448 lines
26 KiB
Markdown
448 lines
26 KiB
Markdown
# 2026-07-01 — /self-check run + skill-registry description trim (GREEN)
|
|
|
|
## User
|
|
- **User:** Mike Swanson (mike)
|
|
- **Machine:** GURU-5070
|
|
- **Role:** admin
|
|
|
|
## Session Summary
|
|
|
|
Ran `/self-check` (the fleet-conformance probe) on GURU-5070. The deterministic probe graded
|
|
AMBER: 83 PASS, 1 WARN, 0 FAIL, 35 INFO against provisional manifest 1.0.0. The single warning
|
|
was `harness.registry_budget` — the sum of all repo SKILL.md frontmatter `description:` fields
|
|
was 15,658 chars against the 10,500 budget (35 skills), i.e. registry bloat taxing every
|
|
session's context load.
|
|
|
|
Ran both semantic passes the skill mandates on a full check. Pass 1 (rogue-memory
|
|
contradiction vs identity.json/settings): clean. The one suspect — `feedback_ollama_tier0_routing.md`
|
|
headlining qwen3:14b while this box's identity.json sets `prose_model: qwen3:8b` — self-resolves:
|
|
the memory body instructs reading `prose_model` from identity.json and documents that 12 GB boxes
|
|
like GURU-5070 get 8b (its Python example hardcoding 'qwen3:14b' is cosmetic only).
|
|
Pass 2 (command-vs-standard): `time-entry-protocol.md` still defers to `/syncro` as SSOT and both
|
|
agree add_line_item is normal billing with timers outlier-only — no drift.
|
|
|
|
Mike asked to trim the descriptions and re-publish. Measured with the probe's own awk logic
|
|
(frontmatter-only, description block until next top-level key). Trimmed 23 skills' descriptions
|
|
from multi-paragraph essays to single ~250-290 char lines, keeping distinctive trigger keywords
|
|
and gating notes. Before cutting, verified every load-bearing fact (tenant IDs, endpoints,
|
|
communityId 622, azcomp4587, B2 accountId, cmdkey/SYSTEM gotchas, SQLX_OFFLINE, etc.) already
|
|
exists in each SKILL.md body — nothing lost, only deduplicated. Registry total: 15,658 -> 9,786
|
|
chars (~700 headroom).
|
|
|
|
Copied the 23 trimmed SKILL.md files to `~/.claude/skills/` so the repo-vs-global duplicate
|
|
check stays "identical" rather than flipping to divergent-WARN. Re-ran with `--publish`:
|
|
**Grade GREEN** (84 PASS / 0 WARN / 0 FAIL / 35 INFO), census published to coord as component
|
|
`selfcheck_GURU-5070 = GREEN`.
|
|
|
|
## Key Decisions
|
|
|
|
- Trimmed descriptions in-place with a Python script implementing the probe's exact awk
|
|
counting logic (frontmatter description block only), rather than eyeballing — the first
|
|
naive measurement (whole-file grab) wildly overcounted and would have led to wrong targets.
|
|
- Kept distinctive trigger keywords in every trimmed description (skill routing depends on
|
|
them); moved nothing that wasn't already duplicated in the SKILL.md body.
|
|
- Verified body coverage of load-bearing facts (grep per key fact) BEFORE deleting them from
|
|
frontmatter, instead of blindly relocating text.
|
|
- Trimmed 4 extra skills (mailprotector, rmm-audit, remediation-tool, gitea) beyond the
|
|
minimum needed, to build ~700 chars of headroom so the next added skill doesn't re-trip
|
|
the WARN.
|
|
- Synced trimmed files to `~/.claude/skills/` immediately to avoid creating repo/global
|
|
divergence (the "same skill, different behavior" failure the duplicates check exists for).
|
|
- Semantic memory pass: judged from MEMORY.md index one-liners + targeted file reads instead
|
|
of opening all ~200 memory files; only opened the one genuine suspect.
|
|
|
|
## Problems Encountered
|
|
|
|
- Initial description measurement (awk over whole file with `head -50`) gave ~80k total vs the
|
|
probe's 15,658 — the probe counts ONLY the frontmatter description block between the `---`
|
|
markers. Resolved by reading `check_harness_smoke()` in
|
|
`.claude/skills/self-check/scripts/self-check.sh` and reusing its exact awk.
|
|
- First trim pass landed at 10,272/10,500 — technically passing but with only ~230 chars
|
|
headroom. Trimmed 4 more skills to reach 9,786.
|
|
|
|
## Configuration Changes
|
|
|
|
Modified (frontmatter description trimmed to one line; body untouched), in BOTH
|
|
`.claude/skills/<name>/SKILL.md` and `~/.claude/skills/<name>/SKILL.md`:
|
|
|
|
- agy, alis, b2, bitdefender, coord, datto-edr, discord-dm, drive-map, frontend-design,
|
|
gitea, grok, gururmm-build, mailprotector, onboard365, packetdial, remediation-tool,
|
|
rmm-audit, rmm-search, screenconnect, synology, unifi-wifi, vault, yealink-ymcs
|
|
(23 skills)
|
|
|
|
Created:
|
|
- `session-logs/2026-07/2026-07-01-mike-self-check-skill-desc-trim.md` (this log)
|
|
|
|
Scratch (session temp dir, not in repo): `trim_descs.py` (the trim script).
|
|
|
|
## Credentials & Secrets
|
|
|
|
None surfaced, created, or rotated.
|
|
|
|
## Infrastructure & Servers
|
|
|
|
- Coord API `http://172.16.3.30:8001` — reachable; census published as component
|
|
`selfcheck_GURU-5070`, state GREEN.
|
|
- Capability tier: ollama_local (Ollama 0.30.11 at localhost:11434, fallback Beast
|
|
100.101.122.4:11434, prose_model qwen3:8b). cargo/node/gh/op present; docker absent
|
|
(capability off, expected).
|
|
|
|
## Commands & Outputs
|
|
|
|
- Probe: `SELFCHECK_TS="$(date -u +%Y-%m-%dT%H:%M:%SZ)" bash .claude/skills/self-check/scripts/self-check.sh report` -> AMBER, sole WARN `harness.registry_budget` (15658 > 10500).
|
|
- Per-skill budget measurement: probe's awk (frontmatter `description:` block, stop at next
|
|
`^[A-Za-z0-9_-]+:` or closing `---`), summed over `.claude/skills/*/SKILL.md`.
|
|
- Re-run + publish: `... self-check.sh --publish` -> GREEN, `[OK] Published census to coord: component selfcheck_GURU-5070 = GREEN`.
|
|
|
|
## Pending / Incomplete Tasks
|
|
|
|
- The 23 trimmed SKILL.md files sync fleet-wide with this /save's commit; other machines
|
|
re-run `/self-check` after pulling to clear their own registry_budget WARN and republish.
|
|
- Baseline manifest still provisional (1.0.0): 25 skills + 4 commands report as census
|
|
candidates — ratification of `baseline/manifest.json` (via fanout + aggregate) still ahead.
|
|
- Standing INFO: 27 commands + 35 skills duplicated repo vs `~/.claude` (identical today;
|
|
probe flags divergence if it happens). Docker absent — deliberate.
|
|
|
|
## Reference Information
|
|
|
|
- Probe engine: `.claude/skills/self-check/scripts/self-check.sh` (budget logic in
|
|
`check_harness_smoke()`, ~line 588).
|
|
- Baseline: `.claude/skills/self-check/baseline/manifest.json` — `harness.registry_desc_budget_chars: 10500`;
|
|
`command_standard_links` has one pair (syncro-billing: `.claude/standards/syncro/time-entry-protocol.md`
|
|
must defer to `/syncro`) — verified intact and non-contradictory.
|
|
- Registry description totals: before 15,658 / after 9,786 (budget 10,500).
|
|
- Semantic pass artifacts checked: `.claude/memory/feedback_ollama_tier0_routing.md`,
|
|
`.claude/standards/syncro/time-entry-protocol.md`, `.claude/commands/syncro.md`.
|
|
|
|
## Update: 15:48 PT — errorlog analysis + five harness improvements
|
|
|
|
### Session Summary
|
|
|
|
Mike asked for an analysis of the ClaudeTools harness based on usage + errorlog.md.
|
|
Full-log analysis (391 entries, 2026-06-14..07-01: 93 friction / 44 corrections / 250 exec):
|
|
40% of volume was two skills' machine-generated noise (bitdefender 111, synology 45);
|
|
top repeat refs proved two documented rules not sticking (feedback_windows_quote_stripping
|
|
9x, feedback_tmp_path_windows 6x); no linter existed for the corpus. Delivered a ranked
|
|
improvement list, then implemented five items across two rounds on Mike's go.
|
|
|
|
Round 1: (a) log-skill-error.sh same-day DEDUP — identical date+machine+skill+message
|
|
bumps a trailing " (xN)" counter instead of appending a duplicate line; (b) fixed the
|
|
machine-name bug — helper read `.machine_name // .hostname` from identity.json but the
|
|
real field is `.machine`, so it always fell back to raw hostname (the Howard-Home vs
|
|
HOWARD-HOME case-drift cause); (c) verified gz.py (bitdefender) already carries the
|
|
expected-error suppression (_should_log_error + GZ_SUPPRESS_ERRORLOG + OID validation)
|
|
— no work needed; (d) errorlog.md header documents the (xN) convention.
|
|
|
|
Round 2: (e) NEW skill `errorlog-dream` (.claude/skills/errorlog-dream/) — the linter the
|
|
log was waiting for; sibling of memory-dream: reports top contexts, repeat refs, cross-day
|
|
noise clusters, [RESOLVED] entries, machine drift, archive candidates; PROPOSED section
|
|
with [STRENGTHEN?]/[SUPPRESS?]/[ARCHIVE?]; --apply-archive rotates >60-day entries to
|
|
errorlog-archive/YYYY-MM.md; fixture selftest green; live run reproduces the manual
|
|
analysis. (f) vault.sh get-field null guard (D:/vault repo) — a missing field made yq
|
|
print literal "null" (4 chars) which callers consumed as a real credential (both
|
|
wrong-4-char-value incidents); now errors exit 1 and prints the entry's key paths.
|
|
(g) Discord hardening — post-bot-alert.sh: payload via stdin not argv (argv encoding
|
|
layer mangled non-ASCII into 50109) + >1900-char truncation; discord-dm.sh: lossless
|
|
newline-aware chunking into <=1900-char sequential messages (50035 fix that preserves
|
|
long content); live DM test to Mike with em-dash/smart-quotes/arrow passed.
|
|
|
|
Round 3 (Mike: "keep going with the EncodedCommand wrapper and /tmp hook"):
|
|
(h) NEW .claude/scripts/ps-encoded.sh — encode <file|-> prints a paste-safe
|
|
powershell -EncodedCommand one-liner (ScreenConnect/plink); rmm <agent-uuid> <file>
|
|
dispatches via GuruRMM as command_type=shell (single quote-free base64 token) with
|
|
timeout_seconds + optional --user-session, then polls /api/commands/{id}; size guards
|
|
(warn 4KB / refuse 6KB encoded, --force) encode the ~7KB agent body limit. Verified:
|
|
byte-exact roundtrip; live powershell exec with embedded quotes and UNC \\ intact
|
|
(len=21 test). Strengthened feedback_windows_quote_stripping memory + MEMORY.md index
|
|
+ /rmm command doc (new "Quote-safe dispatch" section) to lead with the wrapper.
|
|
(i) NEW .claude/hooks/block-tmp-path.sh PreToolUse hook — blocks Bash WRITES to /tmp
|
|
on Windows only (redirects, tee, -o/--output, cp/mv/mktemp targets; reads and quoted
|
|
mentions pass); wired as second PreToolUse Bash hook in settings.json and added to
|
|
baseline manifest (required_hook_files + required_settings_hooks) so self-check
|
|
enforces fleet-wide. Effective for NEW sessions.
|
|
|
|
Self-check re-run: caught my own /rmm doc edit as repo-vs-global divergence (WARN),
|
|
reconciled, published GREEN (86 pass / 0 warn) to coord.
|
|
|
|
### Key Decisions
|
|
|
|
- Dedup window = same calendar day (identical full line), not a rolling 24h — deterministic,
|
|
no timestamps needed, matches the (xN) display convention.
|
|
- errorlog-dream mirrors memory-dream's posture exactly: read-only default, one additive/
|
|
rotational mutation (--apply-archive), judgment stays in PROPOSED for the operator.
|
|
- ps-encoded.sh dispatches as command_type=shell (cmd.exe) not powershell — avoids a
|
|
nested powershell-in-powershell spawn; the base64 token traverses cmd.exe unparsed.
|
|
- Scripts for ps-encoded MUST be authored with the Write tool — Git-bash heredocs
|
|
collapse \\ to \ even single-quoted (proved by od during testing; documented in the
|
|
memory + /rmm doc).
|
|
- /tmp hook is Windows-gated (uname MINGW/MSYS/CYGWIN) so shared settings.json does not
|
|
block Mac/Linux machines where /tmp is one real directory.
|
|
- vault get-field lists KEY PATHS only (never values) on failure — no secret leakage in
|
|
the error path.
|
|
- discord-dm chunks add NO markers so the receiver can copy-paste chunks back together
|
|
verbatim; post-bot-alert truncates instead (alerts are one-liners by contract).
|
|
|
|
### Problems Encountered
|
|
|
|
- Test harness bugs, not production bugs: jq --rawfile with /dev/stdin fails on Windows
|
|
jq (no /proc) — rebuilt test events with jq -n --arg; cmd.exe /c from Git-bash had /c
|
|
MSYS-converted to C:\ opening an interactive cmd (2-min timeout) — used powershell.exe
|
|
directly. Both logged to errorlog as [friction].
|
|
- selftest fixture initially put both "old" entries in the same month — spread to d(95)/
|
|
d(65) to exercise the month-split path.
|
|
- cp/mv /tmp pattern missed line-start cp (required leading whitespace) — anchored with
|
|
(^|[[:space:]]|;|\|).
|
|
- The UNC backslash "loss" during wrapper testing was the Git-bash heredoc collapsing \\
|
|
BEFORE encoding (od-verified) — wrapper itself byte-exact; became the Write-tool
|
|
authoring rule.
|
|
|
|
### Configuration Changes
|
|
|
|
Created:
|
|
- .claude/skills/errorlog-dream/{SKILL.md, scripts/errorlog_dream.py, scripts/selftest.py}
|
|
(+ copies in ~/.claude/skills/errorlog-dream/)
|
|
- .claude/scripts/ps-encoded.sh
|
|
- .claude/hooks/block-tmp-path.sh (exec bit set via git update-index --chmod=+x)
|
|
|
|
Modified:
|
|
- .claude/scripts/log-skill-error.sh (dedup pass + .machine field fix + doc header)
|
|
- errorlog.md (header documents (xN); 2 new friction entries from testing)
|
|
- D:/vault/scripts/vault.sh (get-field null guard + key-path listing) [vault repo]
|
|
- .claude/scripts/post-bot-alert.sh (stdin payload + truncation)
|
|
- .claude/scripts/discord-dm.sh (chunking loop)
|
|
- .claude/memory/feedback_windows_quote_stripping.md (+ mechanical-fix headline)
|
|
- .claude/memory/MEMORY.md (index line updated for the same memory)
|
|
- .claude/commands/rmm.md (+ Quote-safe dispatch section; synced to ~/.claude/commands/)
|
|
- .claude/settings.json (second PreToolUse Bash hook: block-tmp-path.sh)
|
|
- .claude/skills/self-check/baseline/manifest.json (required_hook_files +
|
|
required_settings_hooks += block-tmp-path)
|
|
|
|
### Credentials & Secrets
|
|
|
|
None created/rotated. vault get-field behavior change: missing/null field now exits 1
|
|
with a key-path listing (keys only, values never printed).
|
|
|
|
### Commands & Outputs
|
|
|
|
- Lint the log: `bash .claude/scripts/py.sh .claude/skills/errorlog-dream/scripts/errorlog_dream.py [--apply-archive]`
|
|
- Quote-safe PS dispatch: `bash .claude/scripts/ps-encoded.sh rmm <agent-uuid> script.ps1 --timeout 120 [--user-session]`
|
|
/ paste one-liner: `... encode script.ps1`
|
|
- Selftests: errorlog-dream selftest.py all-pass; discord chunker lossless (3-chunk +
|
|
hard-split); /tmp hook 11-case matrix + grok decision JSON; EncodedCommand len=21 UNC proof.
|
|
- Final: self-check GREEN 86/0/0 published (selfcheck_GURU-5070).
|
|
|
|
### Pending / Incomplete Tasks
|
|
|
|
- Remaining from the improvement list: backend health cache (agy/grok/rmm/coord chronic
|
|
failures — skip retries when a backend is known-down) and Syncro preflight gates in the
|
|
skill script (priority format, product_category null check, prepay detail-GET, unbilled
|
|
line-item check before invoice).
|
|
- Howard-Home env checks (websocket-client, ff.py daemon, tailscale backend state) as
|
|
self-check capability checks — proposed, not built.
|
|
- Other machines: pull + rerun /self-check (new hook enforced), and their identity.json
|
|
case drift (HOWARD-HOME vs Howard-Home) normalizes automatically via the .machine fix.
|
|
- errorlog-dream --apply-archive has nothing to rotate until entries age past 60 days
|
|
(log starts 2026-06-14).
|
|
|
|
### Reference Information
|
|
|
|
- New skill: .claude/skills/errorlog-dream/ ; wrapper: .claude/scripts/ps-encoded.sh ;
|
|
hook: .claude/hooks/block-tmp-path.sh
|
|
- Errorlog stats at analysis time: 391 entries, top contexts bitdefender 111 / synology 45 /
|
|
rmm 30; repeat refs quote-stripping 9x, tmp-path 6x; machines Howard-Home 256 / GURU-5070 116.
|
|
- RMM dispatch shape: POST $RMM/api/agents/{id}/command {command_type, command,
|
|
timeout_seconds[, context]}; poll GET $RMM/api/commands/{command_id}.
|
|
- Discord test message id 1522005953896120494 (mike DM, non-ASCII survival test).
|
|
|
|
## Update: 20:06 PT — BirthBio Gmail folder cleanup + Discord bot to Fable 5
|
|
|
|
### Session Summary
|
|
|
|
Two client/infra tasks after the harness work. First, BirthBio (birthbiologic.com,
|
|
tenant 19a568e8-9e88-413b-9341-cbc224b39145): Mike reported Gmail-import folders named
|
|
"INBOX\<FolderName>". Swept all 21 licensed mailboxes via remediation-tool (investigator
|
|
tier): the artifact was concentrated in bburgess (30 top-level folders literally named
|
|
with flattened label paths like "INBOX/Consultants & Vendors/Kintone", some carrying real
|
|
child subtrees, plus 5 [Gmail]/[Imap] leftovers) and one empty [Imap]/Drafts on mster.
|
|
ksteen's AATB/EBAA + Fax/Scan + PTO/Payroll Info + Shipping/Couriers and ameneely's
|
|
Amnion/Chorion Video are REAL label names containing slashes - left untouched.
|
|
|
|
Enabler work: Graph v1.0 metadata confirmed a native mailFolder move action; the Exchange
|
|
Operator SP holds Graph Mail.ReadWrite in-tenant (verified via appRoleAssignments after
|
|
fixing JWT base64url decode + URL-encoding the $filter), but get-token.sh had no
|
|
exchange-op-to-Graph tier - added `exchange-op-graph` tier (same app b43e7342, Graph
|
|
audience) to the skill permanently. On Mike's YES: created 3 intermediate parents, moved+
|
|
renamed all 30 INBOX/ folders into their real hierarchy (subtrees + ~700 items rode along),
|
|
renamed [Gmail]/Fire Inspectin -> Fire Inspectin (4 items kept), deleted 4+1 verified-empty
|
|
artifacts. 39 actions, 0 failures; both mailboxes verify clean. Report:
|
|
clients/birth-biologic/reports/2026-07-01-bburgess-gmail-folder-cleanup.md. Ticket #32451
|
|
(the email-migration ticket; #32187 is the SharePoint one) got a public emailed comment
|
|
(id 421704524, GET-verified) + [SYNCRO] bot-alert with link.
|
|
|
|
Second, Mike asked to put "the bot" on Fable 5: the ClaudeTools Discord Bot (NSSM service
|
|
ClaudeToolsDiscordBot on GURU-BEAST-ROG, Claude Agent SDK + OAuth subscription, Claude Code
|
|
2.1.183). Flipped CLAUDE_MODEL=claude-sonnet-4-6 -> claude-fable-5 in
|
|
C:\Users\guru\ClaudeTools\projects\discord-bot\.env via RMM, restarted the service, and
|
|
verified the startup log line "Claude model: claude-fable-5" + "Bot is ready". Updated the
|
|
repo defaults (bot/config.py + .env.example) in the acg-discord-bot submodule, commit
|
|
a35bd1bf pushed to main via the internal Gitea URL (external hostname auth failed - known
|
|
GCM shadowing); parent gitlink advances with this /save.
|
|
|
|
### Key Decisions
|
|
|
|
- bburgess restructure via Graph folder MOVE (subtree+items intact) not per-message moves;
|
|
verified move action exists in $metadata before proposing.
|
|
- Deletes gated on live empty re-verification at execution time; [Gmail]/Fire Inspectin
|
|
renamed in place instead of move+delete (same result, zero item handling).
|
|
- Ticket routing: #32451 chosen because Mike's prior email-migration status comments live
|
|
there; #32187 is Datto->SharePoint. Posted public+emailed per Mike's explicit choice.
|
|
- Added exchange-op-graph tier to get-token.sh rather than free-handing a token mint -
|
|
skill-first, durable for future mailbox-folder work.
|
|
- Discord bot: .env override + service restart for the live change; repo defaults changed
|
|
too so redeploys match. Bot uses Agent SDK/Claude Code runtime, so Fable API quirks
|
|
(always-on thinking, no sampling params, refusal fallbacks) are handled by the runtime.
|
|
|
|
### Problems Encountered
|
|
|
|
- exchange-op default token is EXO-audience; decoding roles with plain base64 -d failed
|
|
(JWT base64url) and nearly produced a wrong "no Mail roles" conclusion - fixed decode
|
|
(tr '_-' '/+' + padding) per the errorlog lesson, then read SP appRoleAssignments.
|
|
- Graph $filter with unencoded spaces returned empty via curl - use curl -G --data-urlencode.
|
|
- [Gmail]/Trash/Insurance seen in the first sweep was already gone at execution (evidently
|
|
Outlook-side cleanup); executor enumerates live so it skipped harmlessly.
|
|
- Submodule push to git.azcomputerguru.com failed auth (GCM shadowing) - pushed by explicit
|
|
SHA to internal http://172.16.3.20:3000 and ls-remote verified (a35bd1bf).
|
|
- nssm/claude not on SYSTEM PATH via RMM - used Get-Service/Restart-Service and the
|
|
user-profile claude.exe path instead.
|
|
|
|
### Configuration Changes
|
|
|
|
- .claude/skills/remediation-tool/scripts/get-token.sh: + exchange-op-graph tier (repo +
|
|
~/.claude copies).
|
|
- clients/birth-biologic/reports/2026-07-01-bburgess-gmail-folder-cleanup.md: created.
|
|
- BEAST C:\Users\guru\ClaudeTools\projects\discord-bot\.env: CLAUDE_MODEL=claude-fable-5
|
|
(machine-local, not in git).
|
|
- projects/discord-bot submodule: bot/config.py default + .env.example -> claude-fable-5
|
|
(commit a35bd1bf, pushed to main; .env.example auth comments also tidied).
|
|
|
|
### Infrastructure & Servers
|
|
|
|
- BirthBio tenant 19a568e8-9e88-413b-9341-cbc224b39145; Exchange Operator SP in-tenant
|
|
id bab4699b-32a3-4434-9cad-7a4a08cc4d9e (Graph roles: Mail.ReadWrite,
|
|
MailboxSettings.ReadWrite, User.Read.All, User.RevokeSessions.All, Organization.Read.All).
|
|
- Discord bot: GURU-BEAST-ROG (RMM agent 5233d75b-f589-43c4-b96e-cfa75365a78d), NSSM
|
|
service ClaudeToolsDiscordBot, log C:\Users\guru\ClaudeTools\projects\discord-bot\logs\bot.log.
|
|
|
|
### Commands & Outputs
|
|
|
|
- Folder executor + read-only mapper in session scratchpad (bb_folder_fix.py /
|
|
bb_folder_map.py); action log bb_actions.json (scratchpad).
|
|
- Graph-audience exchange-op token: get-token.sh <tenant> exchange-op-graph.
|
|
- Syncro comment POST via jq-file + --data-binary + GET-verify pattern; alert via
|
|
post-bot-alert.sh (new stdin payload path worked in production).
|
|
|
|
### Pending / Incomplete Tasks
|
|
|
|
- Watch Fable 5 usage burn on the shared Max subscription (bot + interactive share limits);
|
|
fallback is a one-line .env change to claude-opus-4-8 + service restart.
|
|
- BirthBio: ksteen/ameneely slash-named folders are intentional - documented in the report
|
|
so nobody "fixes" them later.
|
|
|
|
### Reference Information
|
|
|
|
- Syncro #32451 internal id 112986219, comment 421704524; customer Birth Biologic 17983014.
|
|
- Submodule commit a35bd1bf1758ac462abdf05bdd9ee6a1c7b427ee (acg-discord-bot main).
|
|
- Bot model verification log lines: 2026-07-01 20:01:07 "Claude model: claude-fable-5".
|
|
|
|
## Update: 2026-07-02 06:22 PT — CrowdStrike Falcon spec + framework build (Tasks 0-3)
|
|
|
|
### Session Summary
|
|
|
|
Continued the CrowdStrike thread. Added the developer.crowdstrike.com API reference to the
|
|
RMM_THOUGHTS entry (OAuth2, Sensor Download + Installation Tokens for install, Hosts/RTR/
|
|
policy for management), then ran `/shape-spec` to produce a full spec at
|
|
projects/msp-tools/guru-rmm/specs/crowdstrike-falcon/ (plan/shape/references/standards).
|
|
Mike's shaping input: multi-tenant per-client CIDs from day one; MODULAR — each partner
|
|
enables with their own API creds/region; RTR + alert ingestion OUT of scope; creds handled
|
|
safely; uniform plugin framework preferred; P1, needs a draft very soon. Design decision:
|
|
build CrowdStrike as plugin #1 on a vendor-agnostic integrations framework (generalizes the
|
|
proven mspbackups shape) rather than a one-off.
|
|
|
|
Then implemented the server half, Tasks 0-3, each committed + pushed to guru-rmm main and
|
|
VERIFIED green by the pipeline (CI [ci-version-bump] on top of each = successful Linux
|
|
server build — the real compile gate; local cargo check is blocked on GURU-5070 by a
|
|
missing MSVC linker, logged as friction against reference_guru5070_rust_toolchain):
|
|
- Task 1 (8b75274): migration 065 — 5 vendor-agnostic tables (integrations,
|
|
integration_credentials [reuses credentials TEXT/base64 encryptor shape],
|
|
integration_client_mappings, integration_sync_state, integration_agent_links), per-
|
|
partner, all IF NOT EXISTS.
|
|
- Task 2 (cac7e1d): IntegrationPlugin trait (axum::async_trait, object-safe) + PluginRegistry
|
|
+ credential encrypt/decrypt chokepoint (crypto::Encryptor) + full runtime-sqlx DB layer.
|
|
KEY FINDING: codebase uses RUNTIME sqlx queries, not query! macros -> NO .sqlx regen ever
|
|
needed for this feature.
|
|
- Task 3 (6c83a03): generic /api/integrations REST (list/upsert/delete/credentials[encrypt
|
|
chokepoint, GET returns configured-bool only]/test[dispatch to plugin]/mappings/sync-state);
|
|
added registry: Arc<PluginRegistry> to AppState.
|
|
|
|
Also: restarted the BEAST Discord bot service (came back up on claude-fable-5 21:15). Server
|
|
framework (Tasks 1-3) complete + building; next is Task 4 (CrowdStrike client: OAuth2 +
|
|
region + Sensor Download/Installation Tokens/Hosts wrappers, test_connection + sync).
|
|
|
|
### Key Decisions
|
|
|
|
- Vendor-agnostic framework FIRST (5 generic tables + trait + registry + generic API), so
|
|
SentinelOne/Guardz/etc. are new modules not new schema. Matches Mike's "modular" + the
|
|
roadmap Integrations Center design principle.
|
|
- Encrypted-cred columns are TEXT/base64 (matches crypto.rs Encryptor + credentials table),
|
|
NOT BYTEA as references.md loosely wrote.
|
|
- Runtime sqlx (no query! macros) -> no .sqlx cache churn; big de-risk.
|
|
- Pipeline build is the compile gate (build-pipeline standard); each task pushed by explicit
|
|
SHA + rebased over concurrent CI version-bumps; verified green via the version-bump marker.
|
|
- v1 single-partner resolution (SELECT id FROM partners ... LIMIT 1) like mspbackups; schema
|
|
carries partner_id everywhere for later multi-partner scoping.
|
|
- Containment/lift is the one management WRITE kept in v1 scope; RTR + alerts deferred.
|
|
|
|
### Problems Encountered
|
|
|
|
- Local cargo check blocked: no MSVC link.exe on GURU-5070 (vcvars64.bat not found under VS
|
|
roots) — env, not code. Used the pipeline (Linux) as the gate; logged friction.
|
|
- JWT roles decode: exchange-op earlier task needed base64url (tr _- /+ + pad); noted.
|
|
- Repeated non-fast-forward pushes from CI [ci-version-bump] commits landing between my
|
|
pushes — rebased onto origin/main each time and pushed by SHA.
|
|
|
|
### Configuration Changes
|
|
|
|
- projects/msp-tools/guru-rmm (submodule, main):
|
|
- specs/crowdstrike-falcon/{plan,shape,references,standards}.md (new, dd646f6)
|
|
- server/migrations/065_integrations_framework.sql (new)
|
|
- server/src/db/integrations.rs (new), server/src/db/mod.rs (+pub mod)
|
|
- server/src/integrations/mod.rs (new), server/src/main.rs (mod + AppState.registry)
|
|
- server/src/api/integrations.rs (new), server/src/api/mod.rs (+pub mod + routes)
|
|
- docs/RMM_THOUGHTS.md (+CrowdStrike thought + API reference)
|
|
- errorlog.md: +1 friction (MSVC linker).
|
|
|
|
### Commands & Outputs
|
|
|
|
- Spec commit dd646f6; Task1 8b75274; Task2 cac7e1d; Task3 6c83a03 (all guru-rmm main,
|
|
pipeline-green via ci-version-bump).
|
|
- Push pattern: commit -> git rebase origin/main -> git push origin <sha>:refs/heads/main
|
|
-> git ls-remote verify; poll origin/main for ci-version-bump = build OK.
|
|
|
|
### Pending / Incomplete Tasks
|
|
|
|
- Task 4: server/src/integrations/crowdstrike/{mod,client}.rs — OAuth2 client-credentials +
|
|
region base URL map (US-1/US-2/EU-1/US-GOV), Sensor Download + Installation Tokens + Hosts
|
|
wrappers; implement test_connection + sync.
|
|
- Task 5: register CrowdStrikePlugin in PluginRegistry::build() + sync worker in main.rs.
|
|
- Task 6: deploy job (migration 066) + agent-side install (Task 7, Win first).
|
|
- Task 8: dashboard (Integrations page + Falcon panels). Task 9: e2e verification.
|
|
- Parent gitlink for guru-rmm still lagging; advance on a later /sync if desired.
|
|
|
|
### Reference Information
|
|
|
|
- Spec dir: projects/msp-tools/guru-rmm/specs/crowdstrike-falcon/ (plan.md = source of truth,
|
|
[DONE] markers per task).
|
|
- CrowdStrike API: developer.crowdstrike.com/api-reference (OAuth2 client creds; Sensor
|
|
Download 13 ops, Installation Tokens 9, Hosts 10, Host Group 9; regional base URLs).
|
|
- guru-rmm main after Task 3 + CI bump: ea148e4.
|