Skip to content

Commit ed52e19

Browse files
docs(skills): add the epic-closeout skill (#170)
## What this is Promotes the orchestrator epic close-out **sequence** out of the one epic it was written in and into a project-level, user-invocable skill at `.claude/skills/epic-closeout/SKILL.md`, taking a **`slug`**. **One file added, nothing else touched.** Footprint is `.claude/skills/epic-closeout/SKILL.md` alone. ### Why a skill rather than a document per epic The source is `.plan/local/orchestrator/api-sheriff-roadmap/epic-closeout.md`, which lives in **the first epic that will close**. Two live epics (`api-sheriff-0-2-0`, `api-sheriff-0-3-0`) would otherwise depend on a mechanism document inside a closed-and-archived tree, and each would carry its own copy of the sequence. ### The split it preserves | | Lives in | Example | |---|---|---| | **Mechanism** | the skill | *how* a lesson is consumed, *how* a bundle round is delivered | | **State** | each epic's ledger | which round is next and how many rows it carries; which defects owe verification | Same split as `status.json` (authority) vs. a generated START-HERE block (rendering). The skill names no epic, no round number, no defect id and no lesson id. ### The rules carried across 1. **Consume means archive, never delete** — `archive/lessons-consumed/{lesson-id}.md`, a fourth sibling to `bundle-handoffs/`, `plans-shipped/`, `plans-struck/`; **persist-then-remove**, so an interrupted pass loses at most the lesson in flight and a re-run is a no-op. 2. **A discard is archived too**, with its rationale. 3. **Archive the corrected text of a superseded lesson, not the original.** 4. **The lessons corpus is global to the repository, not per-epic** — hence the convention must be identical in every epic. 5. **An assertion of re-homing is not a re-homing** — verify it in the target tree, with the structural cause (the write boundary) stated so it reads as a mechanism, not sloppiness. 6. **Bundle hand-off rules** — the index is the durable dedup base checked before compiling; rows flip `UNSENT` → sent **in the same action as the send**; round numbering **restarts at 1 per epic**, with the epic's name distinguishing carriers. 7. **A cover note about a class beats N disconnected rows.** Plus two things the skill states plainly: it **disposes and never calls `close`**, and it is **not runnable by accident** (explicit slug, no plan in flight, operator asked, state document read first). ### One correction to the source `epic-closeout.md` shows the removal as `manage-lessons remove --lesson-id {id}`. That invocation is rejected: `--reason` and `--coverage-verdict` are **required**, and `completely_covered` additionally requires `--covering-clause` and `--covering-input`. The skill carries the full form. ## Gate **Documentation-only, gate not run.** Per `CLAUDE.md` § Pre-Commit Process as it now stands (`ae52984`), the exemption is by file class and mixed commits are explicitly not exempt. This commit adds exactly one file under `.claude/**` — no `*.java`, no `pom.xml`, no `src/**`, no workflow, no Dockerfile — so it cannot change build output. ## Concurrency with PLAN-48 PLAN-48 owns `.claude/skills/release/SKILL.md`, `.github/workflows/release.yml`, `doc/development/release-process.adoc` and `CLAUDE.md`. **None of them is touched here** — the only reference to PLAN-48's surface is a *See also* line pointing at the release skill as a shape precedent. Disjoint footprints. --- ## Requested follow-up — reduce `epic-closeout.md` to state only **Outside my write boundary** (`.plan/local/orchestrator/**` is the orchestrator's tree), so this is reported rather than applied. This is the same boundary that produces rule 5 above; it bites here too. **Target:** `.plan/local/orchestrator/api-sheriff-roadmap/epic-closeout.md`, rewritten to *this epic's state*, opening with a pointer to `.claude/skills/epic-closeout/SKILL.md` for the how. **Keep (state):** - **Bundle round** — round 7 delivered (`archive/bundle-handoffs/plan-marshall-bundle-findings-round-7.md`); round 8 is next, compiled 2026-08-03 and **UNSENT**. **The row count in the document is stale: it says 26, and `bundle-handoff-index.md` now carries 27 `(round 8 item N)` rows.** Either restate it as 27 or, better, drop the number and say *read the count from the index* — a second copy of a count is a second thing to go stale. - Rows 21–26 (now –27) added 2026-08-05 have not been deduped against rounds 1–7; specifically 21 vs 16, and 24 as a *recurrence* of the standing `--delete-branch` clause. - **Ledger sweep candidates** — (30) empty deep-lane component-assessment sink, a two-plan recurrence (PLAN-42, PLAN-45); (31) `q_gate_validation: once` vs `plan_without_asking: true`; (25) empty `documentation.skills_by_profile.module_testing`; (16) no sanctioned execution path for the main-branch `deploy-snapshot` check; (49) `ci pr merge` reports `merged: true` for an enqueue. - The **named class instance**: rows 21, 23, 25 and the `[OK]` self-review are all *a mechanism reporting a clean result it never computed*. - **Lessons** — the corpus stands at **19 active**; note `2026-08-05-10-001` was corrected on 2026-08-05 after its root cause was refuted, so its **corrected** text is what gets archived. - **Defects owing re-homing verification** — **(4), (10b), (21), (43)**, each asserting *"RE-HOMED … TRACK IT THERE, NOT HERE"*; (37) is the discharged precedent (asserted-but-unwritten for a day, enacted 2026-08-05). - **Memory** — 21 files; `coderabbit-oss-rate-limit-blocks-merge` corrected 2026-08-05, its "budget re-triggers" advice wrong. - **The 0.1.0 pre-cut checklist** to implant into `api-sheriff-0-2-0` (re-run Trivy immediately before dispatch; rebuild the scan target from the tree under test; bump `.github/project.yml` `current-version`; assert GHCR `visibility == "public"` via `gh api`; never `--delete-branch`). **State, because it is the record of one cut** — the skill's step 8 states only the rule that such knowledge is harvested into the successor. - **Sequencing** — runs after PLAN-48 lands and is reconciled, before `close`; item 5 (memory) may run at any point. **Drop (now in the skill):** - § *Why this is not a plan* — the Ledger Write-Boundary argument, verbatim in the skill. - The four-destinations table and the *removal is the last step, never the disposition* trap. - § *The consume mechanism — archive, never delete*, in full: the archive path, persist-then-remove and its rationale, discards-archived-with-rationale, corrected-text-not-original. - The bundle-index rules: durable dedup base, check-before-compiling, flip-in-the-same-action, the permanent pre-2026-07-29 dedup gap **as a rule** (the epic keeps the concrete gap as state). - The *cover note about a class* rule (the epic keeps this epic's instance). - The *assertion of re-homing is not a re-homing* rule and its structural cause (the epic keeps the four entries owing verification). - Items **6 and 7** almost entirely — implanting the mechanism and adding a close-out document to each successor, including per-epic round-1 numbering and the corpus-is-global argument. - Item **8**'s framing; only the 0.1.0 checklist content stays. Net: `epic-closeout.md` goes from ~179 lines of mixed mechanism and state to roughly a third of that, all state, headed by one pointer to the skill. ## Not done, deliberately **The close-out itself has not been run.** Authoring the mechanism was the job; the first execution is the orchestrator's, after PLAN-48 lands. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_016zTCGAUEzEbQowHT6yfMjP <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a guided epic closeout workflow for formally dispositioning completed work without closing the epic. * Supports bundle handoffs, lesson and knowledge consolidation, defect and watch-item re-homing, successor setup, and completion reporting. * Includes validation steps and safety safeguards to help ensure no follow-up items or learnings are lost. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: cuioss oliver <23139298+cuioss@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent ae52984 commit ed52e19

1 file changed

Lines changed: 350 additions & 0 deletions

File tree

Lines changed: 350 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,350 @@
1+
---
2+
name: epic-closeout
3+
description: Run an orchestrator epic's close-out — everything that must be dispositioned before the epic is frozen. Takes the epic's slug. Delivers the final bundle hand-off round, sweeps the ledgers for unfiled plan-marshall material, consumes the global lessons corpus into the archive (archive, never delete), distributes open defects to successor epics with every re-homing verified rather than asserted, consolidates memory, and implants the mechanism into the successors. It disposes only — it NEVER calls `close`.
4+
user-invocable: true
5+
allowed-tools: Bash, Read, Edit, Write, Glob, Grep
6+
---
7+
8+
# Epic close-out — API Sheriff orchestrator
9+
10+
Runs the close-out of **one orchestrator epic**, named by its **`slug`**. The close-out is everything
11+
that must be dispositioned *before* the epic is frozen: the last bundle hand-off round, the ledger
12+
sweep, the lessons corpus, the open-defect distribution, memory, and the implant into the successors.
13+
14+
Throughout, the epic under close-out is:
15+
16+
```text
17+
EPIC=.plan/local/orchestrator/<slug>
18+
```
19+
20+
That tree is the **default** root, and steps 1, 2 and 4 write only there. **Steps 3, 5, 6, 7 and 8
21+
deliberately reach beyond it** — into repository source, project-scoped memory, and the successor
22+
epics' trees — and each says so where it does. Read the write scope from the step, not from this
23+
line.
24+
25+
**Nothing in this file names a particular epic, round number, defect id or lesson id** — see
26+
*Mechanism vs state* below; that is the design, not an omission.
27+
28+
---
29+
30+
## THIS SKILL DOES NOT CLOSE THE EPIC
31+
32+
**It disposes. Closing is a separate, deliberate act.** Nothing here calls `close`, archives the
33+
epic, or flips its status to a terminal phase. When every step below is done, **report and stop**;
34+
the operator decides whether the epic is closed, exactly as the release cut is a separate decision
35+
from the plan that prepared it.
36+
37+
A close-out that ran and a close that happened must never look alike.
38+
39+
## Not runnable by accident
40+
41+
Five preconditions, all of them before any write:
42+
43+
1. **The slug is given explicitly.** Never infer it from "the current epic", the most recently
44+
touched tree, or the only one that looks active. `ls .plan/local/orchestrator/` and confirm the
45+
slug exists as a directory.
46+
2. **The epic's plans have all landed and been reconciled.** A close-out that runs while a plan is
47+
still in flight disposes of defects the plan is about to change, and sweeps a ledger that is
48+
about to gain rows. Read `$EPIC/status.json` and `$EPIC/epic.md`; check `$EPIC/plans/` against
49+
`$EPIC/archive/plans-shipped/` and `$EPIC/archive/plans-struck/`, and `$EPIC/inbox/` for an
50+
undrained OUTBOX. **Any plan not yet in a terminal state stops the close-out.**
51+
3. **The operator has asked for it, on this epic.** Say which slug you are about to close out and
52+
what the sweep will touch — the successor epics' trees included — before touching anything.
53+
4. **The epic's close-out state document exists and has been read** — conventionally
54+
`$EPIC/epic-closeout.md`. That is where this epic's *state* lives: which round is next, which
55+
defects owe verification, how many lessons are in the corpus. This skill supplies the *how*; that
56+
document supplies the *what*, and it is authoritative over any recollection.
57+
58+
**It is required, not optional.** Without it the counts and the outstanding items have no
59+
authoritative source and every step below runs on recollection. If it is absent — a successor
60+
that never received one under step 7, or an epic predating the convention — **stop and compile it
61+
first**, from the epic's own artifacts and nothing else: the next round and its row count from
62+
`$EPIC/bundle-handoff-index.md`, the open defects and watches from the anchor, the corpus count
63+
from `manage-lessons list`. Then have the operator confirm it before step 1 writes anything.
64+
5. **Only one close-out runs at a time.** Step 3 drains a corpus that is global to the repository, so
65+
two concurrent close-outs can each read the same lesson as unconsumed and dispose of it twice.
66+
Nothing locks it — the ordering in step 3 makes a *re-run* safe, not a concurrent run.
67+
68+
## Mechanism vs state — the whole design
69+
70+
| | Lives in | Example |
71+
|---|---|---|
72+
| **Mechanism** | this skill | *how* a lesson is consumed; *how* a bundle round is delivered |
73+
| **State** | the epic's ledger | which round is next and how many rows it carries; which defects owe re-homing verification |
74+
75+
The same split as `status.json` (authority) versus a generated START-HERE block (rendering). **A
76+
step in this file that hardcodes an epic-specific fact has broken it** — if you find yourself
77+
wanting to record "round 8" or "defect (43)" here, that belongs in `$EPIC/epic-closeout.md`.
78+
79+
The reason this is a skill rather than a document copied into each epic: the close-out sequence was
80+
first written inside the first epic that would close, and every later epic would then depend on a
81+
mechanism document living in a closed-and-archived tree.
82+
83+
## Why this is orchestrator work, not a plan-marshall plan
84+
85+
The **Ledger Write-Boundary** forbids an executing plan from creating or editing *any* file under
86+
`.plan/local/orchestrator/{epic}/`; its only channels back are its PR and its `inbox/` OUTBOX. Steps
87+
1, 2 and 4 write this epic's ledger; steps 6, 7 and 8 write the successors' ledgers; step 5 is
88+
outside the repository entirely. A plan-marshall call is **structurally incapable** of performing
89+
any of them.
90+
91+
**The one genuine plan-shaped slice** is step 3's tail: where a consumed lesson must land in
92+
*repository source* — documentation, an ADR, `CLAUDE.md`. That is spawned **from** the triage as its
93+
own plan or direct brief; it never contains the triage.
94+
95+
> **This same boundary is why step 4 exists at all.** An orchestrator can record the *intent* to
96+
> re-home a defect but cannot write it into another epic's tree, so the intent depends on a later
97+
> session to enact it. Keep that in view: it is not a quirk of one epic, it is the mechanism's shape.
98+
99+
---
100+
101+
## Step 1 — Deliver the final bundle hand-off round
102+
103+
Compile and deliver the outstanding round of plan-marshall bundle findings for this epic.
104+
105+
- **Source of truth is `$EPIC/bundle-handoff-index.md`.** It is the **durable dedup base** — one
106+
line per delivered finding, kept forever. **Check it before compiling, never re-derive from
107+
memory.** The carrier itself is disposable; the index is not.
108+
- **Flip `UNSENT` → sent in the SAME action as the send**, and relocate the carrier into
109+
`$EPIC/archive/bundle-handoffs/` in that same action. Nothing does this automatically. An index
110+
that is accurate right up until the moment it matters is worse than no index, because it is
111+
believed — a round has already been compiled twice because the flip was deferred.
112+
113+
**This is a rule about not deferring the flip; it is not a claim of atomicity.** The send is
114+
external and the flip is a file edit, so an interruption between them can still leave a delivered
115+
round with unflipped rows, or the reverse. What catches that is the next round's dedup pass
116+
against this index — which is why the pass is mandatory before compiling, and why a suspected
117+
interruption is reconciled against the delivered carriers rather than assumed either way.
118+
- **Round numbering restarts at 1 per epic**, and the epic's name distinguishes the carriers
119+
(`V02-round-1 item 3`, `V03-round-1 item 2`). A sequence shared across epics makes a carrier's
120+
provenance unreadable.
121+
- **State permanent gaps explicitly, so they are not mistaken for completeness.** Where an early
122+
round's contents were not recorded, any finding older than that round needs manual dedup against
123+
the delivered carriers, and the carrier must say so.
124+
- **Rows added since the last delivery have never been through a dedup pass** — run one rather than
125+
assuming. Watch particularly for a row that is a *recurrence* of a standing clause rather than a
126+
new finding; those belong in the carrier as a recurrence, which is a different and more useful
127+
claim.
128+
- **Prefer a cover note about a class over N disconnected rows.** When several findings share a
129+
shape — the recurring example being *a mechanism reporting a clean result it never actually
130+
computed* — one named class is worth more to the bundle than five rows that each look local.
131+
132+
## Step 2 — Sweep the ledgers for unfiled plan-marshall material
133+
134+
Read, in full:
135+
136+
- the epic anchor's **Open Defects** and **Watches** (`$EPIC/status.json` `resume_anchor`, rendered
137+
into `$EPIC/epic.md`)
138+
- every `$EPIC/landings/PLAN-*.md`
139+
- `$EPIC/logs/decision.log`
140+
141+
Confirm that each defect attributable to a **plan-marshall mechanism** (as opposed to this
142+
repository's own code) reached `bundle-handoff-index.md`. Anything that did not is filed now.
143+
144+
- **A defect seen in two or more plans is a recurrence, and says so in the carrier.** A two-plan
145+
recurrence is far stronger evidence of a mechanism defect than two separate one-off rows.
146+
- The class cover-note rule from step 1 applies here too, and this sweep is usually where the class
147+
becomes visible.
148+
149+
## Step 3 — Consume the lessons corpus — the goal is zero
150+
151+
The corpus is **global to the repository, not per-epic**: `.plan/local/lessons-learned/`, listed with
152+
153+
```bash
154+
python3 .plan/execute-script.py plan-marshall:manage-lessons:manage-lessons list
155+
```
156+
157+
**Every epic's close-out drains whatever has accumulated since the last one.** That is precisely why
158+
the archive convention below must be identical in every epic — otherwise a lesson consumed by one
159+
epic is preserved and one consumed by another vanishes, and which lessons keep an audit record
160+
becomes arbitrary.
161+
162+
Every lesson gets **exactly one recorded disposition**. Four destinations:
163+
164+
| Destination | For |
165+
|---|---|
166+
| **Bundle index** | plan-marshall mechanism defects |
167+
| **Successor epic ledger** | standing rules that govern how the *next epic* is run |
168+
| **Repository source** (docs / ADR / `CLAUDE.md`) | rules that govern how the *code* is built — **this is the plan-shaped slice**, spawned as its own plan |
169+
| **Discard** | superseded, already covered, or scoped to work that has shipped |
170+
171+
> **The trap, stated because the word "consume" invites it.** A lesson that is a standing rule and
172+
> is simply *deleted* is lost. Consumption means it lands somewhere that is actually read.
173+
> **Removal is the last step of a disposition, never the disposition itself.**
174+
175+
### The consume mechanism — archive, never delete
176+
177+
A consumed lesson is **moved into the epic's archive**, so the corpus empties while the audit record
178+
survives:
179+
180+
```text
181+
$EPIC/archive/lessons-consumed/{lesson-id}.md
182+
```
183+
184+
A fourth sibling alongside `archive/bundle-handoffs/`, `archive/plans-shipped/` and
185+
`archive/plans-struck/`, following the same principle those three already embody — **this tree
186+
relocates, it does not destroy.**
187+
188+
**Per lesson, in this order — persist, then remove:**
189+
190+
1. **Record the disposition at its destination**: the bundle index row, the successor anchor clause,
191+
the doc/ADR change, or an explicit discard rationale.
192+
2. **Write the lesson body verbatim** to `$EPIC/archive/lessons-consumed/{lesson-id}.md`, with a
193+
header naming the disposition and where it went:
194+
195+
```markdown
196+
> **Consumed <YYYY-MM-DD> — disposition: <bundle index | successor ledger | repository source | discard>**
197+
> Landed at: <the index row, anchor clause, file+section, or the discard rationale>
198+
```
199+
3. **Only then** remove it from the corpus:
200+
201+
```bash
202+
python3 .plan/execute-script.py plan-marshall:manage-lessons:manage-lessons remove \
203+
--lesson-id <id> \
204+
--reason "<what happened to it>" \
205+
--coverage-verdict <completely_covered|redundant|superseded|obsolete> \
206+
--covering-clause "<required for completely_covered>" \
207+
--covering-input "<required for completely_covered>"
208+
```
209+
210+
`--reason` and `--coverage-verdict` are **required**; an unstated verdict is a rejection, not an
211+
assumption. `--force` skips the interactive confirmation — use it only in an unattended pass, and
212+
never as a way past a prompt you have not read.
213+
214+
**Persist-then-remove, never the reverse** — the same discipline the inbox drain uses, and for the
215+
same reason: an interrupted pass loses at most the one lesson in flight, and a re-run over an
216+
already-consumed lesson is a no-op rather than a second disposition. **A lesson removed before its
217+
destination write is simply gone.**
218+
219+
**A discard is archived too, with its rationale.** "Superseded" and "already covered" are
220+
dispositions *with reasons*, and the reason is exactly what a future reader needs when the same
221+
observation recurs. A discarded lesson that leaves no trace gets re-learned and re-filed.
222+
223+
**Archive the corrected text, not the original.** Check each lesson for a diagnosis that has since
224+
been refuted or superseded — a lesson corrected after the fact is common, and preserving the
225+
superseded diagnosis as the record would re-mislead precisely the reader who trusts the archive.
226+
227+
## Step 4 — Distribute open defects and watches to the successors
228+
229+
Every open-defect and watch entry in the epic anchor takes exactly one of:
230+
231+
- **closed**, with the evidence that closed it;
232+
- **re-homed** into a named successor epic;
233+
- **kept as frozen history**, moving to `$EPIC/history.md` at close.
234+
235+
> ### AUDIT ITEM — an assertion of re-homing is not a re-homing
236+
>
237+
> Entries that already read *"RE-HOMED to X — track it there"* are **claims, not facts**. **Verify
238+
> each one exists in the target epic's tree** before accepting it:
239+
>
240+
> ```bash
241+
> grep -rn "<the defect's distinguishing phrase>" .plan/local/orchestrator/<target-slug>/
242+
> ```
243+
>
244+
> **The failure is structural, not sloppiness.** The write boundary (above) forbids the orchestrator
245+
> from writing into another epic's tree, so it can only record the intent and depend on a later
246+
> session to enact it — and a re-homing has already sat asserted-but-unwritten for a day for exactly
247+
> that reason. **You are that later session.** Where the entry is missing from the target, write it
248+
> in now, then mark the source entry re-homed; where it is present, say so with the file and line
249+
> you found it at.
250+
251+
## Step 5 — Consolidate memory
252+
253+
Project-scoped rather than epic-scoped, so it survives this epic and may run at any point in the
254+
close-out.
255+
256+
Dedup the memory files, prune entries about defects that are now closed, and merge near-duplicates.
257+
**Re-read each against current ground truth rather than trusting its summary line** — a memory whose
258+
prescription was refuted after it was written is worse than no memory, because it is consulted with
259+
confidence. Correct it or delete it; do not leave the stale prescription standing.
260+
261+
---
262+
263+
## For the successor epics
264+
265+
Steps 6 and 7 write into the successors' trees. They can start earlier than the rest, but **step 6
266+
should follow step 1**, so the successors inherit a mechanism that has just been exercised end to
267+
end.
268+
269+
## Step 6 — Implant the bundle hand-off mechanism
270+
271+
For each successor epic that lacks it:
272+
273+
- create `bundle-handoff-index.md` and `archive/bundle-handoffs/`;
274+
- **numbering starts at round 1 in that epic**, with the epic's name distinguishing the carriers. Do
275+
not continue the predecessor's round numbering.
276+
- carry across the two rules that were learned expensively: **the index is the durable dedup base,
277+
kept forever**, and **rows flip `UNSENT` → sent in the same action as the send**.
278+
279+
## Step 7 — Add a close-out state document to each successor
280+
281+
Same shape as the predecessor's, adapted: bundle round delivery, ledger sweep, lesson consumption,
282+
defect distribution, memory consolidation — plus whatever this epic re-homed into it.
283+
284+
**Each successor's document carries state and points here for mechanism.** It does not re-state the
285+
sequence; a copy of the mechanism in every epic is the duplication this skill exists to remove. It
286+
*does* carry the consume convention by reference — `archive/lessons-consumed/{lesson-id}.md`,
287+
persist-then-remove, discards archived with their rationale — because the corpus is global and the
288+
convention must hold identically in every epic.
289+
290+
## Step 8 — Harvest what this epic learned for the successor that will do it next
291+
292+
Where this epic performed something a successor will perform again — a release cut, a migration, a
293+
first-of-its-kind rehearsal — the pre-flight knowledge it produced typically exists **nowhere but
294+
this epic's anchor** and would otherwise be re-learned at full price.
295+
296+
Move it into the successor that will do it next, in the successor's own ledger. Two rules about
297+
where it lands:
298+
299+
- Knowledge about **how the repository's process works** belongs in that process's own documentation
300+
or skill, not in an epic ledger — file it as a step 3 *repository source* disposition instead.
301+
- Knowledge that is **an instance-specific caution for the next run** — what was nearly missed last
302+
time, what a green result did not actually prove — belongs in the successor's ledger, where the
303+
next run will read it.
304+
305+
---
306+
307+
## Report and stop
308+
309+
Report, per step:
310+
311+
- the round delivered, its item count, and confirmation that the index rows were flipped **in the
312+
same action**;
313+
- what the ledger sweep found unfiled, and any class named in the carrier rather than filed as rows;
314+
- the lessons corpus count before and after, each disposition, and the archive path each landed at —
315+
**including the discards**;
316+
- for **every** asserted re-homing: whether it was found in the target tree (with file and line) or
317+
written in now;
318+
- what memory consolidation changed;
319+
- which successors received the bundle mechanism, their close-out documents, and the harvested
320+
pre-flight knowledge.
321+
322+
Then **stop**. State plainly that the epic is dispositioned and **not closed**, and that `close` is
323+
the operator's separate decision.
324+
325+
## Critical rules
326+
327+
- **This skill never calls `close`.** Disposition and closure are separate acts.
328+
- **Never run it on an inferred slug**, and never while a plan is still in flight.
329+
- **Consume means archive, never delete**`archive/lessons-consumed/{lesson-id}.md`, and
330+
**persist-then-remove**: destination write, then archive copy, then `manage-lessons remove`.
331+
- **A discard is a disposition with a reason, and is archived with it.**
332+
- **Archive the corrected text of a superseded lesson, not the original.**
333+
- **The lessons corpus is global to the repository**, so the archive convention must be identical in
334+
every epic or the audit record is arbitrary.
335+
- **An assertion of re-homing is not a re-homing** — verify it in the target tree, or enact it.
336+
- **The bundle index is the durable dedup base**, checked before compiling and **flipped in the same
337+
action as the send**; round numbering **restarts at 1 per epic**.
338+
- **A class cover note beats N disconnected rows** when several findings share a shape.
339+
- **Nothing epic-specific belongs in this file.** State lives in the epic's ledger.
340+
- **Temporary files go under `.plan/temp/`.**
341+
342+
> **Activation latency (harness surface).** A newly authored or edited `.claude/skills/**` body is
343+
> not discoverable as an invocable skill in the session that wrote it. Either start a fresh session
344+
> or simply **follow this file as a document** — it is written to read correctly both ways.
345+
346+
## See also
347+
348+
- `$EPIC/epic-closeout.md` — this epic's *state*: what is outstanding, right now.
349+
- `$EPIC/bundle-handoff-index.md` — the durable dedup base for step 1.
350+
- `.plan/local/lessons-learned/` — the repository-wide corpus step 3 drains.

0 commit comments

Comments
 (0)