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

4.9 KiB

name, description
name description
errorlog-dream 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.

# 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 "$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)