Files
claudetools/session-logs/2026-07/2026-07-01-mike-self-check-skill-desc-trim.md
Mike Swanson 2937b00ebf 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
2026-07-01 15:50:54 -07:00

15 KiB

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.jsonharness.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 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).