retrospect-core
Skill2 starsChanged 7 days agoMITView on GitHub
Shared engine for the meta-review organs — orientation pass, NEW/CARRIED/RESOLVED baseline diffing, propose-confirm-commit-with-routing, and review-output-contract report rendering. Library-only — callable by checkpoint (and any future meta-review skill), not user-invoked. There is no /retrospect-core command. Stateless per call except for the report artefacts it persists.
In this repository47 other files it gives its agents.
- AGENTS.mdAGENTS.md
- .github/copilot-instructions.mdCopilot instructions
- autonomizeSkill
- blueprintSkill
- brainstormSkill
- captureSkill
- checkpointSkill
- close-outSkill
- coordinateSkill
- cycleSkill
- deliverSkill
- design-proposalSkill
- discoverSkill
- dispatchSkill
- draft-planSkill
- envisionSkill
- executeSkill
- extract-conventionsSkill
- glossarySkill
- humanizeSkill
- human-viewSkill
- improve-promptSkill
- memory-auditSkill
- new-agentSkill
- new-agents-mdSkill
- new-hookSkill
- new-mcpSkill
- orchestrateSkill
- pr-authorSkill
- prepSkill
- pre-pushSkill
- pr-triageSkill
- recapSkill
- reviewSkill
- rulesSkill
- shortcutsSkill
- specSkill
- systematic-debuggingSkill
- test-driven-developmentSkill
- update-changelogSkill
- update-codemapSkill
- using-git-worktreesSkill
- visualise-codemapSkill
- visualSkill
- work-stateSkill
- wrapSkill
- write-testsSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 1 is distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 63
Since-last-run delta: Read <report_dir>/<scope>/latest.md frontmatter if it exists.
- Very specific: line 83
If no latest.md at baselinePath → Run mode = fresh.
- Very specific: line 106
When a finding needs a memory/proposal body shown inline, call deliver (render_bodies) rather than re-reading and pasting.
- Distinctive: line 122
No silent action — every finding is the user's decision.
- Very specific: line 129
Write the run to <report_dir>/<scope-slug>/, same versioning + atomicity as review §7b:
- Very specific: line 132
If latest.md exists → rename to v<N>.md (highest+1).
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
retrospect-core
The meta-review engine. It is to checkpoint what deliver is to discover/prep/review: one mechanism, its consumers kept single-responsibility without duplicating the engine.
It does not know how to find decision drift or organ overlap — that domain logic lives in the calling skill's passes. retrospect-core owns the four things every meta-review run shares: orient, diff against the prior run, render per the review output contract, and route each confirmed finding to the organ that actually fixes it.
When to run
- A meta-review skill (
checkpoint) invokes one of the functions below programmatically. - Do not respond to user prose triggers. There is no
/retrospect-corecommand and no "when the user says X" branch. It is a format-and-orchestration helper. - Stateless per call, with one exception:
persistwrites a report artefact to disk (the substrate the next run'sdiffreads).
The contract
The caller (checkpoint) owns:
- Which corpus to point at and where its files live.
- The passes — the domain logic that produces findings.
retrospect-core owns:
orient(target)— inventory + since-last-run delta.diff(findings, baselinePath)— NEW/CARRIED/RESOLVED/WONT_FIX tagging.render(report)— the review-output-contract report body.route(finding)— propose-confirm-commit, then hand off to capture / memory-audit / a proposals stub.persist(report, scope)— writelatest.md+v<N>.mdfor the next run's baseline.
A finding passed between caller and engine has this shape:
Finding = {
id: "R<NNN>", // assigned by diff(); provisional in scan order before that
pass: string, // caller's pass label — e.g. "decision-integrity", "responsibility-overlap"
locator: string, // the thing the finding is about: a proposal id, memory path, skill name, file:line
verdict: string, // pass-specific tag — e.g. HOLDS / SUPERSEDED-unmarked / DEAD / OVERLAP
severity: "Critical"|"High"|"Medium"|"Low",
what: string, // one-line, specific
route: "capture"|"memory-audit"|"proposal"|"direct-fix"|"none",
proposed_action: string, // concrete — the capture content, the back-link edit, the proposal stub title
status?: string, // open | applied | skipped | wont_fix:<reason> (set during route())
}route is the load-bearing field: it names which sibling organ fixes this, so the engine never re-implements capture/memory-audit/review. A finding whose route is none is informational (surfaced, not actionable).
Functions
orient(target)
Mirrors review's Phase-1 orientation (§2c), generalised off code and onto whatever corpus the caller names.
Input: target = { kind, roots, report_dir }
kind—"decisions"|"system"|"conformance:<slug>"(reserved — no current consumer; caller-defined; engine treats it as an opaque label for the orientation header and the report path).roots— the directories/files the corpus lives in (caller supplies; e.g. aproposals/directory, the memory tree, the skills tree).report_dir— where this kind's reports persist (e.g..claude/retrospects,.claude/system-reviews).
Steps:
- Inventory. Glob
roots, count by type, note the largest/most-linked nodes. Cheap structural census — not a content read of every file (the passes read content). - Since-last-run delta. Read
<report_dir>/<scope>/latest.mdfrontmatter if it exists; take itsdate. Compute what changed since:- git:
git log --oneline --since=<date>over the relevant repo(s) → commits/ships in the window. - non-git, or files that change outside commits: run review's receipt check,
node <review skill dir>/receipts.mjs check <report_dir>/<scope> --list <roots file list>, and countCHANGED/NEW/GONE. Not mtimes: they lie after restores and cloud sync. No receipt → "first run — full corpus".
- git:
- Emit the orientation block (goes in the report header, before findings):
## Orientation
Corpus: <kind> — <one-line census, e.g. "59 proposals, 38 memory files, 31 skills">
Since last run (<baseline date or "first run">): <N ships / M recaps / K skill changes in window>
Focus hint: <the nodes most likely to harbour drift — e.g. "the longest supersedes chains; skills added since baseline">The focus hint is the meta-review analogue of review's large×high-churn intersection: it points the caller's passes at where drift concentrates (recently-shipped proposals, recently-touched organs, the longest supersedes chains). When the corpus is too small or too new for a meaningful hint, say so explicitly rather than omitting the line.
Orientation is read-only and emits no findings of its own.
diff(findings, baselinePath)
Identical model to review §4b, retargeted at meta-review findings.
- If no
latest.mdatbaselinePath→ Run mode = fresh; assign IDsR001…in caller order; return. - Parse the baseline's findings table to
{id, pass, locator, what, status}. - Match a new finding to a baseline finding when
passis identical and either:locatoris the same node (same proposal id / memory path / skill name), or thewhatstrings are near-identical (concept-level match for a finding whose locator moved). - Tag:
CARRIED— in baseline (open) and in this run; reuse the baseline id.NEW— no baseline match; assign a fresh id continuing above the baseline max.WONT_FIX— baseline-taggedwont_fixand still present; reuse id; suppress from Quick wins; list under "Carried as won't-fix" with the prior reason quoted.RESOLVED— in baseline (open) with no match this run; list under "Resolved since last run" — never silently dropped (surfacing what closed is half the point).
- Malformed baseline → log a one-line header warning, treat as fresh, leave the prior file untouched.
render(report)
Render the report body per the review output contract. The caller supplies findings + the orientation block; the engine produces:
- Header — corpus, files scanned, run mode, baseline.
- Orientation block (from
orient). - Severity × Pass roll-up matrix (the meta-review analogue of review's Severity × Category — rows are the caller's passes).
- Mandatory diagram — try mermaid, fall back to ASCII, only emit a one-line N/A with a why when the run genuinely has no structure to draw. Good defaults: a
supersedes-chain graph for decision-integrity findings; an organ-dependency / overlap graph for organ-surface findings. - Per-node findings, grouped by
locator, severity-sorted within each. - Findings table — uncapped within the run ceiling, one row per finding with
Statuson repeat runs. - Quick wins — Low-effort × Medium+-severity; explicit "None" line when empty.
- "Things that look bad but are actually fine" — structurally required, ≥2 near-misses with reasoning, or an explicit one-line justification when the scope is too narrow. (For meta-review this is high-value: it stops the organ from flagging a deliberate supersedes chain or an intentionally-thin organ as drift.)
When a finding needs a memory/proposal body shown inline, call deliver (render_bodies) rather than re-reading and pasting. The contract wins on any divergence — this section consumes it, does not redefine it.
route(finding) — propose-confirm-commit with routing
Iterate findings in report order. For each, present it and offer:
- Apply → execute by
route:capture→ invoke capture withproposed_actionas candidate content. Capture classifies kind/scope/relevance and runs its own confirm. (Used for: uncaptured lessons, sharpened/added rules.)memory-audit→ the fix is a mechanical memory edit (e.g. add a missingsuperseded_byback-link, fix a broken relation). Apply it as a direct Edit framed as the memory-audit fix, or hand off to memory-audit--checkfor the relevant dimension when the run surfaced several. retrospect-core never decides memory validity itself beyond the caller's verdict — it routes the integrity fix.proposal→ write a stub under the project's proposal convention (numbered slot, backlog row, or issue — whatever the project uses), titled fromproposed_action, body = the finding + why. Never auto-fills a full proposal; it captures the candidate so it isn't lost. Confirm the slot number with the user first.direct-fix→ a self-evident edit the organ owns outright (e.g. an index line, a stale path in a coverage map). Edit, confirm.
- Skip → discard for this run (ephemeral; does not become next run's
wont_fix). - Edit → take the user's revised action; apply; loop.
- View detail → show the underlying node (proposal/memory/skill) via deliver or a direct read; re-prompt.
- Won't fix (reason) → durable one-line reason; tag
wont_fix:<reason>; carries forward next run, suppressed from Quick wins.
No silent action — every finding is the user's decision. Two caller-selectable flows, both user-driven (neither auto-applies):
- Per-finding loop (default —
review,memory-audit): iterate findings in report order, confirm each (the loop above). Each decision is isolated. - Batch-select (
checkpoint): afterrenderpresents the whole batch, the caller collects the user's selected finding ids in one prompt, then callsrouteover only that subset. Fewer conversational round-trips (the efficiency conversations axis); still no silent apply — the user picked the set. Unselected findings persist for the next run, not lost.
persist(report, scope)
Write the run to <report_dir>/<scope-slug>/, same versioning + atomicity as review §7b:
- Slug from the caller's scope (
decisions,system,<feature-slug>for conformance). - If
latest.mdexists → rename tov<N>.md(highest+1); write the new run as bothv<N+1>.mdandlatest.md; setsupersedes: v<N>.mdin the new frontmatter. - Atomic order: write
v<N+1>.md, rename oldlatest.md→v<N>.md, copyv<N+1>.md→latest.md. On failure leave the tree as-is and report in the run summary; never partially overwrite. - Frontmatter carries
date,kind,scope_slug,run_mode,baseline,findings_total, per-severity counts, and per-findingStatusin the table (the next run'sdiffreads these). - Then stamp the receipt over the files the passes read:
node <review skill dir>/receipts.mjs stamp <report_dir>/<scope-slug> --list <list>.reviewowns the script and its rules.
The artefact is committable — diffing v3.md↔v4.md shows which decisions went stale, which organs got consolidated, what reopened.
What retrospect-core does NOT do
- Does not produce findings. The passes (caller-owned) do. The engine orients, diffs, renders, routes, persists.
- Does not fix anything itself beyond
direct-fixindex/path edits. Lessons → capture; integrity fixes → memory-audit; system changes → proposals. It routes; siblings fix. - Does not auto-fire and has no command. Library-only, like deliver.
- Does not re-read or re-filter what the caller passed — findings are taken as the caller produced them (the engine only tags them via
diff). - Does not redefine the output contract. It consumes the review output contract; on divergence the contract wins.
- Does not span projects in one call. One corpus, one report dir, per invocation.
Relationship to other organs
- deliver — called to render memory/proposal bodies inside reports. Same library-only posture.
- review — same orient/diff/persist machinery, here generalised off code; review keeps its own copy inlined.
- capture / memory-audit — the two routing targets for lessons and memory-integrity fixes respectively.
- checkpoint — the consumer. It owns corpus + passes (see its corpus-passes.md); it delegates the spine here.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

