Expand description
Real scars: analyzer input source that reads review / friction notes
from the workspace ledger, and emits High-severity lessons only when the
same problem shows up twice or more — havamal’s “no scar, no doctrine”
rule made mechanical.
Why: SELECTOR2 opened the two natural High paths (supersede / conflict), but analyzer output is still generic self-help (“break the task down”). The ledger’s highest-judgment content — human-written review findings and friction notes — was never read. This module reads it, groups by problem family, and only proposes candidates when a family recurs.
Assumptions (queue 324 goal — operator can override at gate):
- Same problem = same tag family (
revieworfriction) + normalized first-line prefix equal (case-fold, whitespace-collapse, strip trailing punctuation, prefix limit 80 chars). - Recurrence window = 30 days from the most recent occurrence.
- Per-run cap stays at 3; real-scar lessons take priority slots ahead of statistical heuristic lessons.
Structs§
- Ledger
Note - One ledger note fed into the scar analyzer.
Constants§
- PREFIX_
LEN - Family-key length: short enough to catch “same problem, different wording”,
long enough to distinguish unrelated tickets. Bumped down from 80 after a
real friction pair collided at the semicolon (queue 324 test fixture).
pubsince q328 SIGNCHECK so sign_check reuses the exact same family key (single vocabulary, no rival contradiction concept). - RECURRENCE_
WINDOW_ DAYS
Functions§
- analyze_
recurring_ scars - Recurring-problem analyzer output — folded into the main postmortem lessons as High severity (single-family cap: one lesson per recurring family).
- normalize_
prefix - Case-fold, whitespace-collapse, cut at first clause break (
;,—, full-stop or Chinese。), strip trailing punctuation, then take up to PREFIX_LEN chars. Two writeups of the same scar rarely share a full sentence, but the clause-head is stable. - notes_
from_ events - Extract scar notes from workspace-ledger note events.
One event carrying multiple scar tags fans out to multiple LedgerNotes
(a friction that also carries
reviewcounts as both — that’s their real classification, we don’t second-guess the writer). - read_
ledger_ notes - Read notes from a
edda log --json-style JSONL file (row-per-event). Malformed lines skipped; missing file ⇒ empty. Kept as a testable path alongsidenotes_from_events(which reads structured Events directly).