Audit archived plans across twenty-four retrospective checks — execution-manifest correctness, quality-verification findings, metrics anomalies, cross-plan recurring patterns, token-efficiency trend, scope-estimate accuracy, track-selection-accuracy (actual planning track vs counterfactual correct track), PR-merge velocity, task-count efficiency, global-log analysis, token-economics, quality-chain, sequence-and-build-minimality, input-integrity corpus completeness, task-graph redundancy, architecture-lookup-ratio (information-lookup vs build-lookup), preference-pattern-detector (recurring user gate-dispositions → architecture hints), dispatch-topology (leaf/dispatch-topology invariant), finalize-flow-conformance (post-#849 deterministic ci_verify mechanics), merge-window-accounting (widened merge-mutex admission window), lane-lever-effectiveness (checkpoint measurement arm — per-scope-class token spend vs armed targets + lane-lever engagement), exploration-share (measured share of tool-call spend that went to exploration rather than to work), billing-composition (re-derived billing-formula and payload-byte composition, reconciled against the dispatch-boundary ledger, every figure carrying its own population), and cross-check-synthesis facet-completeness — file lessons through the three-gate policy, and dormate reviewed plans
Resources
2Install
npx skillscat add cuioss/plan-marshall/audit-archived-plan-retrospectives Install via the SkillsCat registry.
Audit Archived Plan Retrospectives (project-local)
Twenty-four-check retrospective auditor over the archived-plan corpus. The skill is
the LLM-driven orchestration narrative; scripts/audit.py is the deterministic
computation core. The orchestrator selects which checks to run, surfaces each
check's script-computed TOON verbatim, drives lesson filing through the
three-gate lesson-creation-policy.md sequence, and runs the interactive
dormation step that relocates reviewed plans to .plan/temp/dormated-plans/.
The skill is project-local because it operates on.plan/local/archived-plans/ — a directory that only exists in this
meta-project. Consumer projects of plan-marshall have no equivalent corpus.
Hybrid design: script computes, LLM orchestrates
scripts/audit.py performs all deterministic per-plan and cross-plan
computation and emits each check's rows as bespoke TOON. SKILL.md (this body)
is the LLM half: it chooses the checks, reads the emitted rows, decides whether
a surfaced signal warrants a lesson, and confirms the destructive dormation
move via AskUserQuestion. The boundary is strict — the script computes and
emits; the LLM interprets, files lessons, and confirms destructive moves. The
script never mutates a plan artifact except the explicitly-confirmed dormation
move.
Per extension-api/standards/dispatch-granularity.md Heuristic 1, every check's
core computation is a deterministic predicate over file-derived inputs, so it
stays inside the script rather than spawning a subagent. The slash command is the
LLM-friendly invocation of that script plus the orchestration this body
describes — no subagent is spawned.
Enforcement
Execution mode: Select the checks to run, invoke the audit script for each
selected check, and surface its TOON report verbatim; do not paraphrase rule
names, anomaly classes, or verdicts that the script did not emit.
Prohibited actions:
- Do NOT mutate any plan artifact other than the explicitly-confirmed dormation
move. Every check is read-only against.plan/local/archived-plans/and.plan/local/plans/. - Do NOT re-derive any check's computation inline in the chat; if a check's
logic changes, editscripts/audit.pyand re-run. - Do NOT fall back to interpreting
solution_outline.mdprose when the
structured inputs (references.json,status.json::metadata,metrics.toon,execution.toon,tasks/TASK-*.json,artifacts/findings/*.jsonl) are present — prose interpretation is
non-deterministic and was the source of contradictory verdicts in earlier
ad-hoc audits. - Do NOT run the dormation move without an explicit user confirmation obtained
viaAskUserQuestion; the script's move function refuses to run unless the
orchestrator passes the confirmed flag. - Do NOT file a lesson without first running the three-gate policy
(lesson-creation-policy.md) — dedup, active-plan check, then create. - Do NOT spot-check, skim, or sample a subset of check blocks and generalize a
verdict to the rest. EVERY emitted check block MUST be processed against itschecks/{name}.mdsub-document. - Do NOT conclude "all healthy" / "no findings" / "all sensible" unless that
conclusion is backed by a per-check, per-row adjudication with cited evidence.
A blanket dismissal not grounded in per-row evidence is a contract violation. - Do NOT drop a candidate signal as "already covered" / "already filed" without
first VERIFYING that claim against the lessons corpus and the archived-plan
corpus (the matching lesson ID or covering active-plan ID must be named).
Assumption is not verification.
Constraints:
- The script is invoked exactly as written in the workflow steps — no
PYTHONPATH override, no inlined Python, nofind/grepsubstitutes for the
script's own filesystem walk. - When
--plan-idnarrows the scan, the same TOON shape is emitted (single
row per check) so downstream tooling can consume both forms uniformly. - When
--check {name}narrows to one check, only that check's TOON block is
emitted.
Auditor persona
This audit is the first consumer of the auditor persona. Load it as the
evaluation identity for the retrospective sweep:
Skill: plan-marshall:persona-auditorpersona-auditor is a mode: knowledge persona shell that composes other
personas as evaluation lenses; loading it via this Skill: directive is the
documented composition consumption, not an executable-workflow change. The
tester and reviewer lenses are active; the security lens is still a shell until
workstream 05 lands.
Parameters
| Parameter | Required | Description |
|---|---|---|
--plan-dir PATH |
optional | Override the default .plan/local/archived-plans root. Useful when auditing a vendored snapshot. |
--plan-id ID |
optional | Restrict the scan to one archived plan (its directory basename). |
--include-active |
optional | Additionally scan .plan/local/plans/ so in-flight plans are reported alongside archived ones. Active plans without a manifest are reported as incomplete, not drift. |
--check NAME |
optional | Run a single check instead of all. Valid names: execution-context-manifest, quality-verification-report, metrics, recurring-pattern-detector, token-efficiency-trend, scope-estimate-accuracy, track-selection-accuracy, pr-merge-velocity, task-count-efficiency, global-log-analysis, token-economics, quality-chain, sequence-and-build-minimality, input-integrity, task-graph-redundancy, architecture-lookup-ratio, preference-pattern-detector, dispatch-topology, finalize-flow-conformance, merge-window-accounting, lane-lever-effectiveness, exploration-share, billing-composition, cross-check-synthesis. Default: run every check. When --check cross-check-synthesis is selected, the script still computes the upstream checks it consumes (without emitting their blocks) so the synthesis can fire. |
--dormate ID [ID ...] --confirmed |
optional | Relocate one or more archived plans to .plan/temp/dormated-plans/{plan_id}/. Accepts an explicit list of plan IDs; duplicate IDs are deduplicated silently. The whole batch is all-or-nothing — a single grammar violation, missing source, or pre-existing destination refuses the entire batch with nothing moved. Inert (refused, exit 0) without --confirmed. The interactive confirmation is owned by the LLM body (Step 5), never delegated to the script. |
--dormate-all --confirmed |
optional | Relocate EVERY archived plan under .plan/local/archived-plans/ to .plan/temp/dormated-plans/ in one call. Same all-or-nothing posture as --dormate. Inert (refused, exit 0) without --confirmed. The body MUST surface the full would-move plan list before confirming (Step 5). |
--dormate-global-logs --confirmed |
optional | Relocate COMPLETE past-date global logs ({prefix}-YYYY-MM-DD.log) from .plan/local/logs/ to .plan/temp/dormated-plans/global-logs/. Today's still-active log is never moved. Inert (refused, exit 0) without --confirmed; on a destination-name clash the whole move refuses (status: error) rather than overwriting. The interactive confirmation is owned by the LLM body (Step 5), never delegated to the script. |
Repo-root resolution
The script resolves repo_root by walking up from the current working directory
(the working directory itself included) to the nearest ancestor containing a.plan/local directory, falling back to the working directory when no ancestor
qualifies. --plan-dir is joined against that resolved root and keeps its
existing corpus-scan-root meaning. The persisted report under.plan/local/audit-reports/ therefore lands in the project regardless of which
directory the auditor was invoked from.
Shipping-predicate corpus partition
The delivery-cost checks — the eight whose numbers are cost-per-delivery
ratios — run over the SHIPPING partition of the corpus rather than every scanned
plan. A plan that consumed budget and delivered nothing would otherwise dilute
every one of their aggregates.
- The decision is derived from delivery evidence, never from a recorded
reason string: a plan ships when it carries a PR record OR a real footprint. archived_reasonis the exclusion LABEL, not the decision input. It rides
the read-out so an exclusion is legible; a plan carrying no reason at all is
still excluded, labelledunrecorded.- The exclusion is reported separately from the examined count. Each
partitioned block carriesplans_excluded_non_shipping(a number distinct from
its examined/scanned count) andexcluded_non_shipping_plan_ids(each entry{plan_id}:{archived_reason or unrecorded}), so no row is ever silently
dropped.
Membership is stated once, in scripts/audit.py's DELIVERY_COST_CHECKS; the
complement FULL_CORPUS_CHECKS is derived from it, so every declared check lands
in exactly one partition and a newly-added check defaults to the unpartitioned
side. input-integrity in particular keeps seeing every scanned plan — it is the
no-false-healthy foundation and a partition would blind it. Read the partition's
per-check consequences in the relevant checks/{name}.md; the predicate's
implementation is not restated here.
Available checks
Each check is documented in a self-contained sub-document under checks/. The
sub-document records what scripts/audit.py computes for that check, the inputs
it reads, the emitted columns, and how the orchestrator interprets and acts on
the rows.
| Check | Sub-document | Surfaces |
|---|---|---|
| Execution-manifest correctness | `checks/execution-context-manifest.md` | Persisted execution.toon vs the re-derived seven-row rule; the name_drift signal. |
| Quality-verification report | `checks/quality-verification-report.md` | Findings present, proposed lessons, and whether each was already filed. |
| Metrics anomalies | `checks/metrics.md` | Disproportionate token usage, incomplete recordings, impossible values, optimization signals. |
| Recurring-pattern detector | `checks/recurring-pattern-detector.md` | Cross-plan finding signatures appearing in N≥3 plans as systemic signals. |
| Token-efficiency trend | `checks/token-efficiency-trend.md` | Chronological tokens-per-phase regression across the corpus. Runs over the shipping partition; non-shipping plans are counted in plans_excluded_non_shipping. |
| Scope-estimate accuracy | `checks/scope-estimate-accuracy.md` | Declared scope_estimate vs actual affected/modified file count. Runs over the shipping partition; non-shipping plans are counted in plans_excluded_non_shipping. |
| Track-selection accuracy | `checks/track-selection-accuracy.md` | Actual planning track (planning_lane/track) vs the counterfactual track reconstructed from realized signals via the imported evaluate_signals_pure; OVER-TRACKED / UNDER-TRACKED / correct verdict. |
| PR-merge velocity | `checks/pr-merge-velocity.md` | PR open-to-merge duration; long-review-cycle flagging. Runs over the shipping partition; non-shipping plans are counted in plans_excluded_non_shipping. |
| Task-count efficiency | `checks/task-count-efficiency.md` | Under-decomposed / over-decomposed task-count outliers. Runs over the shipping partition; non-shipping plans are counted in plans_excluded_non_shipping. |
| Global-log analysis | `checks/global-log-analysis.md` | Cross-plan .plan/local/logs/ parse: error/warning lines, slow calls, high-frequency callers, impossible/hang durations, and test-fixture leaks — correlated to plan execution windows. |
| Token economics | `checks/token-economics.md` | Cross-plan per-phase token shares + efficiency ratios joined to scope/change_type, with corpus-derived (never hard-coded) anti-pattern flags: fixed-overhead floor, planning≫execute, outline/refine/finalize-heavy, big-spend-tiny-footprint, long sessions, execute-metrics blindness. Runs over the shipping partition; non-shipping plans are counted in plans_excluded_non_shipping. |
| Quality chain | `checks/quality-chain.md` | Cross-plan findings classified by mechanism (build / self-review / auto-review / human-review) × resolution (direct_fix / loop_back / rerun_flake / accepted / suppressed / pending / lesson); per-plan matrix + corpus totals, chain anti-pattern flags (build_pending_pile, auto_review_only, review_body_duplicate, no_qgate6), and shift-left tiering (Tier 1-4) of auto-review findings against the ext-self-review surfacer remit. Per-finding rows, walked step-by-step. |
| Sequence and build minimality | `checks/sequence-and-build-minimality.md` | Cross-plan call-sequence reconstruction from logs/script-execution.log, bucketed into phases by the logs/work.log [DISPATCH] role=phase-N timeline; per-build duration classification (minimal <120s / scoped / heavy >400s) and work.log build-verb mining (verify / scoped-vs-all module-tests / quality-gate / coverage / compile), with redundancy / non-minimality flags (build_churn, non_minimal_build, docs_only_build, ci_rerun, phase_reentry, arch_over_resolution, consecutive_dup). Carries three structural caveats (finalize-fold conflation, verify-count-upper-bound vs heavy-duration-floor, consecutive_dup over-count) documented in the sub-doc. Runs over the shipping partition; non-shipping plans are counted in plans_excluded_non_shipping. |
| Input integrity | `checks/input-integrity.md` | Per-plan input presence/health (execution.toon / metrics.toon / references.json / tasks/ / artifacts/findings/ / logs/script-execution.log) plus three input-health flags (metrics_blind, incomplete_lifecycle, missing_dispatch_markers) and a corpus data_confidence summary (fully-recorded / partial / blind). The no-false-healthy foundation: every other check MUST annotate rows derived from a metrics_blind plan as "floor, not truth", and no check may claim "all healthy" over blind-input plans. |
| Task-graph redundancy | `checks/task-graph-redundancy.md` | Per-plan task-graph adjacency over tasks/TASK-*.json: multi_task_file (a file edited by ≥2 tasks — the primary duplicate-task signal), dup_substep (same (target, intent) in >1 task), in_task_build (a heavy build/verify baked into a task's verification that phase-5/6 already runs), verif_task_fanout (>1 module_testing/verification task), and deliverable_fanout (a deliverable whose task count exceeds the per-run corpus outlier threshold max(3, median*2)). All five sub-checks emit genuine. |
| Architecture-lookup-ratio | `checks/architecture-lookup-ratio.md` | Per-plan ratio of information lookup (architecture orientation/navigation: find/which-module/files/module/info/overview) vs build lookup (resolve/derive-verification), both from logs/script-execution.log. Corpus-derived build_dominated_lookup flag (build_lookups ≥ corpus-median AND info/build ratio ≤ corpus-p25, with a degenerate-corpus guard) surfaces plans whose architecture use is build-resolution-heavy with little navigation — a PROMPT (not a verdict) to check whether navigation bypassed the structured-query lever (Read/raw-bash instead of architecture find). A low ratio may simply mean no navigation was needed (recipe/surgical/issue-fix). Discovery verbs (discover/enrich/crawl-*) are counted separately and excluded from the ratio. |
| Preference-pattern detector | `checks/preference-pattern-detector.md` | Cross-plan recurring user gate-dispositions: (module, finding-class, disposition) tuples (suppressed/accepted/taken_into_account) appearing in N≥THRESHOLDS["preference_disposition_occurrences"] plans, surfaced as candidate preferences. The threshold gate is script-owned; Step 4c routes every surfaced row to architecture enrich per the shared disposition-to-hint-routing.md contract (generalize, do not log raw dispositions). |
| Dispatch topology | `checks/dispatch-topology.md` | Per-plan verification of the roadmap's leaf/dispatch-topology invariant (subagents are LEAVES — only the orchestrator dispatches further subagents). Scans each plan's logs/work.log [DISPATCH] (caller) target=… lines and flags any whose (bundle:skill) caller is NOT an allowed dispatcher (plan-marshall:plan-marshall or a plan-marshall:phase-N-… phase context) — a leaf that spawned a subagent. The allowlist catches a newly-added leaf by default. |
| Finalize-flow conformance | `checks/finalize-flow-conformance.md` | Per-plan verification of the post-#849/#850 finalize mechanics (deterministic ci_verify gate, adaptive ci-wait ratchet). Reads the phase_6.steps roster + artifacts/ci-runs/*/manifest.toon and flags missing_ci_verify (a PR was created with no ci-verify gate — pre-#849 shape), ci_wait_timeout (a recorded wait_outcome: deadline_exceeded), and ci_unresolved (the latest run's final_status never reached success). |
| Merge-window accounting | `checks/merge-window-accounting.md` | Cross-plan accounting of the #849 widened merge-mutex + FIFO admission-queue window. Buckets the global [LOCK] (merge:*) lifecycle lines by lock_id (= plan_id) and reports per-plan acquire/release/blocked/reclaim counts + max FIFO waiting_count; flags merge_contention when a plan waited behind the queue front. Accounts for the merge-window cost the widened mutex trades for fair ordering / parallelism. |
| Lane-lever effectiveness | `checks/lane-lever-effectiveness.md` | The checkpoint measurement arm of the token-optimization roadmap. Cross-plan measure of whether the cost-reducing lane levers (recipe auto-routing, the light planning lane, the minimal execution posture, the #854 surgical-fix micro-lane) are engaged, and scores each plan's summed total_tokens against its scope class's armed checkpoint target (surgical ≤1.2M / single_module ≤1.5M / multi_module ≤2.5M): per-plan within/over/unclassed/no_metrics checkpoint verdict (checkpoint_over is the genuine overspend signal), corpus lever-engagement counts (recipe routes / light-lane fires / minimal-posture choices), the posture_not_taken lever-adoption gap on surgical plans, and an estimated_avoided_tokens scope-gated subtraction (an upper bound). Runs over the shipping partition; non-shipping plans are counted in plans_excluded_non_shipping. |
| Exploration share | `checks/exploration-share.md` | Cross-plan measure of how much of each plan's tool-call spend went to exploration (locating/inspecting existing state) rather than to producing or mutating it — the measured counterpart to architecture-lookup-ratio, which counts calls to the navigation lever while this counts the navigation cost, whichever tool paid it. Sums the ten per-phase exploration counters from metrics.toon and reports each plan's payload-byte share (headline) and turn share (companion) over the productive exploration + work + execute denominator, with corpus-derived (never hard-coded) cut-points behind a degenerate-corpus spread guard: exploration_byte_heavy, exploration_turn_heavy, many_cheap_probes (the groping-around signature architecture-lookup-ratio cannot see), unclassified_tools. Absent is not zero: a plan carrying no counters is EXCLUDED from the corpus and named in excluded_plan_ids, never counted as zero exploration. Also runs over the shipping partition, whose separate exclusion is counted in plans_excluded_non_shipping — a DIFFERENT exclusion from the absent-counter one above. |
| Billing composition | `checks/billing-composition.md` | Cross-plan re-derivation of the corpus billing composition — the billing-formula reconstruction input + output + round(0.1 × cache_read) + round(1.25 × cache_creation) with its cache_read / cache_creation / output shares — and the payload-byte composition (exploration / work / execute / orchestration shares over ALL five buckets, with the unclassified residual emitted as an explicit byte count rather than folded into a named share). Not a re-read of the phase rows: each phase is reconciled against the plan's work/metrics-dispatch-boundaries-{phase}.toon ledger under the same same-population max(row, boundary) rule cmd_generate applies (NOT a sum — the accumulator and the ledger record the same leaves), and the two named under-counts are reported SEPARATELY — unabsorbed_loop_back (a close_count > 1 row whose figures are sums across closes) and omitted_row (a canonical phase absent from metrics.toon, i.e. a member of the persisted unrecorded_phases). Every emitted figure carries its OWN population and floor_population (the two families are independent, so a plan may contribute to one and not the other), and a figure any metrics_blind / partial / omitted-row plan contributed to is labelled floor — a lower bound, never a truth. Absent is not zero: a plan measuring neither family is EXCLUDED and named in excluded_plan_ids. Measurement only — no saving is quantified or projected. Also runs over the shipping partition, whose separate exclusion is counted in plans_excluded_non_shipping. |
| Cross-check synthesis | `checks/cross-check-synthesis.md` | The facet-completeness critic (runs LAST). Joins the OTHER checks' retained structured results into ten cross-check couplings single rows miss: trend_empty_untrustworthy (empty token-trend regression over blind-execute plans), churn_explains_walltime (non_minimal_build/build_churn corroborated by a plan's build wall-clock total_build_seconds upper-half — build redundancy wastes wall-clock, not tokens), qgate_gap_chain (no_qgate6/auto_review_only correlating with ci_rerun / finalize_heavy), argparse_signature_cluster (recurring-pattern argparse signatures correlating with global-log errors and unfiled quality-verification signatures — collapsed to ONE candidate), scope_underestimate_cost (scope under-estimation correlating with high tokens/file or a task-count outlier), redundant_build_churn (task-graph-redundancy in_task_build correlating with sequence build_churn/phase_reentry), dispatch_topology_reentry (a leaf-emitted dispatch corroborated by sequence phase_reentry), finalize_gate_gap_ci_rerun (missing/failed #849 ci_verify gate correlating with sequence ci_rerun), merge_window_ci_rerun (merge-queue contention correlating with ci_rerun / finalize_heavy), and surgical_overpay (lane-lever-effectiveness checkpoint_over correlating with token-economics big_spend_tiny_footprint — a lane-lever miss). Each coupling carries its qualifying caveat and the D1 severity column; the block operationalizes the Step-4b completeness gate. |
Check era model (fixed_since + retire-on-quiet)
Every check carries an era stamp and participates in a retire-on-quiet
proposal loop. Both are script-computed in scripts/audit.py from the singleCHECK_ERA table and the THRESHOLDS["retire_on_quiet_runs"] tunable — the LLM
half only reads and acts on the surfaced signals, it never recomputes them.
fixed_since(era stamp). Each check's block header carries afixed_since: {stamp}line naming the roadmap-era boundary as of which the
check's computation is known accurate (e.g.#849,#852,#854,plan-10).
The stamps live in ONE centralCHECK_ERAdict inscripts/audit.pyand are
surfaced deterministically on every emitted block — no check inline-duplicates
its own boundary. Read the stamp as "this check reflects mechanics as of era
X"; when the roadmap advances past X for a check whose semantics that advance
touched, the check is a candidate for a semantic refresh.retire-on-quiet (removal PROPOSAL, never a removal). A check whose
genuine_signal_counthas been zero across at leastTHRESHOLDS["retire_on_quiet_runs"](default 3) consecutive recorded runs
surfaces a removal proposal in the dedicatedretire-on-quietblock. Each
proposal row names the check, its quiet-run streak, itsfixed_sincestamp,
and proposal text. The mechanism is proposal-only — the script never
removes a check, and the block is emitted on every full sweep (an empty rows
table shows the mechanism ran but proposed nothing). The per-run genuine counts
are persisted asgenuine__{check}keys in each report'ssummary_metrics
header (under.plan/local/audit-reports/), so the streak is read back across
runs; a report predating the era model contributes nogenuine__keys and
therefore breaks a streak rather than silently extending it. Treat a surfaced
proposal as a prompt to confirm the check is genuinely obsolete (versus quiet
because the corpus simply had no offending plans) before any future plan
removes it.
Lifecycle-footer convention for future roadmap plans. The not-yet-landed
roadmap plans (plan-5 … plan-8) are not yet era boundaries. When one of them
ships and changes a check's semantics, add or bump that check's CHECK_ERA
entry to the new boundary in scripts/audit.py (never in a per-check emit
function) as a one-line change, and re-run the audit — the new stamp then rides
every emitted block for that check automatically. This keeps CHECK_ERA the
single, greppable ledger of which roadmap era each check is aligned to.
Usage Examples
/audit-archived-plan-retrospectivesRuns every check over every archived plan and emits one TOON block per check.
/audit-archived-plan-retrospectives --plan-id 2026-05-26-fix-1-init-phase-boundary-bootstrap-bugSingle-plan audit across all checks; useful when a retrospective wants a focused
read-out.
/audit-archived-plan-retrospectives --check metricsRuns only the metrics-anomaly check across the corpus.
/audit-archived-plan-retrospectives --include-activeAdds in-flight plans to the scan. In-flight plans that have not yet reachedphase-4-plan Step 8b show up under the incomplete bucket for checks that
depend on execution.toon.
Workflow
Step 0: Gather + expand the coverage cell
This skill implements the coverage-gathering contract. At invocation, gather the (thoroughness, scope) cell from the user via the contract's canonical AskUserQuestion shape — a scope question (change-set/artifact/component/module/overall + an explicit inherit (default — behave exactly as today)) and a thoroughness question (T1…T5 + inherit). The coupling constraint (reject thoroughness ≥ T4 ∧ scope < component) constrains the offered scope options when the user picks T4/T5.
Validate + expand the gathered pair in one call — coverage expand validates the literal pair (re-prompt on coverage_coupling_violation; do NOT re-implement the coupling math) AND returns the operational instruction block:
python3 .plan/execute-script.py plan-marshall:manage-config:manage-config coverage expand --thoroughness {T} --scope {S}This is a single-invocation audit skill that runs outside a plan, so hold the gathered identifier + expanded instruction in-context for the invocation (the in-context path of the contract's persistence mechanism — no status.json write). Consume the expanded instruction (NOT the raw cell) in Steps 1 and 4b below. When the user selects inherit/inherit (the default), the expanded instruction is behavior-preserving and Steps 1–4b run exactly as before (all 24 checks, full corpus, today's Step-4b gate).
See persona-plan-marshall-agent/standards/thoroughness.md for the ladders and coverage-gathering-contract.md for the gather shape and the cell→instruction table — restate neither here.
Step 1: Select the checks to run, governed by the coverage cell
The expanded instruction's scope rung sets the corpus radius: change-set/artifact → a single plan (--plan-id); component/module → a domain/scope-filtered subset of the corpus; overall → the full archived-plan corpus (today's default). Its thoroughness rung gates check breadth: T1 → cheap deterministic checks across a representative sample; T2 → all 24 checks once; T3 → all 24 plus the cross-check-synthesis coupling join; T4/T5 → all 24 plus the Step-4b loop-until-dry / what-did-I-miss adversarial completeness pass.
When the user supplies an explicit --check {name}, that narrows to one check regardless of the thoroughness rung. The check names are listed in the Available checks table above; each maps to a checks/{name}.md sub-document and a --check {name} value the script accepts. The inherit/inherit expanded instruction reproduces today's behavior: all checks, the full corpus.
Step 2: Run the audit script for the selected checks
python3 .claude/skills/audit-archived-plan-retrospectives/scripts/audit.py [--plan-dir PATH] [--plan-id ID] [--include-active] [--check NAME]The script walks .plan/local/archived-plans/{plan_id}/ (and optionally.plan/local/plans/), reads the structured inputs each check requires, computes
the per-plan and cross-plan signals, and emits one bespoke-TOON block per check.
Surface each emitted block verbatim and interpret its rows using the
corresponding checks/{name}.md sub-document.
Step 3: Interpret each check's rows
The orchestrator MUST process EVERY emitted check block against its matchingchecks/{name}.md sub-document — no block may be skipped, sampled, or
generalized from a peer. The sub-documents are the single source of truth for
what each column means and which row states warrant action; this body does not
restate them.
For EVERY row that is a potential signal — drift, a populated name_drift,impossible_value, a scope mismatch, unfiled proposed lessons, a systemic
recurring pattern, a PR-velocity flag, a task-count outlier, a global-log
signal (error/non-INFO line, slow call, impossible-duration call, high-frequency
caller, or fixture leak), a token-economics anti-pattern flag
(fixed_overhead_floor, planning_gt_exec, outline_heavy / refine_heavy /finalize_heavy, big_spend_tiny_footprint, long_session,exec_metrics_blind), a quality-chain signal (a chain anti-pattern flag —build_pending_pile, auto_review_only, review_body_duplicate, no_qgate6 —
or a genuine per-finding row, especially a Tier-1 auto-review finding), or a
sequence-and-build-minimality flag (build_churn, non_minimal_build,docs_only_build, ci_rerun, phase_reentry, arch_over_resolution,consecutive_dup — read each against the three structural caveats inchecks/sequence-and-build-minimality.md), an input-integrity flag
(metrics_blind, incomplete_lifecycle, missing_dispatch_markers, or adata_confidence: blind plan), a task-graph-redundancy flag (multi_task_file,dup_substep, in_task_build, verif_task_fanout, deliverable_fanout — read
each against checks/task-graph-redundancy.md), an architecture-lookup-ratio flag
(build_dominated_lookup — read against checks/architecture-lookup-ratio.md: a
PROMPT, not a verdict; a low ratio may simply mean no navigation was needed), a
dispatch-topology violation (leaf_dispatch > 0 — a leaf spawned a subagent, read
against checks/dispatch-topology.md), a finalize-flow-conformance flag
(missing_ci_verify, ci_wait_timeout, ci_unresolved — read againstchecks/finalize-flow-conformance.md), a merge-window-accounting flag
(merge_contention — read against checks/merge-window-accounting.md), a
lane-lever-effectiveness flag (checkpoint_over — a plan overspent its armed
checkpoint target, read against checks/lane-lever-effectiveness.md), an
exploration-share flag (exploration_byte_heavy, exploration_turn_heavy,many_cheap_probes, unclassified_tools — read againstchecks/exploration-share.md: a prompt, not a verdict, and cross-read with the
plan's architecture-lookup-ratio row; plans named in excluded_plan_ids
carry no measurement and MUST NOT be read as zero exploration), a
billing-composition under-count or floor (unabsorbed_loop_back, omitted_row,
a non-empty reconciled_phases, or a floor label — read againstchecks/billing-composition.md: a floor-labelled figure is a lower bound that
MUST be quoted as "at least X over its own population", never as a
measurement, and the two under-counts MUST stay separately named), or a
cross-check-synthesis coupling that FIRED (trend_empty_untrustworthy, churn_explains_walltime,qgate_gap_chain, argparse_signature_cluster, scope_underestimate_cost,redundant_build_churn, dispatch_topology_reentry, finalize_gate_gap_ci_rerun,merge_window_ci_rerun, surgical_overpay — read each against its qualifying caveat inchecks/cross-check-synthesis.md) —
explicitly state BOTH:
- the verdict — action (file a lesson / fold into an active plan / surface
for human review) or no-action; and - the cited evidence or cross-check that justifies the verdict — the
specific sub-doc rule, theseveritycolumn value, the corpus match, or the
structured input that grounds the decision.
A row may be dismissed as informational/expected ONLY with a cited reason (e.g.
"informational per checks/metrics.md § How the orchestrator interprets the
rows" or "severity: informational per the manifest check"). A bare "looks
fine", a silent skip, or a generalized "the rest are the same" is a contract
violation. The execution-context-manifest check's severity column andgenuine_signal_count summary are the precision aids for this adjudication:informational rows still require a one-line cited dismissal; genuine rows
require a full verdict-plus-evidence treatment.
Standing rule: the input-integrity verdict is the no-false-healthy floor
The input-integrity check is the deterministic foundation every other
check's adjudication is built on. Process it FIRST among the per-plan reads, and
honour its verdict for the rest of the audit:
- A check may not claim "all healthy" over blind-input plans. Whenever the
input-integrityblock reportsdata_confidence_blind > 0, NO check — and no
corpus-level summary — may conclude "all healthy" / "no findings" for the
corpus. The blind plans' downstream rows are floors: absence of a signal there
is absence of recorded data, not absence of a problem. The honest conclusion
reads "no findings among fully-recorded plans; the N blind plans
(blind_plan_ids) are floored and cannot be cleared". - Annotate floored rows "floor, not truth". Any row another check derives
from a planinput-integritymarksmetrics_blind(especially ablind-bucket
plan) MUST be annotated "floor, not truth" in the adjudication — a
token-economics, token-trend, or metrics number computed over a blind execute
is an under-count, not a measurement. - Name the blind plans when dismissing. When dismissing a blind plan's peer
row as "no signal", citeinput-integrity'sblind_plan_idsas the reason the
row cannot be cleared; never generalize it into a healthy verdict.
See `checks/input-integrity.md` §
"The cross-check obligation" for the full statement of this rule.
Step 4: File lessons through the three-gate policy
Two check classes emit candidate lesson signatures: the quality-verification
report's unfiled proposed lessons and the recurring-pattern detector's systemic
signals at the 3+ threshold. For each candidate signature, run the canonical
three-gate sequence from plan-marshall:manage-lessons'slesson-creation-policy.md:
- Gate 1 — dedup: search the lessons corpus for an existing lesson covering
the same signature. Onmerge_into/already_closed, extend the existing
lesson instead of filing a new one. - Gate 2 — active-plan check: if an active plan already covers the fix, fold
the signal into that plan rather than filing a lesson. - Gate 3 — create: only when Gates 1 and 2 both clear, allocate a lesson
file viamanage-lessons addand write the body to the returnedpath.
Any candidate signature the orchestrator is about to drop on a Gate-1 (dedup) or
Gate-2 (active-plan / "already covered") basis MUST have that basis VERIFIED
against the corpus before the signal is dropped: name the actual matching lesson
ID (Gate 1) or the active plan ID that covers it (Gate 2), and record that
verification in the adjudication. A dismissal without a named, verified
reference is a contract violation.
The quality-verification check already cross-checks each proposed lesson against
the lessons corpus and the archived-plan corpus, so a candidate it marks as
"already filed" or "covered by archived plan {id}" MUST NOT be re-filed — that
marking is itself a cited verification and satisfies the obligation above.
Source-keyed argparse-rejection lessons: the per-plan retrospective'sscript-failure-analysis aspect (see plan-marshall:plan-retrospective aspect 8)
classifies each non-zero-exit script call by stderr signature
(invalid choice: → invented subcommand, the following arguments are required:
→ missing required flag, unrecognized arguments: → invented flag) and keys its
proposed lessons to the source notation that argparse rejected — the{bundle}:{skill}:{script} {subcommand} whose surface drifted — not to the
consuming plan that happened to trip it. For archived-plan audits this changes
how the recurring-pattern detector's signals are filed: when the same source
notation surfaces across N≥3 archived plans' argparse-rejection findings, file (or,
on Gate-1 dedup, extend) a single source-keyed lesson naming the exact
subcommand/flag drift, rather than one lesson per consuming plan. A source-keyed
lesson already covering that notation satisfies Gate 1 for every later plan that
trips the same rejection — so the dedup check MUST search the corpus by the source
notation, not by the consuming plan ID.
Token-economics flags are already covered by the shipped token-economics
check: the token-economics check's corpus-derived anti-pattern taxonomy IS
the operationalized form of the original one-off token deep-dive — the check is
its own coverage source. A flagged token-economics row is therefore COVERED on a
Gate-1 dedup basis against the check's taxonomy and MUST NOT be re-filed. The
file-worthy signal from this check is a corpus drift (e.g. the execute-share
falling further, a fresh fixed-overhead recurrence on a plan created after a
remediation shipped, or a previously-unflagged anti-pattern becoming systemic);
a genuine drift warrants filing a fresh lesson through the three-gate policy
rather than being folded silently into the taxonomy. Seechecks/token-economics.md § "Adjudication against the shipped token-economics
check".
Step 4c: Route preference-pattern-detector rows to architecture hints
The preference-pattern-detector check surfaces recurring user gate-dispositions
as (module, finding-class, disposition) candidate rows. Because the check
THRESHOLD-gates every surfaced row via its THRESHOLDS script constant, this
step routes EVERY surfaced row — there is no further gating in the body.
For each surfaced row, generalize the disposition recurrence into a hint string
and route it to architecture enrich, following the shared contract in
`phase-6-finalize/standards/disposition-to-hint-routing.md`
for the generalization rule, the routing targets
(architecture enrich best-practice for module-attributed rows,architecture enrich insight --module default for cross-cutting rows), and the
"generalize, do not log raw dispositions" privacy invariant. This step MUST NOT
restate those rules inline — the shared contract is the single source of truth.
This is the auditor's richer corpus-wide preference-learning path; the
consumer-available default:finalize-step-preference-emitter is the cheap
per-plan path that shares the same contract and the same architecture enrich
sink.
Step 4b: Review-completeness gate
Before reaching Step 5 (Interactive dormation), the orchestrator MUST satisfy
this completeness gate. Dormation is BLOCKED until every item below is true and
demonstrable from the adjudication produced in Steps 3–4.
Coverage-cell depth (from Step 0's expanded instruction): the gate's rigor is
indexed by the gathered thoroughness rung. inherit/T1/T2/T3 run the gate
exactly as the checkboxes below describe (today's behavior). T4/T5 add an
adversarial completeness pass on top: after the checkboxes pass once, run a
what-did-I-miss critic and a loop-until-dry sweep — re-examine the surfaced rows
asking which facet, plan, or coupling was assumed-not-examined, and repeat until a
pass surfaces no further gap. This is the contract's depth dimension applied to
the audit's completeness gate; it widens nothing the surfacer did not surface.
The cross-check-synthesis check is the deterministic surface that
operationalizes this gate: it joins the other checks' results into the six
cross-check couplings (see `checks/cross-check-synthesis.md`)
and stamps each fired coupling severity: genuine. A fired coupling is therefore
a genuine-signal row this gate's first checkbox accounts for, and itstrend_empty_untrustworthy coupling is the structural enforcement of the
blind-plan checkbox across the trend facet — a premature "no findings" conclusion
cannot pass the gate while any coupling fired unresolved.
- Every emitted check block was examined against its
checks/{name}.md
sub-document — none skipped or sampled. - Every genuine-signal row (
severity: genuine,impossible_value, realdrift, unresolved-rolename_drift, scope mismatch, unfiled lesson,
systemic pattern, PR-velocity flag, task-count outlier, global-log
error/slow/impossible/high-frequency/fixture-leak signal, token-economics
anti-pattern flag, quality-chain anti-pattern flag,genuine
quality-chain per-finding row, or sequence-and-build-minimality flag —build_churn,non_minimal_build,docs_only_build,ci_rerun,phase_reentry,arch_over_resolution,consecutive_dup, or an
input-integrity flag —metrics_blind,incomplete_lifecycle,missing_dispatch_markers, a task-graph-redundancy flag —multi_task_file,dup_substep,in_task_build,verif_task_fanout,deliverable_fanout, an architecture-lookup-ratio flag —build_dominated_lookup, a dispatch-topology violation (leaf_dispatch > 0),
a finalize-flow-conformance flag —missing_ci_verify,ci_wait_timeout,ci_unresolved, a merge-window-accounting flag —merge_contention, a
lane-lever-effectiveness flag —checkpoint_over, an exploration-share
flag —exploration_byte_heavy,exploration_turn_heavy,many_cheap_probes,unclassified_tools, a billing-composition
under-count or floor —unabsorbed_loop_back,omitted_row, a non-emptyreconciled_phases, or afloorlabel, or a FIRED
cross-check-synthesis coupling —trend_empty_untrustworthy,churn_explains_walltime,qgate_gap_chain,argparse_signature_cluster,scope_underestimate_cost,redundant_build_churn,dispatch_topology_reentry,finalize_gate_gap_ci_rerun,merge_window_ci_rerun,surgical_overpay)
was adjudicated with a stated verdict AND cited evidence. - Every cross-check-synthesis coupling that
fired(severity: genuine) was
resolved by adjudicating its COUPLED rows together — not in isolation —
against the coupling's qualifying caveat inchecks/cross-check-synthesis.md; in particular,trend_empty_untrustworthywas honoured as a floor (no "no regression"
healthy claim over blind-execute plans) andargparse_signature_cluster
was collapsed to ONE source-keyed candidate. - If
input-integrityreporteddata_confidence_blind > 0, no check and no
corpus summary claimed "all healthy" / "no findings" over the corpus; every
blind plan's peer rows were annotated "floor, not truth" and the blind
plans were named (blind_plan_ids) rather than cleared. - Every
billing-compositionfigure carried into the adjudication was quoted
WITH its ownpopulationandlabel— never with another figure's
population and never bare — and everyfloor-labelled figure was stated as
a lower bound ("at least X") rather than as a measurement. - For the quality-chain check specifically, EVERY per-finding row was walked
step-by-step — never sampled — perchecks/quality-chain.md§
"Methodology constraint: walk every finding, never sample". - Every dismissal of a potential-signal row carries a cited justification —
no bare "looks fine" and no silent skip. - Every "already covered" / dedup / active-plan drop was corpus-verified with
the matching lesson ID or covering active-plan ID named.
The gate is framed so a reviewer CANNOT truthfully reach "no findings" via a
quick look: the per-row adjudication and the named corpus verifications are the
evidence the gate checks for. If any item is unmet, return to Step 3/Step 4 and
complete the adjudication before proceeding.
Step 5: Interactive dormation
After the audit has been reviewed, offer to dormate each reviewed plan —
relocating its directory from .plan/local/archived-plans/{plan_id}/ to.plan/temp/dormated-plans/{plan_id}/. The move is destructive, so confirmation
is mandatory:
For the plans the user wants to dormate, raise an
AskUserQuestion
confirming the move (the confirmation is owned here, in the LLM body — never
delegated to the script).Only on explicit confirmation, invoke the script's confirmed dormation move.
The body MAY pass multiple plan IDs to a single--dormate ... --confirmed
call — the batch is deduplicated silently and moved all-or-nothing (a single
clash refuses the whole batch with nothing moved):python3 .claude/skills/audit-archived-plan-retrospectives/scripts/audit.py --dormate {plan_id} [{plan_id} ...] --confirmedTo relocate the entire reviewed corpus in one call, use
--dormate-all. The
body MUST surface the full would-move plan list in theAskUserQuestion
before confirming, so the user sees exactly which plans the whole-corpus move
relocates:python3 .claude/skills/audit-archived-plan-retrospectives/scripts/audit.py --dormate-all --confirmedWithout
--confirmed, the script's move function is inert and refuses to
relocate anything.
After offering per-plan dormation, also offer to dormate the COMPLETE past-date
global logs — relocating each {prefix}-YYYY-MM-DD.log from .plan/local/logs/
to .plan/temp/dormated-plans/global-logs/. This move is destructive in the same
way, so confirmation is mandatory and owned here:
Determine the complete date-files that would move. Today's still-active log
(the{prefix}-YYYY-MM-DD.logwhose date equals today) is NEVER moved, so it
MUST be excluded from the set surfaced to the user. Raise anAskUserQuestion
that lists exactly the past-date{prefix}-YYYY-MM-DD.logfiles (today's
active log excluded) and confirms the move (the confirmation is owned here, in
the LLM body — never delegated to the script).Only on explicit confirmation, invoke the script's confirmed global-log
dormation move:python3 .claude/skills/audit-archived-plan-retrospectives/scripts/audit.py --dormate-global-logs --confirmedThe script re-applies the same past-date-only / never-move-today's-active-log
rule, refuses on any destination-name clash (status: error), and emits amoved[N]{date_file}TOON listing the relocated date files. Without--confirmed, the move function is inert and refuses to relocate anything.
Critical Rules
- The script is the single source of truth for every check's computed rows. Do
not paraphrase or re-implement any check in chat. execution.toon,metrics.toon, and the other structured inputs are parsed
by small inline readers insidescripts/audit.py(the project'stoon_parserlives behind the executor PYTHONPATH which this skill does not
load). If a manifest or metrics schema changes, update the reader inscripts/audit.pyrather than calling out to amanage-*script — that would
be a dispatch-shaped solution for deterministic work.- The audit is read-only against all plan artifacts except the
explicitly-confirmed dormation move. - Lesson filing always passes through the three-gate policy — never file
directly from a surfaced signal.
Related
plan-marshall:manage-execution-manifest— the composer audited by the
execution-context-manifest check.plan-marshall:manage-lessons— the lessons corpus and the three-gatelesson-creation-policy.mdthat Step 4 follows.plan-marshall:plan-retrospective— consumesexecution.toon,metrics.toon,
and the compose decision-log lines; audit failures here predict stale
retrospective signals.extension-api/standards/dispatch-granularity.md— the heuristic basis for
keeping this skill script-shaped rather than dispatch-shaped.