Files

39 KiB
Raw Permalink Blame History

name, description, triggers, role
name description triggers role
retrospective Use ONLY when running a retrospective at the end of any work cycle (release, feature, bugfix, port). The Retrospective Lead (Worker) inspects project facts — git log, file churn, test history, commit patterns — and generates actionable improvement items. No pipeline artifacts required.
retrospective
复盘
lessons learned
post-mortem
postmortem
Producer

Core 中立版(Increment 6a 改写,原 deferHard verbatimDir)。机制、结构与 frontmatter 保持;实例术语(工具名、路径、工单号)按 core/adapters/TERMINOLOGY.md 绑定到具体实例。

Retrospective

Inspect the project's recent work cycle to extract patterns and generate concrete action items. Based purely on project facts: git history, code churn, commit quality, test results, and build health.

Purpose: Continuous improvement of BOTH the project AND the SDLC pipeline itself. Every retrospective may modify templates, checklists, or SKILLs.

Agent Role

The retrospective is owned and executed by the Retrospective Lead (Worker).

Context compaction: retrospective is a pipeline stage boundary. The main session compacts at this clean boundary ONLY when a capacity/projection trigger holds, per core/rules/compact.md §"Stage-boundary compaction" (long multi-stage runs — DAG Epic orchestration — keep the legacy every-boundary compaction; short runs — bugfix / DAG task — and standalone runs default to NOT compacting). The Retrospective Lead itself is single-phase and data-driven: all findings are written to the retrospective report as they are produced, so a mid-run compaction loses nothing — re-read the report artifact to resume.


Preconditions

Before starting the retrospective:

  • A work cycle has been completed (release was cut, feature merged, bug fixed, or port landed).
  • The project is a git repository with recent commits.
  • core/checklists/retrospective.md is accessible.

