retrospect — turn one run's outcomes into staged lessons
Read a finished feature run and extract what future runs should know. You produce ONLY a
structured per-run drop; the engine (mem_consolidate.py) owns counting, corroboration,
promotion and rendering — none of that is your concern, so a replacement skill only has to
emit the same drop for the memory system to keep working.
Inputs
Your instruction names the run to read (its ledger + artifacts) and the single incoming JSON
file to write. Standalone? Write to a path you choose and tell the user.
The two things worth remembering are what the user asked to change and what went
wrong while running — because both are where a future run can do better from the start.
Method
Capture the user's requested changes. This is the primary signal. Walk the gate
history in state.yaml (gates): every revise/rework request and review finding the
human raised, the feedback/guidance text they gave, and anything they had to correct
so the output finally matched the requirement. Also read state.yaml's notes — the
out-of-band instructions the user gave mid-run — they are requested changes too. Read the
requirement itself (under .maestro/<slug>/requirement/) to frame each as the gap it
closed. Turn each into forward-looking guidance so the NEXT run gets it right the first
time — e.g. "list endpoints must paginate — requested at contract review on add-orders".
Capture the issues faced while running. Operational problems during the run: steps
that failed or retried, loops that hit their visit cap, contract-check / QA / build
breakages, worktree or merge trouble — anything (from visits/attempts/status,
failure reasons, and the artifacts) that made the run stumble. Turn each into a lesson
that helps a future run avoid it.
Add to / refresh the living docs — technical, functional, AND architectural. Using
the same structure build-knowledge produced, for every domain the feature touched:
- Technical (
docs/technical/<domain>.md) — CREATE the file if the feature introduced
a new domain; otherwise update it (new or changed modules, schemas, APIs, storage, jobs).
- Functional (
docs/functional/<domain>.md) — likewise: create for a new domain, else
update (new or changed behaviour, business rules, flows, edge cases).
- Architectural (
docs/architecture.md) — whenever the feature added or changed a
service, component, connection, or data flow: add the new node(s)/edge(s) to the Mermaid
diagram(s) and the matching entry in the "How services connect" section.
- Per-repo codebase map (
docs/codebase-map.md in each affected repo) — run
python3 .maestro/engine/codebase_scan.py plan to get, per repo, the files changed since
the map was last recorded; update ONLY those areas (new/changed flows, execution modes,
APIs, conventions). A repo reported current is unchanged — skip it. Do NOT touch the
<!-- maestro-codebase-map commit=… --> marker — the engine restamps it after you write.
Create files that don't exist yet; edit existing ones in place (never duplicate). Skip a
surface only when the feature genuinely did not affect it — but wherever it did, ADD the
content, don't just tweak.
Emit a structured lessons drop. Write the incoming file named in your instruction as JSON:
{
"slug": "<this run's slug>",
"lessons": [
{"domain": "backend-review", "key": "n-plus-one-list-endpoints",
"text": "Check for per-row queries in loops before approving."}
]
}
domain — the consuming SDLC role the lesson helps (plan, backend-design,
backend-review, architecture-review, or codebase for cross-cutting facts).
key — a short, stable, kebab-case identifier for the pattern. Pick it so a DIFFERENT
run observing the same pattern would choose the SAME key — that is how the engine
corroborates across runs. Do not encode the slug or a date in the key.
text — one short, actionable sentence.
- Do NOT set
authoritative (that is for bootstrap). Do NOT write knowledge/ or
candidates/ — the engine renders those.
Standards
- A lesson is a repeatable pattern, not a one-off event narration. If it only makes sense for
this feature, leave it out.
- Keep
text short; injected knowledge is paid for in tokens on every future run.
Safety
- Read-only against application code; writes are limited to the incoming JSON drop named in
your instruction and the living docs it refreshes (the central
docs/ tree and each repo's
docs/codebase-map.md). Never edit application code or run state.
Output contract
Return incoming_path (the JSON file written), lessons_count (integer), and summary
(one line).
1---2name: retrospect3description: Distill a finished Maestro run into structured, keyed lessons staged for the engine to consolidate. Front door for /retrospect.4---56# retrospect — turn one run's outcomes into staged lessons78Read a finished feature run and extract what future runs should know. You produce ONLY a9structured per-run drop; the **engine** (`mem_consolidate.py`) owns counting, corroboration,10promotion and rendering — none of that is your concern, so a replacement skill only has to11emit the same drop for the memory system to keep working.1213## Inputs14Your instruction names the run to read (its ledger + artifacts) and the single incoming JSON15file to write. Standalone? Write to a path you choose and tell the user.1617The two things worth remembering are **what the user asked to change** and **what went18wrong while running** — because both are where a future run can do better from the start.1920## Method211. **Capture the user's requested changes.** This is the primary signal. Walk the gate22 history in `state.yaml` (`gates`): every revise/rework request and review finding the23 human raised, the `feedback`/`guidance` text they gave, and anything they had to correct24 so the output finally matched the requirement. Also read `state.yaml`'s `notes` — the25 out-of-band instructions the user gave mid-run — they are requested changes too. Read the26 requirement itself (under `.maestro/<slug>/requirement/`) to frame each as the gap it27 closed. Turn each into forward-looking guidance so the NEXT run gets it right the first28 time — e.g. "list endpoints must paginate — requested at contract review on add-orders".292. **Capture the issues faced while running.** Operational problems during the run: steps30 that failed or retried, loops that hit their visit cap, contract-check / QA / build31 breakages, worktree or merge trouble — anything (from `visits`/`attempts`/`status`,32 failure reasons, and the artifacts) that made the run stumble. Turn each into a lesson33 that helps a future run avoid it.343. **Add to / refresh the living docs — technical, functional, AND architectural.** Using35 the same structure `build-knowledge` produced, for every domain the feature touched:36 - **Technical** (`docs/technical/<domain>.md`) — CREATE the file if the feature introduced37 a new domain; otherwise update it (new or changed modules, schemas, APIs, storage, jobs).38 - **Functional** (`docs/functional/<domain>.md`) — likewise: create for a new domain, else39 update (new or changed behaviour, business rules, flows, edge cases).40 - **Architectural** (`docs/architecture.md`) — whenever the feature added or changed a41 service, component, connection, or data flow: add the new node(s)/edge(s) to the Mermaid42 diagram(s) and the matching entry in the "How services connect" section.43 - **Per-repo codebase map** (`docs/codebase-map.md` in each affected repo) — run44 `python3 .maestro/engine/codebase_scan.py plan` to get, per repo, the files changed since45 the map was last recorded; update ONLY those areas (new/changed flows, execution modes,46 APIs, conventions). A repo reported `current` is unchanged — skip it. Do NOT touch the47 `<!-- maestro-codebase-map commit=… -->` marker — the engine restamps it after you write.48 Create files that don't exist yet; edit existing ones in place (never duplicate). Skip a49 surface only when the feature genuinely did not affect it — but wherever it did, ADD the50 content, don't just tweak.514. **Emit a structured lessons drop.** Write the incoming file named in your instruction as JSON:5253 ```json54 {55 "slug": "<this run's slug>",56 "lessons": [57 {"domain": "backend-review", "key": "n-plus-one-list-endpoints",58 "text": "Check for per-row queries in loops before approving."}59 ]60 }61 ```6263 - `domain` — the consuming SDLC role the lesson helps (`plan`, `backend-design`,64 `backend-review`, `architecture-review`, or `codebase` for cross-cutting facts).65 - `key` — a short, stable, kebab-case identifier for the *pattern*. Pick it so a DIFFERENT66 run observing the same pattern would choose the SAME key — that is how the engine67 corroborates across runs. Do not encode the slug or a date in the key.68 - `text` — one short, actionable sentence.69 - Do NOT set `authoritative` (that is for bootstrap). Do NOT write `knowledge/` or70 `candidates/` — the engine renders those.7172## Standards73- A lesson is a repeatable pattern, not a one-off event narration. If it only makes sense for74 this feature, leave it out.75- Keep `text` short; injected knowledge is paid for in tokens on every future run.7677## Safety78- Read-only against application code; writes are limited to the incoming JSON drop named in79 your instruction and the living docs it refreshes (the central `docs/` tree and each repo's80 `docs/codebase-map.md`). Never edit application code or run state.8182## Output contract83Return `incoming_path` (the JSON file written), `lessons_count` (integer), and `summary`84(one line).