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:
@@ -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).
|
||||
|
||||
Reference in New Issue
Block a user