No .artifacts/{slug}/ files are required. (Deprecated: .artifacts/ file-system access is being migrated to Gitea wiki. SDLC artifacts now live as wiki pages under {slug}/; use wiki 读写 API(见 TERMINOLOGY and wiki 读写 API(见 TERMINOLOGY to read them.) The retrospective reads the project's own state and git history.


Phase 1 — Scope the Cycle

Determine the time range to analyze:

  1. If a release was just done: use git log <last-tag>..<new-tag>.
  2. If no tag exists: prompt the user for a time range or revision range (e.g. HEAD~20..HEAD, or --since="last work cycle").
  3. If the user specifies a range, use that.
## Cycle Scope

**Range**: {commit range or "last work cycle"}
**Date**: {start} → {end}
**Commits analyzed**: {N}
**Authors**: {names}

Phase 2 — Collect Data

Run project-inspection commands and summarize findings:

2.1 Commit patterns

git log {range} --oneline --no-merges
git log {range} --format='%s' | grep -cE '^(BREAKING|feat|fix|perf|refactor|docs|chore)'
  • Count commits by type (BREAKING, feat, fix, refactor, etc.).
  • Flag commits with no conventional prefix — these are opaque and hard to trace → log as [SIGNAL: low commit hygiene].
  • Count revert commits (git log {range} --grep="Revert" --oneline).
    • High revert count → likely insufficient testing or review before merge.

2.2 File churn

git diff --stat {range}
git diff --numstat {range} | sort -k1 -rn | head -20
  • Identify the most-churned files (top 10 by lines added + deleted).
  • High churn in a single file (> 200 lines in one cycle) → possible monolithic module, design issue, or scope creep.
  • List new files vs. deleted files.

2.3 Test health

  1. Run the test suite: confirm pass/fail count and duration.
  2. Check if any test files changed during the cycle:
    git diff --name-only {range} | grep -E 'test|spec|__tests__'
    
  3. If test files were NOT changed but source files were → [SIGNAL: untested changes]. Architecture-A exemption: If the cycle touches ONLY <instance-root>/ and .gitea/ files (config, skills, templates, rules, checklists) with zero packages/* source changes, the "untested changes" signal does NOT apply — <instance-root>/ files are validated by the audit-process review gate, not by unit tests. Record this as [NOTE: Architecture A — config-only cycle, unit-test exemption applies] in the test summary.
  4. Check for skipped/flaky tests if the framework reports them.

2.4 Build health

  1. Run bun typecheck (or project equivalent). Note first-time errors.
  2. Run bun oxlint --deny-warnings (repo root; bun lint is the package-script alias). Note any first-time warnings.
  3. If the project has CI, check the latest run status.

2.5 Dependency health

  1. Run bun audit (or equivalent). Flag any new HIGH/CRITICAL CVEs.
  2. Check if any dependency was added/removed/upgraded:
    git diff {range} -- package.json bun.lockb
    

2.6 Process quality

Inspect the SDLC infrastructure around the project — not just the code, but the factory that produces it. These checks are all file-existence and configuration reads; they require zero prior pipeline artifacts.

  1. Pre-commit guards:

    • Does the project have pre-commit hooks? (Check .husky/, lefthook.yml, .pre-commit-config.yaml, package.json "lint-staged" key.)
    • If absent → [GAP: no pre-commit guard — bad code can land].
    • If present → what commands do they run? (lint? typecheck? test?)
  2. CI/CD pipeline:

    • Does CI exist? (Check .gitea/workflows/ — this repo's CI location — then .github/workflows/, .gitlab-ci.yml, Jenkinsfile, etc.)
    • If absent → [GAP: no CI — no automated gate before merge].
    • If present → does it block merge on failure? Check branch protection (GitHub: gh api repos/{owner}/{repo}/branches/main/protection).
  3. Code review practice:

    • Does the project have a review template or guideline? (Check .github/PULL_REQUEST_TEMPLATE.md, CONTRIBUTING.md, etc.)
    • Are PRs used? Look at merge commits: do they reference PR numbers?
    • If direct pushes to main → [SIGNAL: no review gate].
  4. SDLC artifacts:

    • Use wiki 读写 API(见 TERMINOLOGY(owner="Octopus", repo="octopus") to check for {slug}/ wiki pages (.artifacts/ file-system access is retired — SDLC artifacts now live as wiki pages under {slug}/).
    • If no {slug}/ pages exist → [NOTE: no structured SDLC artifacts — decisions not traceable].
    • If present but stale → [SIGNAL: artifacts not maintained — process drift].
  5. Tooling consistency:

    • Does the project have a unified formatter config? (.prettierrc, biome.json, etc.)
    • Does it have a unified typecheck/lint/test command? (Check package.json scripts.)
    • Are there multiple competing tools for the same concern? (e.g. both prettier AND biome, both jest AND vitest.)
  6. Documentation health:

    • Does README.md include setup, build, and test instructions?
    • Does AGENTS.md or <instance-root>/AGENTS.md exist?
    • Are there any outdated docs? (Check for files referencing removed commands or directories.)

2.7 Token telemetry

Collect LLM token-consumption signals to assess workflow quality. Five metrics: M1 from an inline check; M2M5 from the token-telemetry probe.

  1. M1 — Review convergence. The number of rounds each review dimension needed to converge is the strongest signal of upstream-stage quality.

    Discover review rounds via wiki 读写 API(见 TERMINOLOGY(owner="Octopus", repo="octopus") with prefix {slug}/reviews/ (.artifacts/ file-system listing is retired). For each review, max(roundN) is its convergence round count.

    • 🟢 12 / 🟡 34 / 🔴 ≥5.
    • ≥5 rounds → [SIGNAL: review convergence ≥5 — upstream stage quality insufficient, rework deferred to review].

    The remaining four metrics come from a single probe run:

    bun run core/skills/retrospective/scripts/token-telemetry.ts
    

    It scans ~/.local/share/octopus/octopus-*.db (token usage) and review rounds from two sources — the Tier 1 review-status file <runs-root>/{slug}/reviews/{stage}/status.json (canonical — reads the history[] field (legacy alias rounds[]) and current_round) with the legacy .artifacts/**/reviews/*/status.json tree fallback, plus the committed archive bundles <runs-root>/archive/{slug}.json for closed runs — and prints M2M5.

  2. M2 — Stage distribution. Token spend per pipeline stage (design, review, implement, …). The probe reconstructs a per-session stage timeline from ~/.local/share/octopus/token-stage-ledger.jsonl — written by the auto-discovered <instance-root>/plugin/token-stage-ledger.ts plugin, which hooks tool.execute.after on the skill tool — and attributes each message's tokens to the stage active at its creation.

    • Ledger-gated. If the plugin was not active during the cycle the ledger is absent and the probe prints [NOTE: token-stage-ledger.jsonl absent — M2 skipped]. That is "unavailable", not "failed" — proceed.
    • Review-stage share: 🟢 <35% / 🟡 3560% / 🔴 >60%.
    • 60% → [SIGNAL: review stage >60% of token spend — over-reviewing, review findings not actionable upstream].

  3. M3 — Review rework. Rework fraction — review rounds beyond the first as a share of total review rounds. The probe merges two sources, deduped by {slug}/reviews/{stage} (the ACTIVE status.json wins): (a) the Tier 1 review-status file <runs-root>/{slug}/reviews/{stage}/status.json (canonical — history[] field, legacy alias rounds[], and current_round; skips _archive/) with the legacy .artifacts/**/reviews/*/status.json tree fallback — in-flight runs only, since the active workspace is deleted at archive-at-close; (b) the committed archive bundles <runs-root>/archive/{slug}.json, where per-review round counts are reconstructed from the documented reviews/{stage}/round{N}/ layout in index.artifacts[].path ([org-internal #2591] — the archive source is what makes M3 durable instead of structurally emptying as runs close). Available once any run has closed.

    • Rework fraction: 🟢 <15% / 🟡 1530% / 🔴 >30%.
    • 30% → [SIGNAL: rework fraction >30% — review findings not actionable or upstream design unclear].

  4. M4 — Context hygiene. Per-session input-token growth and cache efficiency, read from the octopus session database. The cache read/input ratio measures context reuse.

    • 🟢 cache_read/input > 10:1 / 🟡 310:1 / 🔴 < 3:1.
    • < 3:1 → [SIGNAL: cache hit <3:1 — context re-read, code-graph-first not followed].
    • Compact frequency ([org-internal #2601] pilot data): report the token-telemetry "Compactor Activity" line (compactor messages/tokens in window) and the zero-compact share of short runs (bugfix / DAG task) — the capacity-driven compaction pilot metrics. A rising zero-compact share with NO late-stage degradation signal is the evidence that retires the pilot gate in rules/compact.md § Stage-boundary compaction.
  5. M5 — Explore/execute ratio. Token spend by agent type (data.agent per message). A low ratio means workers are doing explorers' job — context-gathering that should be delegated.

    • 🟢 > 2:1 / 🟡 12:1 / 🔴 < 1:1.
    • < 1:1 → [SIGNAL: explore/execute <1:1 — workers doing explorers' job, exploration skipped or under-delegated].

2.8 Gate defect-escape analysis (single metric, [org-internal #3061])

Gates earn their cost by what they CATCH, and the honest test is what slips past them: a gate that runs clean while the same defect resurfaces downstream is under-powered — the opposite of redundant. This probe computes ONE metric per gate_id (the legacy per-(Kind × Size × gate) keying is retired with the sizing subsystem — sub-5 cell counts produced noise, not evidence):

escape_rate = clean runs with a downstream escape / clean runs

  • Clean run: the gate ran on a cycle ticket and passed round 1 with zero INFO-or-worse findings.
  • Downstream escape: within 14 days after the clean gate, either (a) a verify FAIL/WARN finding in the same area (module/dimension) on the same ticket, or (b) a post-merge Kind/Bug ticket whose body references the area the gate covered.

Data sources (all read-only):

  • Review status: commit-status context pipeline/{review_type} (_shared/gitea-write-patterns.md Pattern 8), read via octopus review status CLI or commit-status inspection. Final reports at {slug}/reviews/{stage}/final/report record round count and highest severity.
  • Downstream (a): verify reports {slug}/05-verify-iteration-{N} for the same slug.
  • Downstream (b): 工单 API(见 TERMINOLOGYlist(labels="Kind/Bug", state=closed) within the window; match by module/path references in the body.
  • slug ↔ issue map: the issue's ## 工件索引 comment (legacy: ## Pipeline 工件追踪表) or Closes #N in the PR body.

Procedure:

  1. Enumerate closed tickets in the cycle with any review run; resolve slugs.
  2. Per gate run: classify clean / not-clean; for clean runs, search both downstream sources for an escape.
  3. Tally per gate_id: clean_runs, escapes, escape_rate.
  4. Reading (thresholds are this skill's own policy — the gate_trim: block they once deferred to was retired 2026-08-21, [org-internal #3072] phase 3; nothing trims gates anymore, so the trim-candidate branch below is gone):
    • escape_rate ≥ 0.3 → the gate is UNDER-POWERED: route the escape causes into §2.9 pre-flight (producer-side self-checks) and note the gate in the report. Do NOT propose trimming it.
    • escape_rate < 0.3 → healthy; report the numbers, no further verdict.

DAG single-gate exclusion ([org-internal #2267]): review-dag is structurally non-trimmable (dag.route.single_gate.never_trim: true — self-contained in the dag: block); verify and merge-pr were never_trim in the retired gate_trim block and stay untouchable by convention.

keep_gates exclusion (TD-390, [org-internal #3061]) — RETIRED with gate_trim: the rule that a trim candidate's gate must not be a member of the target route's keep_gates guarded a landing field (sizing.tiers.*.additional_skip) that no longer exists. Historical record: wiki rules/gate-trim.

Sample-sufficiency gate (structural, not optional): fewer than 5 clean runs for a gate → report the raw numbers with [NOTE: insufficient sample for gate {id}] and emit no verdict for it.

### Gate defect-escape (M6)

| gate                                | clean runs | escapes | escape_rate | verdict                   |
| ----------------------------------- | ---------- | ------- | ----------- | ------------------------- |
| review-code                         | 12         | 1       | 0.08        | healthy                   |
| review-design-space (sticky legacy) | 6          | 3       | 0.50        | UNDER-POWERED → feed §2.9 |
| ...                                 | ...        | ...     | ...         | ...                       |

- [NOTE: insufficient sample for gate X] where clean runs < 5.
- UNDER-POWERED gates (escape_rate ≥ 0.3) feed §2.9 pre-flight — never a
  unilateral trim: the only exit is a furlough entry in
  `<instance-root>/gate-ledger.yaml` (evidence + reopen condition, [org-internal #3607]).

2.9 Pre-flight defect-prevention analysis ([org-internal #2599])

First-round FAIL/WARN findings are the pipeline's cost multiplier: every multi-round review pays for them twice (review round + revision round). This probe tallies their root causes and proposes producer-side self-checks — the defensive complement of the retired gate-trim meta-process: instead of removing a gate that never catches anything, inject the causes that keep costing rounds as a pre-flight checklist the Producer verifies BEFORE writing code.

Data sources (read-only, same as 2.8): review status pages / final reports for the cycle's tickets ({slug}/reviews/{stage}/final/report — round-1 findings with severity FAIL/WARN, their dimension codes, and the finding text for root-cause categorization) + the source issues' Kind/* labels. For DAG-routed Epics ([org-internal #2905] 方案 3), two further read-only sources feed the REQ × late-discovery root cause (step 1): (a) DAG oversize-signal eventsnode_split / registry-row additions recorded on the Epic's issue timeline / ## DAG 状态 whose trigger is a NEW requirement rather than a refactor; (b) demo-period feedback — stakeholder comments naming functionality the frozen DAG never covered. For browser-evidence cycles ([org-internal #4499], contract browser-evidence-4486/shared/evidence-ref-v1 §3), a third read-only source: (c) browser session rows — per browser-debug session {session_id, outcome: evidence-captured | env-unavailable | replay-failed, replay summary, env.mode}, derived from Tier-1 pack manifests (sanitized transitively by the N-03 write boundary — this probe never touches raw captures). Replay failure attribution rides the FIXED ReplayFailureCategory enum (browser-evidence-4486/shared/pack-manifest-v1 §4); env-unavailable sessions default to the enum's own environment slot (env-binary-missing) unless the row carries an explicit attribution; browser-class causes enter the step-2 route-class tally as BROWSER × {category} and a qualifying cause becomes a PRE-FLIGHT PROPOSAL candidate landing on routes.{Kind}.preflight (human-landed in Phase 6, never auto-applied). Rows are currently Task-DAG cycle products by default (the helper's --route-class override / row-level route_class field re-keys a future Bug- or Feature-cycle session to its own landing slot). The replay success-rate baseline (N-03 BENCH) is exposed as a consumable metric — a SEEDED CONVENTION (fixture-authored outcomes, channel health), NOT a live-browser trend baseline. Mechanical helper: <harness-package>/scripts/browser-retro-tally.ts. Boundary rules ([org-internal #4499] AC-3): out-of-enum or empty categories fall into an explicit other bucket with provenance (recorded, never silently swallowed, never a crash); rows missing replay/attribution fields yield structured errors in the tally output; a cycle with no browser session rows keeps this probe's current behavior (empty tally, no synthetic proposal rows).

Procedure:

  1. For each ticket with a multi-round review in the cycle, read the round-1 findings with severity FAIL or WARN. Categorize each by (dimension × root-cause) — the dimension code is checklist-qualified (checklist-local namespace; e.g. code-review.md TST × missing-boundary-test, code-review.md COR × unhandled-null, code-review.md STY × wrong-import-order). Canonical root-cause category for DAG-routed Epics: REQ × late-discovery — 冻结后才被发现的需求 (a requirement that surfaced only after the DAG froze). A late discovery usually manifests as a round-1 REQMAP FAIL on the re-run review, but the underlying event is an oversize signal or demo comment — count it from sources (a)/(b) above, not only from review findings.
  2. Tally per route-classBug, Feature-DAG, Epic-DAG-route, Task-DAG (Kind/Feature routes to the DAG pipeline since [org-internal #3061] Phase 2 / TD-388 — Feature-legacy survives only as a historical bucket for tickets closed before 2026-08-20; the Size dimension is retired from retro keying, [org-internal #3061]: DAG-routed tickets derive depth instead of carrying Size/* (spec-06), and Kind/Bug carries no ladder). First-round hit count and distinct-ticket count per cause per class.
  3. A cause is a pre-flight candidate when ALL hold (thresholds from workflow-routing.yaml preflight — do NOT restate values here):
    • hit count ≥ preflight.min_sample
    • distinct tickets ≥ preflight.consecutive_recur A qualifying Epic × DAG-route cause (e.g. REQ × late-discovery) lands on <instance-root>/workflow-routing.yaml dag.route.preflight — NOT routes.Kind/Epic.preflight (legacy-roadmap-era landing; the legacy route was archived [org-internal #3072] phase 3) ([org-internal #2905] 方案 3). The analyze-dag skill reads dag.route.preflight before decomposition.
  4. Aging: for causes ALREADY landed in routes.{Kind}.preflight or dag.route.preflight, count consecutive clean first rounds since landing (from this and prior retro data); at ≥ preflight.aging_consecutive_clean, emit a REMOVAL row.

Sample-sufficiency guard mirrors 2.8: zero qualifying tickets → emit [NOTE: insufficient sample for pre-flight proposals] and skip this probe.

### Pre-flight defect prevention (M7)

| route-class    | Cause (checklist-qualified dim × root-cause) | 1st-round hits | tickets                     | qualify?                         |
| -------------- | ------------------------------------------- | -------------- | --------------------------- | -------------------------------- |
| Bug            | code-review.md COR × unhandled-null         | 5              | 4 ([org-internal #2400] [org-internal #2429] [org-internal #2471] [org-internal #2488]) | ✅ PROPOSE                       |
| Bug            | code-review.md STY × wrong-import-order     | 6              | 2                           | ⛔ tickets <3                    |
| Feature-DAG    | code-review.md TST × missing-boundary-test  | 3              | 3                           | ⛔ hits <5                       |
| Epic-DAG-route | REQ × late-discovery        | 5              | 3 (#27xx #28xx #29xx)       | ✅ PROPOSE → dag.route.preflight |

- [NOTE: no pre-flight proposals] if the table is empty or nothing clears threshold.
- ✅ PROPOSE rows feed Phase 5 PRE-FLIGHT PROPOSAL action items.
- Landed-item aging: `cor-unhandled-null clean streak 5 ≥ aging 5` → REMOVAL row.

2.10 Derived-ticket health ([org-internal #3061])

Derived tickets (TD promotions, BF umbrellas, FT tickets) are the pipeline's exhaust. Unmanaged they accumulate into flush cycles (2026-08 evidence: 122 open tech-debt tickets, ~9.4/day creation, zero pre-August closures, a 115-ticket bulk flush). Under the registry-first regime (verify Phase 5.5) this probe checks whether the system DIGESTS what it records:

Metrics (cycle window):

  • TD flow: registry rows created / rows promoted to tickets / promoted tickets closed-as-fixed vs closed-as-wontfix.
  • Median open age: open TD rows + promoted tickets, by module/origin.
  • BF triage compliance: % of verify-Phase-5.55 BF umbrellas triaged (assigned or scheduled) within 1 day of filing.
  • FT expiry compliance: % of verify-Phase-5.56 FT tickets fixed-or- isolated within their N-day window.
  • Per-module open count vs the promotion quota (verify Phase 5.5).

Actions:

  • A category (module/origin) with creation ≥ fix across ≥2 consecutive retros → mark it register-only: verify Phase 5.5 stops promoting rows to tickets there until one retro shows net-negative backlog.
  • Open TD rows unclaimed for >3 retro cycles → mark the row [COLD] (revivable — a pull event clears the mark). Cold rows are excluded from adjacency-quota pressure and do not count against the module quota.
  • BF/FT compliance < 100% → name the untriaged/expired items in the report (they are SLA breaches, not statistics).
### Derived-ticket health (M8)

| metric                                    | this cycle | last cycle | trend |
| ----------------------------------------- | ---------- | ---------- | ----- |
| TD rows created / promoted / closed-fixed |            |            |       |
| median open-TD age (days)                 |            |            |       |
| BF same-day triage %                      |            |            |       |
| FT fix-or-isolate %                       |            |            |       |

- register-only categories: {list or "none"}
- rows marked [COLD] this cycle: {list or "none"}

2.11 Threshold calibration tally ([org-internal #3380])

Process prose constants (round caps, D1D4 thresholds, preflight knobs, escape-rate cutoffs, quotas — full index: docs/workflow-refactor/thresholds-ledger.md) are only as good as the data behind them. This probe keeps them honest, mirroring §2.9's propose-and-human- lands pattern:

  1. Round-cap distribution (per stage): read {slug}/reviews/*/final/report headers (**Rounds completed**: N) for the cycle's slugs; tally per stage (code / dag), report n / p50 / p90 / p95 / max, and how often the cap was the binding stop (Rounds completed == cap with Converged: false).
  2. CALIBRATION PROPOSAL rows: for any ledger constant whose data source this retro tallied, emit a proposal row — constant | current | observed | proposed | evidence — when the data contradicts the current value (cap never binding AND p95 ≪ cap → propose lowering; cap binding with converged-improving runs → propose raising). Proposals are never auto-landed: a human lands them by editing the definition site AND the ledger row in one PR citing this retro (preflight evidence-field pattern).
  3. Ledger sync: if any constant's definition site changed since the last retro (value or location), update the ledger row — drift between the two is a TD-480-class double-source failure.
### Threshold calibration (M9)

| stage                             | n       | p50      | p90      | p95                 | max | cap-binding runs |
| --------------------------------- | ------- | -------- | -------- | ------------------- | --- | ---------------- |
| code                              |         |          |          |                     |     |                  |
| dag                               |         |          |          |                     |     |                  |
| - CALIBRATION PROPOSAL: {constant | current | observed | proposed | evidence} or "none" |

- ledger sync: {rows updated or "none"}
## Data Summary

### Commits

| Type          | Count  |
| ------------- | ------ |
| BREAKING      | {N}    |
| feat          | {N}    |
| fix           | {N}    |
| refactor      | {N}    |
| docs/chore    | {N}    |
| **no prefix** | {N} ⚠️ |
| **reverts**   | {N}    |

### Churn Top 10

| File                  | +lines | -lines | Concern     |
| --------------------- | ------ | ------ | ----------- |
| src/{module}/large.ts | 200    | 150    | Monolithic? |
| ...                   | ...    | ...    | ...         |

### Tests

- Suite: {N} passed, {M} failed, {S} skipped — {duration}s
- Test files changed: {N} / {M}
- Untested source changes: {list or "none"}

### Build

- Typecheck: ✅ / ❌ (N errors)
- Lint: ✅ / ⚠️ (N warnings)

### Dependencies

- Added: {list}
- Removed: {list}
- Upgraded: {list}
- Audit: ✅ / ⚠️ N CVEs

### Process

| Check               | Status       | Detail                             |
| ------------------- | ------------ | ---------------------------------- |
| Pre-commit hooks    | ✅ / ❌      | {what runs / "none"}               |
| CI/CD               | ✅ / ❌      | {provider / "none"}                |
| PR / review gate    | ✅ / ❌      | {PR # pattern / direct push}       |
| SDLC artifacts      | ✅ / ⚠️ / ❌ | {present & fresh / stale / absent} |
| Formatter config    | ✅ / ❌      | {tool / "none"}                    |
| Typecheck+Lint+Test | ✅ / ⚠️      | {unified scripts?}                 |
| README / AGENTS.md  | ✅ / ⚠️      | {present / stale / absent}         |

### Token

- M1 review convergence: max {N} rounds ({review name}) — 🟢/🟡/🔴
- M2 stage distribution: design {X}% / review {X}% / implement {X}% (review share {X}% — 🟢/🟡/🔴)
- M3 rework: {X}% rework fraction ({rework}/{total} rounds across {N} reviews) — 🟢/🟡/🔴
- M4 context: p50={N} / p90={N} / max={N} input tokens; cache {ratio}:1 — 🟢/🟡/🔴
- M5 explore/execute: {ratio}:1 (explorer {N} / worker {M} tokens) — 🟢/🟡/🔴
- M6 gate defect-escape: {N} gates scanned, {M} UNDER-POWERED (escape_rate at/above threshold, top: {gate}) — 🟢 all healthy / 🟡 {M} under-powered → feed §2.9 / 🔴 broad under-powering across gates
- [NOTE: M2 skipped if token-stage-ledger.jsonl absent]

Phase 3 — What Went Well?

Identify positive patterns — things to repeat or amplify:

  1. High-quality commits: commits with clear prefixes, atomic scope, good descriptions → name specific examples.
  2. Low-churn modules: files that were changed but had low +/ counts (well-factored, easy to modify).
  3. Tests that caught bugs: if any test was added before the fix commit, that's TDD → highlight it.
  4. Fast turnaround: if any commit → production cycle was unusually fast.
  5. Process safeguards active: pre-commit hooks catching errors before push, CI blocking broken builds, PR review catching design issues early.
  6. Fresh documentation: README and AGENTS.md are up to date and referenceable.
## What Went Well

1. {finding} — {evidence from data} — {why it worked, do again}
2. {finding}
3. {finding}

Phase 4 — What Went Wrong?

Identify problems — focus on patterns in the data, not blame:

Data signal Root cause pattern Example
Revert commits > 0 Bug slipped through review / testing "Revert 'fix auth' — original fix broke login"
High churn in a single file (> 300) Monolithic module, hard to change safely src/handler.ts +400/-350 in one cycle
feat commits without test changes New features landed untested 3 feat commits, 0 test files changed
No conventional commit prefix Low commit discipline, harder to auto-changelog 8 of 12 commits have no prefix
Test suite growing slower Test debt accumulating Source +200 lines, tests +10 lines
Dependency added without audit check Supply chain risk New dep added, audit not run
Typecheck broke mid-cycle No pre-commit / pre-push hooks Type error landed on main, fixed later
No pre-commit hooks Every developer must remember to run checks manually Type errors and lint violations land on main
No CI/CD No automated gate before merge Broken build merged, discovered later
No PR template / direct pushes No structured review process Design flaws not caught until production
Stale SDLC artifacts Process was followed once then abandoned .artifacts/ exists but empty for last 3 cycles (deprecated: check Gitea wiki {slug}/ pages instead)
Multiple formatters / test frameworks Tooling inconsistency slows onboarding Both prettier and biome configured
Review rounds ≥5 Upstream stage quality low — rework deferred to review design converged only at round 5
cache_read/input < 3:1 Context re-read repeatedly — code-graph-first not followed 2.8:1 across design stage
explore/execute < 1:1 Workers doing explorers' job — exploration skipped or under-delegated 0.7:1 — worker tokens exceed explorer
review stage >60% of token spend Over-reviewing — review findings not actionable upstream design 20% / review 65% / implement 15%
rework fraction >30% Review findings not actionable or upstream design unclear 62% rework — 30 of 48 rounds beyond first
retrospective skill modified in cycle range Retrospective reviewing its own modification — potential self-review bias core/skills/retrospective/SKILL.md changed in git diff {range}
## What Went Wrong

1. **{signal}** — {root cause} — {impact: what broke / slowed down}
2. **{signal}** — {root cause} — {impact}
3. **{signal}** — {root cause} — {impact}

Phase 5 — Action Items

For each "what went wrong", generate a concrete, measurable action item. Each item MUST specify:

  • What — the change to make.
  • Where — which template, checklist, SKILL, or project config to modify.
  • Who — which role or agent is responsible.
  • When — effective immediately or next cycle.
## Action Items

| #   | What                                               | Where                                   | Who                | When       |
| --- | -------------------------------------------------- | --------------------------------------- | ------------------ | ---------- |
| 1   | Add pre-commit hook: typecheck + lint on staged    | `.husky/pre-commit`                     | Developer          | immediate  |
| 2   | Require test file changes for every feat commit    | `core/checklists/implementation.md` | Retrospective Lead | next cycle |
| 3   | Add commit message template (conventional commits) | `.gitmessage` or `CONTRIBUTING.md`      | Retrospective Lead | next cycle |

Rules:

  • Maximum 5 action items per retrospective. If you have more, group by root cause and take the top 5.
  • Every action item MUST reference a specific file to modify.
  • Action items that modify SKILLs or templates are applied immediately (the Retrospective Lead can edit <instance-root>/ files).
  • Action items MUST NOT be vague ("try harder", "be more careful").
  • Layering question (injection-budget ruling item 3, [org-internal #3547]): every action item that encodes a lesson as a process constraint MUST answer "which layer carries this lesson?" — options in ascending per-turn cost, pick the cheapest that actually enforces it:
    1. L0 tool-enforced — hook / bash guard / CI validation (zero prompt bytes);
    2. Skill step — inline in the phase skill that executes the work (bytes paid only when that skill is loaded);
    3. L2 on-demand — wiki / rule doc fetched when a task needs it;
    4. L1 per-turn injection — an core/rules/*.md whitelist entry (bytes paid by EVERY role on EVERY turn; item must cite the current corpus bytes vs bun run check:rule-budget cap headroom). Option 4 is default-deny: choosing it requires stating why 13 cannot carry the lesson (2026-08 batch-1 cut builder -41% / explorer -69% per-turn corpus — do not casually re-grow it; the rule-GC report in that same check flags aging L1 rules for L2 retirement).

TRIM PROPOSAL rows — RETIRED ([org-internal #3072] phase 3, 2026-08-21): the gate-trim landing machinery (gate_trim.actionsizing.tiers.{Size}.additional_skip / routes.{Kind}.skip / auto_approve.stages) was removed with the gate_trim: and sizing: blocks — nothing trims gates anymore, so Phase 5 emits NO trim proposals. Gate health findings flow exclusively through §2.8's escape-rate verdict (UNDER-POWERED → §2.9 pre-flight) and ordinary action items. Historical spec: wiki rules/gate-trim (L2).

PRE-FLIGHT PROPOSAL rows (from Phase 2.9 defect-prevention, [org-internal #2599]): format the What cell as Add pre-flight '{id}' to {Kind} ({hits} first-round FAIL/WARN hits, {tickets} tickets — {evidence}) and the Where cell as <instance-root>/workflow-routing.yaml routes.{Kind}.preflight — or, for causes keyed Epic × DAG-route (e.g. REQ × late-discovery, [org-internal #2905] 方案 3), <instance-root>/workflow-routing.yaml dag.route.preflight (consumed by analyze-dag before decomposition). Aging removal rows: Remove pre-flight '{id}' from {Kind} (clean streak {N} ≥ aging threshold).

Same doctrine the retired TRIM proposals used: a PRE-FLIGHT PROPOSAL is a recommendation, not an auto-apply — landing (and removal) happens in Phase 6 only when the action item survives the retrospective's own review. Landed checklists must stay within preflight.max_items entries per route (drop-oldest by added_cycle).


Phase 6 — Apply Improvements

For each action item that modifies a <instance-root>/ or project-config file:

  1. Read the current file.
  2. Apply the change.
  3. Note the change in the retrospective report.
## Applied Improvements

1. Modified `{.file}`: {what was changed} — {commit hash}
2. Modified `{.file}`: {what was changed} — {commit hash}

Phase 7 — Report

Publish the retrospective report as a Gitea wiki page _retrospectives/{cycle-name} via wiki 读写 API(见 TERMINOLOGY. The _retrospectives/ namespace is an intentional cross-cycle, slug-less exception to the {slug}/... artifact-path convention (retrospectives aggregate multiple slugs and outlive any one pipeline run) — analogous to the audit audit/{date}/ date-slug exception documented in the NAM 4.4 checklist item.

# Retrospective: {cycle description}

**Date**: {YYYY-MM-DD}
**Range**: {commit range or time range}
**Commits**: {N}
**Overall**: 🟢 GREEN / 🟡 YELLOW / 🔴 RED

## What Went Well

{list}

## What Went Wrong

{list}

## Action Items

{table}

## Applied Improvements

{list}

References

  • core/checklists/retrospective.md — Retrospective self-check