39 KiB
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. |
|
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.mdis 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:
- If a release was just done: use
git log <last-tag>..<new-tag>. - If no tag exists: prompt the user for a time range or revision range
(e.g.
HEAD~20..HEAD, or--since="last work cycle"). - 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
- Run the test suite: confirm pass/fail count and duration.
- Check if any test files changed during the cycle:
git diff --name-only {range} | grep -E 'test|spec|__tests__' - 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 zeropackages/*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. - Check for skipped/flaky tests if the framework reports them.
2.4 Build health
- Run
bun typecheck(or project equivalent). Note first-time errors. - Run
bun oxlint --deny-warnings(repo root;bun lintis the package-script alias). Note any first-time warnings. - If the project has CI, check the latest run status.
2.5 Dependency health
- Run
bun audit(or equivalent). Flag any new HIGH/CRITICAL CVEs. - 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.
-
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?)
- Does the project have pre-commit hooks? (Check
-
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).
- Does CI exist? (Check
-
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].
- Does the project have a review template or guideline? (Check
-
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].
- Use
-
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.jsonscripts.) - Are there multiple competing tools for the same concern? (e.g. both prettier AND biome, both jest AND vitest.)
- Does the project have a unified formatter config? (
-
Documentation health:
- Does
README.mdinclude setup, build, and test instructions? - Does
AGENTS.mdor<instance-root>/AGENTS.mdexist? - Are there any outdated docs? (Check for files referencing removed commands or directories.)
- Does
2.7 Token telemetry
Collect LLM token-consumption signals to assess workflow quality. Five metrics: M1 from an inline check; M2–M5 from the token-telemetry probe.
-
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.- 🟢 1–2 / 🟡 3–4 / 🔴 ≥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.tsIt 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 thehistory[]field (legacy aliasrounds[]) andcurrent_round) with the legacy.artifacts/**/reviews/*/status.jsontree fallback, plus the committed archive bundles<runs-root>/archive/{slug}.jsonfor closed runs — and prints M2–M5. -
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.tsplugin, which hookstool.execute.afteron theskilltool — 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% / 🟡 35–60% / 🔴 >60%.
-
60% →
[SIGNAL: review stage >60% of token spend — over-reviewing, review findings not actionable upstream].
- Ledger-gated. If the plugin was not active during the cycle the
ledger is absent and the probe prints
-
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 aliasrounds[], andcurrent_round; skips_archive/) with the legacy.artifacts/**/reviews/*/status.jsontree 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 documentedreviews/{stage}/round{N}/layout inindex.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% / 🟡 15–30% / 🔴 >30%.
-
30% →
[SIGNAL: rework fraction >30% — review findings not actionable or upstream design unclear].
-
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 / 🟡 3–10: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.
-
M5 — Explore/execute ratio. Token spend by agent type (
data.agentper message). A low ratio means workers are doing explorers' job — context-gathering that should be delegated.- 🟢 > 2:1 / 🟡 1–2: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/Bugticket 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.mdPattern 8), read viaoctopus review statusCLI or commit-status inspection. Final reports at{slug}/reviews/{stage}/final/reportrecord round count and highest severity. - Downstream (a): verify reports
{slug}/05-verify-iteration-{N}for the same slug. - Downstream (b):
工单 API(见 TERMINOLOGY)list(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 工件追踪表) orCloses #Nin the PR body.
Procedure:
- Enumerate closed tickets in the cycle with any review run; resolve slugs.
- Per gate run: classify clean / not-clean; for clean runs, search both downstream sources for an escape.
- Tally per
gate_id:clean_runs,escapes,escape_rate. - 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 events — node_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:
- 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. - Tally per route-class —
Bug,Feature-DAG,Epic-DAG-route,Task-DAG(Kind/Feature routes to the DAG pipeline since [org-internal #3061] Phase 2 / TD-388 —Feature-legacysurvives 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 carryingSize/*(spec-06), andKind/Bugcarries no ladder). First-round hit count and distinct-ticket count per cause per class. - A cause is a pre-flight candidate when ALL hold (thresholds from
workflow-routing.yamlpreflight— do NOT restate values here):- hit count ≥
preflight.min_sample - distinct tickets ≥
preflight.consecutive_recurA qualifyingEpic × DAG-routecause (e.g.REQ × late-discovery) lands on<instance-root>/workflow-routing.yamldag.route.preflight— NOTroutes.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 readsdag.route.preflightbefore decomposition.
- hit count ≥
- Aging: for causes ALREADY landed in
routes.{Kind}.preflightordag.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, D1–D4 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:
- Round-cap distribution (per stage): read
{slug}/reviews/*/final/reportheaders (**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 withConverged: false). - 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). - 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:
- High-quality commits: commits with clear prefixes, atomic scope, good descriptions → name specific examples.
- Low-churn modules: files that were changed but had low +/− counts (well-factored, easy to modify).
- Tests that caught bugs: if any test was added before the fix commit, that's TDD → highlight it.
- Fast turnaround: if any commit → production cycle was unusually fast.
- Process safeguards active: pre-commit hooks catching errors before push, CI blocking broken builds, PR review catching design issues early.
- 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:
- L0 tool-enforced — hook / bash guard / CI validation (zero prompt bytes);
- Skill step — inline in the phase skill that executes the work (bytes paid only when that skill is loaded);
- L2 on-demand — wiki / rule doc fetched when a task needs it;
- L1 per-turn injection — an
core/rules/*.mdwhitelist entry (bytes paid by EVERY role on EVERY turn; item must cite the current corpus bytes vsbun run check:rule-budgetcap headroom). Option 4 is default-deny: choosing it requires stating why 1–3 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.action →
sizing.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:
- Read the current file.
- Apply the change.
- 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