sync: auto-sync from GURU-5070 at 2026-07-01 15:49:56

Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-07-01 15:49:56
This commit is contained in:
2026-07-01 15:50:48 -07:00
parent 1775571abb
commit 2937b00ebf
15 changed files with 1217 additions and 67 deletions

View File

@@ -113,3 +113,143 @@ None surfaced, created, or rotated.
- 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).