Skip to content

skill · phase: maintenance

Retrospective

Purpose

Close the feedback loop: when an instance completes, capture what the work taught us while it is fresh, and write durable lessons where the next instance will read them. This is the system-level quality mechanism — gates and reviews protect one instance; retrospectives make the next one start smarter.

{{glossary:instance}}

When to Run

  • At every instance's completion moment, regardless of scope or template. The completion moment is the last applicable phase (template × scope) reaching complete — except when that phase is maintenance, where entering maintenance is the moment (maintenance is open-ended).
  • When a retro-pending marker exists for an instance: markers live in <git-common-dir>/aidlc/retro-pending/<instance> (resolve via git rev-parse --git-common-dir; fallback .aidlc/state/<instance>/retro-pending outside git). The entry-point and continue skills route here when they see one.
  • In consolidation mode when the user accepts a consolidation prompt (see Consolidation below).

Run the retro before any completion cleanup (worktree removal, claim release) — its outputs must be committed to the instance's branch first.

Retro Flow

{{glossary:retrospective}}

  1. Idempotency check. If retrospective.md already exists in the instance state dir, offer to update or skip — never duplicate. A skip still removes the retro-pending marker.
  2. Gather state. Read instance.yaml, phase-*.yaml, and transitions.log. For the cost summary, prefer aidlc cost <instance> (it applies fidelity precedence); only read costs.ndjson raw when the CLI is unavailable, and mark that summary approximate. No cost data → omit the cost section entirely, never write zeros.
  3. Ask — one round-trip. Three questions in a single message: what surprised us? what would we do differently? what took longer than expected? For Micro scope, compress to one question: "anything surprising, worth doing differently, or slower than expected?" Declining the retro is fine: remove the marker, write nothing.
  4. Write retrospective.md in the instance state dir: the answers; instance metadata (template, scope); per-phase durations (pair each transitions.log to: X with the next from: X; fall back to the phase YAML's entered_at/completed_at; note inconsistencies rather than guessing); and the cost summary when available.
  5. Distill lessons — 0 to 3. A lesson is a durable, project-general observation ("NDJSON merge=union false-dedups identical same-second events"), not an instance anecdote ("we finished late"). If nothing generalizes, write no lesson — an empty distillation is a valid outcome.
  6. Confirm, then append. Show the distilled entry verbatim and get one confirmation for the whole entry. Never append unconfirmed text — lessons are auto-loaded into every future session, so this confirmation is the injection gate. Redact anything resembling credentials or secrets. On confirm, append to the lessons layer per the write rules below.
  7. Commit retrospective.md and the lessons append to the current branch now, before any worktree cleanup runs.
  8. Remove the retro-pending marker if one exists.

Lessons Layer — Write Rules

Target: .aidlc/guidance/lessons.md in the current checkout/worktree, on the instance's branch (entries travel with the merge — never write another checkout's copy).

First use. If .aidlc/guidance/ or index.yaml is missing, create them. index.yaml gains (or is created with) the entry:

layers:
  - name: lessons
    file: lessons.md
    last_consolidated: null

If index.yaml already exists, add only the lessons entry — never modify other entries. After registering, verify the layer loads (e.g. aidlc update --dry-run or re-reading the index); surface any loader warning to the user instead of swallowing it.

File shape. The frontmatter is immutable — created once, never rewritten (all mutable metadata lives in index.yaml):

---
name: lessons
description: Lessons from completed instances — historical observations, not directives.
---

The body is append-only between consolidations: one ## <instance> — <YYYY-MM-DD> section per retro run, containing 1–3 bullet lessons, each ending with — from <instance>, <date>. A lesson that belongs in a context doc gets the suffix [promote-to-context] instead of editing .aidlc/context/ directly — the retro never touches context docs.

Re-runs supersede by appending: write a new dated section for the same instance rather than editing the old one; readers use the latest section per instance; consolidation collapses the rest.

Concurrent-write discipline (two sessions may complete instances simultaneously): write the full updated file to a temp name in the same directory, rename it over lessons.md, then re-read and verify your section is present. If it vanished (a concurrent writer won the rename), re-append and re-verify.

Consolidation Mode

Three independent triggers — any one of them offers consolidation. lessons.md exceeds:

  • 20KB (20,480 bytes), or
  • 25 instance sections (count ## headings), or
  • 90 days since last_consolidated in index.yaml.

The retro checks at step 2 and offers it; aidlc status surfaces the same notice. The size trigger exists because the other two are the wrong dimension: this project's file reached 88KB at 23 sections, 12 days after a consolidation — long and old were both still in the future while big had long since arrived, and bytes are what a session pays for.

Run only in the primary checkout (not a linked worktree — check git rev-parse --git-common-dir resolves to ./.git):

  1. Propose merges of duplicate/superseded sections, retirement of stale entries, and application of [promote-to-context] flags (drafting the context-doc edit for approval).
  2. Every edit is confirmed by the user individually. Nothing is deleted silently.
  3. Regenerate lessons-digest.md — the always-read distillation that stands in for the full corpus (see The always-read rule in aidlc-overview). Rewrite everything under its ## Entries heading with the lessons this project has paid for more than once, each ending with — from <instance>, <date> as in lessons.md. Keep the whole file at or under 4096 bytes; that bound is the point of the file, so a digest that needs more entries needs shorter ones, not a larger cap. Leave the text above ## Entries alone — it states that the digest is lossy and names the full corpus, and a reader who only has the digest depends on both.
  4. Confirm what the digest omits, not only what it keeps. A digest is a lossy read of a safety mechanism: show which entries did not make it and get the same individual confirmation step 2 requires. Dropping a lesson from the always-read layer is a decision the user makes, never a side effect of fitting a byte budget.
  5. Report what changed; set last_consolidated in index.yaml to today.

Rules

  • The retro never blocks completion: it is non-blocking, declinable, and its absence is never an error.
  • Never write lessons without the step-6 confirmation. Never record credentials or secrets.
  • Lessons are historical observations, not directives — phrase them as what was learned, not as instructions to obey.