Files
claudetools/.claude/skills/errorlog-dream/SKILL.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

108 lines
4.9 KiB
Markdown

---
name: errorlog-dream
description: "Lint the fleet error log (errorlog.md): top failure contexts, repeat ref= citations (rules that are not sticking), cross-day noise clusters, resolved entries, machine-name drift; --apply-archive rotates old entries to errorlog-archive/. Triggers: errorlog dream, lint/analyze the error log, errorlog patterns."
---
# Errorlog Dream
Sibling of `memory-dream` for `errorlog.md` — the corpus of skill failures,
user corrections, and self-inflicted friction that CLAUDE.md mandates logging.
The log exists so we "never pay tokens twice for the same avoidable mistake";
this skill is the payoff step: it reads the corpus and surfaces what to fix.
Read-only by default. The single mutating op (`--apply-archive`) only moves
old entries into `errorlog-archive/YYYY-MM.md`. Everything judgment-shaped
lands in a `## PROPOSED` section for the operator.
## What it reports
`scripts/errorlog_dream.py` parses the canonical entry format
(`YYYY-MM-DD | MACHINE | skill/context | [type] msg [ctx: ...] (xN)`;
`(xN)` is the log helper's same-day repeat counter) and produces:
1. SUMMARY — totals by type (exec/correction/friction), machine, date span,
plus a count of unparsed legacy blocks (left untouched, never archived).
2. TOP CONTEXTS — failure volume by context group, weighted by `(xN)`.
3. REPEAT REFS — `ref=` citations appearing >=2x. **The highest-value signal:**
a friction entry citing a documented gotcha means that rule/memory is NOT
working; repeat citations mean it keeps failing. Checks whether the cited
memory file actually exists.
4. NOISE CLUSTERS — same machine + skill + normalized message (ids/numbers
collapsed) recurring across >=3 days or >=5 weighted hits. These need a
skill-side fix (expected-condition filter, backoff, health-gate) — not
more log lines.
5. RESOLVED — entries carrying a `[RESOLVED ...]` annotation; archive
candidates regardless of age.
6. MACHINE-NAME DRIFT — the same machine logged under multiple spellings
(case drift in identity.json).
7. ARCHIVE CANDIDATES — entries older than `--days` (default 60).
8. PROPOSED — `[STRENGTHEN?]` (repeat refs -> add a mechanical guard or
rewrite the memory), `[SUPPRESS?]` (noise clusters -> fix the skill),
`[ARCHIVE?]` (resolved entries).
## Modes
- Default — report only; prints to stdout and writes
`errorlog-archive/_reports/YYYY-MM-DD-HHMM-dream.md`.
- `--no-file` — stdout only.
- `--report-file <path>` — explicit report path.
- `--days <n>` — archive-age threshold (default 60).
- `--apply-archive` — move entries older than `--days` into
`errorlog-archive/YYYY-MM.md` (grouped by entry month, verbatim lines,
unparsed legacy blocks never moved). Idempotent.
## Running it
Stdlib only, no pip deps.
```bash
# report only
bash "$CLAUDETOOLS_ROOT/.claude/scripts/py.sh" "$CLAUDETOOLS_ROOT/.claude/skills/errorlog-dream/scripts/errorlog_dream.py"
# rotate out entries older than 60 days
bash "$CLAUDETOOLS_ROOT/.claude/scripts/py.sh" "$CLAUDETOOLS_ROOT/.claude/skills/errorlog-dream/scripts/errorlog_dream.py" --apply-archive
```
## The operator MUST work the PROPOSED section — that is the run's purpose
Same posture as memory-dream: the report is not the deliverable, the fixes
are. After each run:
1. **`[STRENGTHEN?]` repeat refs** — the cited prose rule demonstrably fails
under flow. Prefer a MECHANICAL guard over more prose: a PreToolUse hook,
a wrapper that makes the safe path the only path (e.g. `-EncodedCommand`
for quote-mangling layers), or a script-side preflight. If the cited
memory file is missing, fix or remove the dangling ref convention.
2. **`[SUPPRESS?]` noise clusters** — patch the failing skill: filter
expected/validation responses out of logging (the gz.py pattern +
`GZ_SUPPRESS_ERRORLOG`-style env flag), add a stop-after-2-identical-
failures guard, or health-gate a chronically-down backend.
3. **`[ARCHIVE?]` / archive candidates** — run `--apply-archive`; append
`[RESOLVED <date>]` to entries you fixed so the next run proposes them.
4. Commit + `/sync` so the trimmed log and archive reach the fleet.
If a proposal needs a decision you can't make, leave it AND say so in your
summary — don't silently skip the section.
## Self-test
`scripts/selftest.py` builds a synthetic errorlog in a temp dir and asserts
every detector fires (counters, repeat refs, noise clusters, resolved,
machine drift, archive candidates) and that `--apply-archive` moves exactly
the old entries, splits by month, preserves the marker + unparsed blocks,
and is idempotent.
```bash
bash "$CLAUDETOOLS_ROOT/.claude/scripts/py.sh" "$CLAUDETOOLS_ROOT/.claude/skills/errorlog-dream/scripts/selftest.py"
```
## Files
```
.claude/skills/errorlog-dream/
SKILL.md this file
scripts/errorlog_dream.py the analyzer (report / --apply-archive)
scripts/selftest.py fixture-based self-test
errorlog-archive/ rotated months + _reports/ (created on use)
```