Skip to content

feat(retro): add the retro phase and the lessons store - #7

Merged
null-result merged 2 commits into
developfrom
feature/retro-phase-lessons-store
Jul 31, 2026
Merged

feat(retro): add the retro phase and the lessons store#7
null-result merged 2 commits into
developfrom
feature/retro-phase-lessons-store

Conversation

@null-result

Copy link
Copy Markdown
Owner

What this changes

Adds retro as the final phase of the default pipeline (… → it → audit → retro → done) and a new project artifact it owns: the lessons store under paths.lessons (default specs/lessons/), one LSN-NNNN-<slug>.md per lesson.

New: kivax_lessons.py (CLI: list / show / new / relevant / check / lint), the knowledge-curator agent, the kivax-retro phase skill, the kivax-lessons-schema reference skill, and a lesson template. Wired into DEFAULT_PIPELINE, kivax init, kivax doctor, and the CLI passthrough; the plan/tdd/it/audit/evolve/status skills and their canonical agents were updated to read and enforce it.

Why

spec.yml records what was built. The wiki records what it means. Neither records what the iteration cost — the bug rediscovered, the assumption wrong twice, the fix redone — so every cycle paid for it again.

Why not the wiki. The wiki is derived from the spec, and its one non-negotiable rule is that every claim on a page traces to a REQ. A lesson about a recurring bug has no REQ behind it by construction, so folding it in would have meant relaxing that rule and weakening kivax wiki lint. Separate artifact, separate owner, separate lifecycle (reinforced on recurrence, retired when it stops being true — never reingested on a hash change).

How it binds

A knowledge store nobody reads is a diary. Three mechanisms, in order of teeth:

  1. Read firstkivax-plan, kivax-tdd, and kivax-it run kivax lessons relevant --phase <p> before producing anything. Deliberately generous: no path filtering unless asked, because at plan time nobody knows yet which files the feature will touch, and a lesson withheld for that reason is a lesson about to be relearned.
  2. Write it downplan.md gains a ## Lessons applied section (shipped in the template): one line per applicable lesson, saying how the plan honors it or not applicable: <reason>.
  3. The gatekivax lessons check computes the applicable set (project-wide lessons, plus path-scoped ones whose globs match the branch diff or a path named in plan.md) and exits 1 when one isn't answered for. The trace-auditor runs it as part of the audit. A lesson can be dismissed; it cannot be dismissed silently.

Notes for the reviewer

  • The audit gate wasn't in the original ask. The requested consumption points were plan + tdd; kivax lessons check in kivax-audit is the addition that turns documentation into enforcement. It's the piece most worth a second opinion.
  • Ids come from the CLI (kivax lessons new), never from the agent writing the lesson — same rule as feature numbers. Two lessons sharing an id would make every ## Lessons applied reference ambiguous and nothing downstream would notice. Ids are never reused after deletion.
  • Anti-rot rules are hard rules on the agent, not suggestions: reinforce (seen_in) instead of duplicating, retire (status: retired + superseded_by/retired_reason) instead of deleting, and zero lessons is a valid cycle — every applicable lesson is read by every future planner, so a worthless entry buys inattention to the good ones.
  • A lesson is never a substitute for a REQ. Unspecified behavior found during the retro is a GAP: routed to kivax-evolve. Stated explicitly in the skill, the agent, and the orchestrator's principles so the store can't become a back door around spec-first.
  • Existing projects need a manual config.yml edit (pipeline, paths.lessons, gates.retro) — kivax upgrade copies the new skill/agent in but never rewrites config. Migration snippet is in the README. kivax lessons falls back to <paths.features>/lessons so nothing breaks mid-migration, and kivax doctor flags the missing key when retro is in the pipeline.
  • kivax lessons check acts on the active feature (unlike validate/trace, which span every feature); the sample CI step notes that.

Verified end to end on a scratch project: a lesson scoped to src/booking/** was correctly ignored by check until the plan's REQ→modules table named a matching path, then failed the gate.

Checklist

  • pytest tests passes — 429 tests (67 new)
  • Coverage stays above the 90% gate — total went 95% → 97.7%; kivax_lessons.py at 98%
  • ruff check . bin/kivax passes
  • Behavior change covered by tests — tests/unit/test_kivax_lessons.py covers applicability, acknowledgment parsing, the gate's pass/fail paths, id allocation, and every lint rule
  • Agents and skills under share/ updated alongside the CLI
  • README updated (pipeline table, artifacts, CLI reference, a section on the store, migration snippet)

🤖 Generated with Claude Code

null-result and others added 2 commits July 31, 2026 17:48
The pipeline had no place for what an iteration *cost*. spec.yml records
what was built and the wiki records what it means, but the knowledge that
actually gets lost between features — the bug rediscovered, the assumption
wrong twice, the fix redone — had nowhere to live, so every cycle paid for
it again.

Adds `retro` as the final default phase, after `audit`. The knowledge-curator
reconstructs the cycle from evidence already in the repo (state.yml history,
fix-on-fix commits, audit and reviewer findings) and writes one lesson per
file under the new paths.lessons.

The store is deliberately NOT part of the wiki: the wiki is derived from the
spec and its one non-negotiable rule is that every claim traces to a REQ,
which a lesson about a recurring bug never can.

What makes it bind rather than rot into a diary:
- plan/tdd/it run `kivax lessons relevant --phase <p>` before producing
  anything (no path filtering by default — at plan time nobody knows yet
  which files the feature will touch)
- plan.md gains a `## Lessons applied` section, in the template
- `kivax lessons check` computes the applicable lessons and exits 1 when one
  isn't answered for; the trace-auditor runs it at the audit gate. A lesson
  can be dismissed, but only in writing.

Lesson ids are allocated by `kivax lessons new`, never by hand — a shared id
would make every reference in every plan ambiguous, and nothing downstream
would notice.

Co-Authored-By: Claude <noreply@anthropic.com>
develop landed a breaking change while this branch was open (constitution →
principles, plus the researcher agent and resumable task lists), so this is a
real adaptation, not a textual reconciliation:

- every reference the retro work added to CONSTITUTION.md / paths.constitution
  / CONSTITUTION-VIOLATION now uses the principles naming
- `retro` joins the renamed default pipeline; PASSTHROUGH carries both `task`
  and `lessons`
- knowledge-curator gains the task-list block every long-running specialist
  now has, and joins that roster in kivax-tasks and the README — the retro
  phase can be interrupted mid-write like any other
- the audit's step order absorbs both new checks: lessons first (mechanical),
  then principles (judgment)
- skill counts corrected to 6 reference + 14 phase-driver

Verified on the merged tree: 465 tests pass, ruff clean, and a fresh `kivax
init` produces a pipeline ending in retro with `kivax doctor` OK and both
`kivax lessons` and `kivax task` working.

Co-Authored-By: Claude <noreply@anthropic.com>
@null-result
null-result force-pushed the feature/retro-phase-lessons-store branch from 45be48d to 6d8dc96 Compare July 31, 2026 16:00
@null-result
null-result merged commit 87e5b62 into develop Jul 31, 2026
13 checks passed
@null-result
null-result deleted the feature/retro-phase-lessons-store branch July 31, 2026 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant