---
name: project-retro
description: "Project retrospective workflow (cross-skill): collect real execution evidence → three-way defect attribution (wrong rule / missing rule / drift) → reverse attribution to gates → score an audit of existing rules → produce a change table → lock in after user approval and run regressions. The deliverable is a **change table**, not a report; an empty table means the retrospective is unfinished. Use when the user asks for a \"retrospective\", \"project summary\", \"sum up the lessons\", \"post-mortem analysis\", \"where did this round get reworked\", \"put the findings back into the skill\", \"capture the lessons\", \"retrospective\" or \"postmortem\"."
---

> Original skill · commissioned by the user · English edition, 2026-11-12

# Project Retrospective Workflow (cross-skill orchestration layer)

> This skill **adds no knowledge**; it governs "how to run a retrospective effectively".
> Each skill's `LESSONS.md` is the **ledger** (what to record, how to upgrade, how to deprecate);
> this skill is the **procedure** for executing a retrospective (when to do it, in what order, what counts as the criterion, what it produces, who approves).

## 0. Division of labour between the three skills (do not mix them up)

| Layer | Carrier | Responsibility |
|---|---|---|
| Ledger | each skill's `LESSONS.md` | record one lesson, its status transitions, upgrade/demotion thresholds |
| Protocol | each skill's `SKILL.md` § feedback protocol | trigger timing, the three retrospective questions, landing-spot mapping |
| **Procedure** | **this skill** | **how to actually finish a retrospective on one round**: evidence → attribution → audit → changes → approval → regression |

**Relationship**: at the moment of the retrospective this skill **orchestrates** each skill's ledger and protocol, and writes the result back when it ends.

---

## 1. Six stages (**the order cannot be skipped, above all do not jump to B**)

```
A collect evidence → B attribute → C rule audit → D change table → [E user approval] → F lock in + run regressions
(script run)      (three-way + reverse)  (tick off)   (empty = unfinished)   (the only change point)   (locked by test cases)
```

### A Collect evidence (**hard gate 1: no evidence file, no attribution**)

```powershell
python scripts/retro_scan.py --project <PROJECT> --skills <skill dirs...> `
       --out <PROJECT>/review/retro_evidence.md --json <PROJECT>/review/evidence.json
```

All eight evidence classes are machine-readable: timeline / retry traces / aspect ratio / cost / review rejections / distribution completeness / ledger state / rule list.
Details and "how to fill the gaps when it cannot be read" are in `references/01-evidence-collection.md`.

> ⚠️ **Never write a retrospective from memory.** Memory mistakes "the thing remembered most vividly" for "the most serious thing".
> Anything the evidence cannot show must be explicitly marked "needs manual entry"; **do not guess**.

### B Attribution (three-way classification + reverse attribution to gates)

Judge **every single** rework evidence item:

| Three-way (`references/02`) | Meaning | Direction of action |
|---|---|---|
| **Wrong rule** | the rule itself is wrong or out of date | change the rule |
| **Missing rule** | there is no such rule at all | add a rule |
| **Rule right but drifted** | the rule exists and was not followed during execution | **change the landing spot** (something that belongs in a script was written as prose) |

Then ask one more question: **which gate should have stopped this defect?**

- If you can answer → the gate **did not fire** (→ rule right but drifted) or **its threshold is too low** (→ wrong rule)
- If you cannot answer → record **`unmapped`** and write "this is a new class of risk".
  **⛔ Do not force an attribution onto some gate** — a wrong attribution adds a rule that catches nothing next time.

### C Rule audit (score the **existing** rules, not only new lessons)

Tick off every rule in the rule list in `retro_evidence.md` §8: `+hit` / `+violated` / `+not applicable`.
Output **the list of rules that never hit** — this is the only basis for demotion or removal. See `references/03`.

> Recording only new lessons and never auditing old rules = the skill only grows and never shrinks, until it becomes a long document nobody reads.

### D Change table (**hard gate 2: an empty table = the retrospective is unfinished**)

Use `templates/retro_table_template.md`, one row per item:

`which file | what change | three-way type | threshold basis | pending approval?`

**The threshold basis must be citable**: which lesson met "reproduced ≥2 times" or "one occurrence with a real cost".
If you cannot cite one → leave the status at `Observing`; **it does not enter the change table**.

### E Approval (**hard gate 3: this round's deliverable is a proposal, not an edited skill**)

Editing skill files is a **separate step that requires explicit user approval**. At the end of the retrospective, deliver only the change table.
(Source: `nacl-postmortem` in `ITSalt/NaCl` states explicitly "No skill edits in this deliverable".)

### F Lock in (only after approval)

1. Edit the files per the change table (`LESSONS.md` ledger / `SKILL.md` rules / `references` craft / `scripts` checks)
2. **If `scripts/` or a threshold changed → you must run that skill's `tests/run_tests.py`**
3. After each row of the change table is done, go back to `LESSONS.md`, change the entry status to `Upgraded` and **fill the "landing spot" column**
4. Append this round's new lesson as one row using `templates/lessons_entry_template.md`

---

## 2. Hard gates (seven)

1. **Evidence first**: no `review/retro_evidence.md`, no attribution.
2. **An empty table means unfinished**: an empty change table = nothing was captured this round; **do not mark it "retrospective complete"** (that is a diary, not a retrospective).
3. **Proposals only**: do not touch any skill file without approval.
4. **Quote verbatim**: the user's exact words, the raw log text and error codes are **copied**, not paraphrased (paraphrasing loses the decisive qualifier).
5. **Honest `unmapped`**: do not attribute every defect to an existing gate; if you cannot answer, write `unmapped`.
6. **Regressions after every change**: if you touched a script or a threshold you must run `tests/run_tests.py`; it is done only when all green.
7. **Every conclusion carries its measurement basis**: whenever you give a **number** (project count / skill count / overspend / hit rate / coverage),
   you must give the **measurement basis** and a **reproducible command** at the same time; an unmeasured number **must not be written as fact**, only as "not measured".
   Basis: a past report stated a skill count that did not match the measurement, and the user made decisions on that figure.

## 3. Success retrospective branch (**successes get a retrospective too**)

A–F is the **defect** retrospective procedure. A success case runs the same procedure, but the stage-B questions **are replaced by four others**
(full text in `references/05-success-retrospectives.md`):

1. What was **done right** this time? — one sentence, **no adjectives**
2. **Which pressure** forced it out? — pick one of four and give the evidence: **repetitive work / environmental constraint / open slot in the map / being reminded**
3. Under the same conditions, **why did it not happen elsewhere**? — find the mechanism; **do not attribute it to "conscientiousness"**
4. Can it become a **mechanism** so that it happens next time **without relying on conscientiousness**?

**The four checks for question 3** (all required):

| Check | How it is asked |
|---|---|
| Reproduction count | how many times has this pain point occurred? (**≥2** before it is worth locking in) |
| Evidence form | is there **clear physical evidence of the failure/success**? |
| Decidability | can the conclusion be written as an **executable rule**? |
| **Evidence survival** | are the files that back the retrospective **still there**? |

> ⚠️ **The fourth is the deadliest**: if the evidence is deleted, the project can never be retrospected.
> Measured in a past audit: a `<SESSION_STORE>` folder held **0 files**, and the working directories of most of its threads were already cleaned up —
> those efforts left nothing that could be retrospected. **The first obstacle to capture is not habit; it is whether the evidence is still alive.**

**Assess maturity → propose a skill** (**5 metrics + 4-step gate**, see `references/05` §7):
reproduced ≥3 times / steps stable / every step has a checkable output / ≥2 known failures / does not depend on a single context.
**Propose only when all 5 pass; the proposal must state "skill name + responsibility + overlap boundary with existing skills + cost (skill list +N)";
build only after approval.** ⚠️ **Mature ≠ must create a new skill** — if it can land as a gate or a discipline inside an existing skill, do not add a skill.

**Success and defect retrospectives share the same change table** (`templates/retro_table_template.md`);
fill the "three-way type" column with "pressure source" instead.

## 4. Anti-patterns (six reasons retrospectives fail)

| Anti-pattern | Consequence | Correct approach |
|---|---|---|
| Writing the retrospective from memory | you remember what stung most, not what cost most | run `retro_scan.py` first |
| Writing the retrospective as praise / self-criticism | no executable output | produce a change table |
| Attributing every problem to "be careful next time" | the same mistake next time | three-way classification + a named landing spot |
| Forcing an attribution onto some gate | adds a rule that stops nothing | record `unmapped` |
| Recording only new lessons, never auditing old rules | the skill only grows and never shrinks | tick off in stage C + deprecation candidates |
| Editing the skill on the spot during the retrospective | the change skipped approval and ran no regression | A–D produce proposals only; F edits after E approves |

## 5. Trigger timing

- after a project delivery (**default**)
- when the user says "retrospective", "sum it up", "where did this round get reworked"
- when the same class of defect **appears a second time** (the upgrade threshold is already met, so it deserves its own retrospective)
- after a delivery is rejected / a clear budget overrun (**do not wait for wrap-up; do it immediately**)

## 6. Reference sources (external projects, **borrow the method, not the code**)

| Project | License | What was borrowed |
|---|---|---|
| [ITSalt/NaCl · nacl-postmortem](https://github.com/ITSalt/NaCl) | MIT | **reverse attribution between defects and gates**, the "wrong / missing / drifted rule" three-way split, the **honest `unmapped` exit**, **no skill edits during the retrospective** |
| [Ecrypted-Data/Evolve-Skill](https://github.com/Ecrypted-Data/Evolve-Skill) | Apache-2.0 | scoring an audit of **existing rules** (+hit/+violated/+not applicable), rule↔event traceability, non-destructive appends |
| [imgabrieldev/hexagram · postmortem](https://github.com/imgabrieldev/hexagram) | — | **"an empty change table means the retrospective is unfinished"** (a retrospective without changes is just a diary) |
| [z3z1ma/10x · Compounding](https://github.com/z3z1ma/10x) | — | routing lessons **to different record types by nature**; observations that lead to no action still get a **no-action reason** |

> All four are **software-engineering** retrospectives (SRE incidents / dev workflow / skill-gap audits),
> and **none of them targets content-creation projects** — so this skill implements its own, borrowing only the method skeleton above.
> Text and scripts are self-written; no code was copied from those projects.

---

## Working discipline (three hard rules, **read before changing anything**)

**① Research first** — before creating or heavily changing a skill or a process, you must first check the **skills already on this workstation** and the **online space (GitHub / plugin marketplaces)** for an existing solution, and give the three-part conclusion: **what was found → adopt / do not adopt → why**.

- A reason for not adopting must be specific (license restriction / conflict with existing rules / maintenance cost / context burden); "not suitable" is not allowed
- When a reusable solution is found, **reuse it or borrow only the method**; do not rewrite it
- Basis: three recurrences (an audio round asking "what open-source options exist", a script skill asking "check whether one already exists before building", a retro skill asking "online and offline")

**② Do not expand scope on your own** — scope expansion the user did not ask for is **proposed only, never executed**;
a proposal must **state the cost explicitly** (skill list +N items, per-round context +X, how many files added), and the user decides.

- Exception: when not expanding scope would lead to a **wrong conclusion or a safety risk**, stop and explain instead of continuing on your own initiative
- Basis: the round-trip where "operate a body-copy-level lint" was borrowed and then reverted

**③ Budget first** — **make the budget → report the budget → plan within the approved amount → keep the ledger → reconcile**, a five-step loop.
**You may not start until ① and ② are done; you may not call any paid interface until ③ is passed.**

| Step | Action | Hard requirement |
|---|---|---|
| ① **Make the budget** | `python <PIPELINE>/scripts/budget_plan.py --budget <amount> --durations <shot seconds> --plan-out <PROJECT>/spend_plan.md` | must include a **rework reserve** (default 25%, not optional) and a **tier lock** |
| ② **Report the budget** | hand the plan to the user and obtain an **explicitly approved amount** | an empty "approved amount" field in the plan = **not approved = do not start** |
| ③ **Plan within the amount** | scope / shot count / duration / tier are **back-solved from the amount** | amount too small → **cut scope** (lower tier → fewer shots → shorter duration); **do not exceed the budget** |
| ④ **Keep the ledger** | book every charge immediately, **including rejected ones at 0** | planning without booking actuals = the easiest place to fail (a past run overspent because of it) |
| ⑤ **Reconcile** | settle: plan vs paid | more than **10%** over plan → stop and re-request approval; **changing tier = changing the plan = re-requesting approval** |

```powershell
# 1) make the budget (amount -> plan; the price table reuses cost_preflight.py, single source of truth)
python <PIPELINE>/scripts/budget_plan.py --budget 6 --durations 4,4,4 --anchors 1 --plan-out spend_plan.md
# 2) when you only know the amount, first solve for the maximum number of shots
python <PIPELINE>/scripts/budget_plan.py --budget 6 --max-shots --duration-each 4
# 3) ledger / audit / gate (over budget exits with code 1)
python <PIPELINE>/scripts/cost_ledger.py add --ledger <PROJECT>/cost_ledger.json --item "clip_01" --cost 1.20
python <PIPELINE>/scripts/cost_ledger.py check --ledger <PROJECT>/cost_ledger.json
```

- Measured: with a budget of 6 units, **a single 4-second shot at the main tier (14.96) already overspends by 2.5x** — planning without counting money guarantees rework
- Division of labour between the three tools: `budget_plan.py` amount → plan | `cost_preflight.py` storyboard → money | `cost_ledger.py` actuals → ledger
- Basis: **most past projects kept no ledger**; a past round paid far over plan
