Incident loop, Phase 4.9 Troubleshoot-to-Guardrail¶
Forge accumulates lessons faster than it accumulates prevention. Phase 4.9 closes that gap. Use this when a bug surfaces in a live session.
Four steps before moving on¶
- Root cause one line. Format
cause was X because Y. Not "I fixed it." If you cannot state the cause cleanly you have not understood the bug yet. - Log the lesson. Run
forge/scripts/forge_incident_log(a thin shim intoforge_memory_auto_capture.log_incident(), the single owner of LESSONS.md writes). Atomic tempfile plus rename. Upserts onincident_id: existing entries getseen_countbumped,last_seenupdated, the date appended under### Recurrences. - Decide guard tier (seen-twice rule). A single low-blast occurrence logs only. Two or more occurrences, or one with high blast radius (data loss, security, silent corruption, customer-visible regression with no quick rollback), require a concrete guard the same session: hook, eval check, doctrine clause, boundary sanitizer.
- Link forward. Lesson's
guard:field references the guard's file path or doctrine section. The guard's comment references theincident_id. Future audits trace the chain in either direction.
CLI¶
forge_incident_log \
--id "kebab-case-stable-id" \
--title "one-line title" \
--blast low|medium|high \
--doctrine "Section X (rule)" or "n/a" \
--eval-check "check-name" or "none" \
--root-cause "cause was X because Y" \
--fix "what changed in code" \
--guard "path/to/guard.py:LN" or "doctrine:Section-X" \
--guard-status shipped|proposed|not-needed|overdue \
--recurrence-prevention "what stops this from happening again"
Only --id and --title are required; missing fields render as tbd or sensible defaults. Output is JSON {action, incident_id, seen_count, last_seen} to stdout.
Schema (LESSONS.md, new entries only)¶
## YYYY-MM-DDTHH:MM [incident_id] one-line title
- **doctrine:** Section X (rule name) | n/a
- **eval_check:** check-name | none
- **incident_id:** kebab-case-stable-key
- **seen_count:** N
- **first_seen:** YYYY-MM-DD
- **last_seen:** YYYY-MM-DD
- **blast_radius:** low | medium | high
- **guard:** path/to/guard.py:LN | doctrine:Section-X | none (single-occurrence)
- **guard_status:** shipped | proposed | not-needed | overdue
### Root cause
One line.
### Fix
What changed.
### Recurrence prevention
What stops this from happening again, or the proposed mechanism if guard_status is proposed.
Existing pre-4.9 free-form entries are grandfathered. New entries follow the schema.
Eval harness¶
Two checks registered in forge/eval.json under doctrine_section 10.4, both warning severity (initial; tighten to error after one clean week per the same policy as no-em-dashes):
lessons-md-schema-conformance(forge_eval_check_lessons_md_schema.py): warns when a Phase 4.9 incident block (kebab-tagged header plus declaredincident_id) omits required fields.lessons-orphan-recurrence(forge_eval_check_lessons_orphan_recurrence.py): warns whenseen_count >= 2,guard_statusisproposedornone, andlast_seenis 7+ days old.
Auto-dream nag (Sunday)¶
forge_memory_auto_dream.lessons_recurrence_scan() runs as Pass E during the nightly consolidation, but only fires on Sunday. Compiles backlog of seen_count >= 2 entries with guard_status in (proposed, none) and routes through forge_notify.sh warning. The bot does not auto-build guards: silent automated guard-building violates the seen-twice judgment requirement, so the human keeps the call.
CLI smoke test: forge_memory_auto_dream.py --recurrence-scan --force-recurrence --dry-run.
Doctrine¶
FORGE-DOCTRINE.md Section 10.4. Sub-clause of self-iteration; the contract that says "when X breaks twice, a guard ships."
Files¶
forge/scripts/forge_memory_auto_capture.py— ownslog_incident(), single writer of LESSONS.mdforge/scripts/forge_incident_log— thin CLI shimforge/scripts/forge_memory_auto_dream.py—lessons_recurrence_scan()(Pass E)forge/scripts/forge_eval_check_lessons_md_schema.pyforge/scripts/forge_eval_check_lessons_orphan_recurrence.pyforge/eval.json— registers both checksforge/FORGE-DOCTRINE.md— Section 10.4forge/LESSONS.md— single store
[phoenix-4-9 worker]