compact · diff
git:20260905.ce103be to git:20260906.efaff19
17 added, 17 removed. Audit A to A.
---
name: compact
description: Put the compaction question to a snapshot that drifted — route what no longer constrains unfinished work, and say what moves before moving it. In flight or done; the log is appended to, never edited or trimmed.
disable-model-invocation: true
argument-hint: "optional: a work slug, or nothing to put the question to every in-flight snapshot"
allowed-tools: Bash(python3 ${CLAUDE_SKILL_DIR}/../genius-file/measure.py *)
---
# Compact
- Every close is supposed to compact — the question in [genius-file's format](../genius-file/FILE-FORMAT.md) asked of each line, the answers routed. Snapshots drift anyway: a close that ran before the question existed, a session that read "compact to current truth" as satisfied by changing nothing, a stretch of slices closed in a hurry. `/reconcile` is what finds a snapshot over its ceiling or carrying history; **this is what fixes one** — `errata`'s three moves cannot, because nothing here is wrong, it is only in the wrong file.
+ Every close is supposed to compact — the question in [genius-file's format](../genius-file/FILE-FORMAT.md) asked of each line, the answers routed. Snapshots drift anyway. `/reconcile` finds a snapshot over its ceiling or carrying history; **this is what fixes one** — `errata`'s moves cannot, because nothing here is wrong, it is only in the wrong file.
- The concept: **the same question, the same destinations, applied where a close did not — and nothing moves before the user has seen what moves.** The rule is not this command's to invent: that format owns the question, its three destinations and its two tie-breaks, and reading it there is the first step, not a formality. What this command adds is the retroactive pass, the proposal, and the checks below.
+ The concept: **the same question, the same destinations, applied where a close did not — and nothing moves before the user has seen what moves.** The format owns the question, its destinations and its tie-breaks; reading it there is the first step. What this command adds is the retroactive pass, the proposal, and the checks below.
- The counts as this command was invoked — every snapshot under the work dir, whole and with the roster excluded, against the ceiling. On Claude Code the block below is the instrument's output; where a policy notice shows instead (shell injection disabled for this session), run it before proposing. Below the counts, both directions of the invariant as the instrument reads them — links whose target or anchor is missing, log entries nothing links, keys with prose after them:
+ The counts as this command was invoked — every snapshot, whole and roster excluded, against the ceiling — and both directions of the invariant: links whose target or anchor is missing, log entries nothing links, keys with prose after them. Where a policy notice shows instead (shell injection disabled), run it before proposing:
```!
python3 ${CLAUDE_SKILL_DIR}/../genius-file/measure.py snapshots
python3 ${CLAUDE_SKILL_DIR}/../genius-file/measure.py links
```
- - **Scope: a snapshot with a log beside it, in flight or done.** Unlike `/distill`, being finished is no bar: a done file is record layer for *correcting* (`errata` skill carries the carve-out), and routing a misfiled line is not correcting a wrong one. **The log is appended to and never otherwise touched** — not edited, not trimmed, not tidied. A heading whose key carries prose after it is the case that most tempts a pass into breaking that rule; the format holds the repair, and it is the link rather than the heading. ⚠ **A link whose target is genuinely not in the log is reported, never repaired** — check first that it is not the prose-after-key case, which looks missing and is not. Where the entry truly was never written, this command has no move and should not invent one: repairing it means writing the log, which it does not do, or guessing an anchor, which puts a wrong door where a missing one at least reads as missing. `/reconcile` routes these here, so "found, not fixed, here is the link and what it names" is the honest end of that route rather than a failure of it — and the call is the user's, since only they know whether the entry is missing or the link was always wrong.
- - **A work in some other shape is brought to the format as it is routed.** A contract still sitting in the snapshot goes to a `CONTRACT.md` created for it, in the right layer; a work sitting flat in `.genius/` moves into its folder with the repository's own move, its links rebased in both directions — the files at `.genius/` gain the slug's folder, the work's own paths become siblings. Lines that answer "arrived with a slice" are never routed to the log to make the number work: the log records and does not bind, so that trade buys a smaller file by demoting live constraints to history. A brand-new work whose log has no first entry yet has nothing to route into, and that is the true reason to skip it.
- - **Read before proposing.** The snapshot, the `CONTRACT.md` beside it where Galvanizing wrote one, and the log's headings. Destinations are decided against the Slices list, which is in the snapshot, so a full log read is never the price of this pass.
- - **Propose, then move.** Read-only until the user has seen, per section, what leaves and where to (categories and counts, not a line-by-line ballot), the character count now and after, and every line you were unsure about. Three things make a line unsure, and each has to be said rather than quietly decided: it answers two branches at once (the tie-break covers it, say which way it went), its owning slice is not obvious, or its log entry's heading carries prose after the key so the link cannot be written. One confirmation covers the batch; a move the user has not seen is a silent one.
- - **Count the way the format counts**, instrument and exclusions both — read them there rather than from memory, since a count taken the wrong way is what sends this pass after the wrong problem: a full-text count reads a thirty-slice migration as bloated when its prose is half the ceiling, and the three remedies you would then reach for are all wrong. The block above is the count *now*; the count *after* is the same command run again once the moves are made, never arithmetic done on the proposal.
- - **Under-ceiling is not the same as compacted, and this pass says which it found.** A snapshot under its ceiling can still be carrying a closed slice's paragraph; one over it can be a large roster that is exactly right. Report the two separately, and where the question moves nothing, say "nothing to route" — finding a snapshot already in shape is a result, not a failure to find work.
- - **Where the count stays over after routing, say so and stop.** The remedies from there are not this command's: a Problem section carrying design, an Open section nobody drained, or a cut that is really two pieces of work. Name which it looks like; never shorten a kill-reason to make a number.
+ - **Scope: a snapshot with a log beside it, in flight or done.** Unlike `/distill`, being finished is no bar: routing a misfiled line is not correcting a wrong one (`errata` skill carries the carve-out). **The log is appended to and never otherwise touched.** A heading whose key carries prose after it is the case that most tempts a pass to break that rule; the format holds the repair, and it is the link, not the heading. ⚠ **A link whose target is genuinely not in the log is reported, never repaired** — check first that it is not the prose-after-key case. Repairing it would mean writing the log, which this command does not do, or guessing an anchor, which puts a wrong door where a missing one at least reads as missing; the call is the user's.
+ - **A work in some other shape is brought to the format as it is routed.** A contract still sitting in the snapshot goes to a `CONTRACT.md` created for it, in the right layer; a work sitting flat in `.genius/` moves into its folder with the repository's own move, links rebased in both directions. Lines that answer "arrived with a slice" are never routed to the log to make the number work: that trade demotes live constraints to history. A brand-new work whose log has no first entry has nothing to route into; skip it.
+ - **Read before proposing.** The snapshot, the `CONTRACT.md` beside it, and the log's headings. Destinations are decided against the Slices list, so a full log read is never the price of this pass.
+ - **Propose, then move.** Read-only until the user has seen, per section, what leaves and where to (categories and counts, not a line-by-line ballot), the character count now and after, and every line you were unsure about: one answering two branches at once (say which way the tie-break went), one whose owning slice is not obvious, one whose log heading carries prose after the key. One confirmation covers the batch; a move the user has not seen is a silent one.
+ - **Count the way the format counts**, instrument and exclusions both: a full-text count reads a thirty-slice migration as bloated when its prose is half the ceiling, and every remedy you would then reach for is wrong. The count *after* is the same command run again once the moves are made, never arithmetic on the proposal.
+ - **Under-ceiling is not the same as compacted, and this pass says which it found.** A snapshot under its ceiling can still carry a closed slice's paragraph; one over it can be a large roster that is exactly right. Where the question moves nothing, say "nothing to route": that is a result.
+ - **Where the count stays over after routing, say so and stop.** The remedies from there are not this command's: a Problem section carrying design, an Open section nobody drained, a cut that is really two pieces of work. Name which it looks like; never shorten a kill-reason to make a number.
## Where the branches land
- - **Into `CONTRACT.md`, in the right layer.** The brief, the test seams and the pinned values belong to the plan layer; a convention a slice established belongs to the established layer with its source link. Putting them in the wrong layer costs nothing today and everything at the next version bump, which replaces the plan layer whole: seams filed as "established" survive a replacement they should not have, and anything filed as "plan" that a slice established is deleted while it still binds.
+ - **Into `CONTRACT.md`, in the right layer.** The brief, the seams and the pinned values belong to the plan layer; a convention a slice established belongs to the established layer with its source link. The wrong layer costs everything at the next version bump, which replaces the plan layer whole.
- **Into the log, in the shape the format names** — verbatim, keyed off the anchor its line already links.
- - **Open drains by its own rule** (the format's law for Open — it grows by how many times the user was met, so it is drained rather than shortened): a consumed `assumed:` to the log, an item that is its own work to the log verbatim first, with `.genius/BACKLOG.md` taking a one-line seed pointing at that anchor. `BACKLOG.md` sits at `.genius/`, so its links start with the slug's folder — the format's link rule.
- - **`stage: done` changes three things.** The snapshot's resting shape stays whole, whatever a literal reading of the question says about it — the format's rule for done work names what that covers, and it is the Problem, the Decision, the changelog and the roster together, not the roster alone; read it there rather than deciding it here. `CONTRACT.md` is not drained — Tenacity's close-out settled that. And a log already carrying `distilled at close-out` will not be distilled again, so anything appended after that line stays forever: append it only where it is worth keeping on those terms, and say in the pass entry that content follows the distillation.
+ - **Open drains by its own rule**: a consumed `assumed:` to the log; an item that is its own work to the log verbatim first, with `.genius/BACKLOG.md` taking a one-line seed pointing at that anchor (links from `.genius/` start with the slug's folder).
+ - **`stage: done` changes three things.** The resting shape stays whole — Problem, Decision, changelog, roster — whatever a literal reading of the question says. `CONTRACT.md` is not drained. And a log already carrying `distilled at close-out` will not be distilled again, so anything appended after that line stays forever: say in the pass entry that content follows the distillation.
## Finishing
- - **Mark the pass** — `## compacted-<date>` in the log, naming what moved and where, with a link to it left in the snapshot beside the drained-from section, so it is reachable like everything else.
- - **Check both directions before reporting done.** Every link in the snapshot resolves to a heading that exists, and every `##` entry in the log is linked from the snapshot or named in the report as one that should not be. The block above read both directions as this command was invoked; after routing, run the same `links` command again, because the moves just made are exactly what can break them. An entry that should be reachable and is not gets its link restored **here**, in the section it backs — that is a snapshot write, which is this command's own layer, and it is the half of the invariant nothing else sweeps per work. The second direction is the one this pass can break, and the one the invariant actually promises; `/reconcile` sweeps for it across works, this checks the work in hand.
- - **Check that nothing binding left the binding layer**: every line that was in the contract section is now in `CONTRACT.md` or the snapshot. A contract line that reached only the log has been silently demoted from binding to history, which is the one failure this pass could cause that nobody would notice.
+ - **Mark the pass** — `## compacted-<date>` in the log, naming what moved and where, with a link left in the snapshot beside the drained-from section.
+ - **Check both directions before reporting done**: run `links` again, because the moves just made are what can break them. An entry that should be reachable and is not gets its link restored here, in the section it backs — a snapshot write, this command's own layer, and the half of the invariant nothing else sweeps per work.
+ - **Check that nothing binding left the binding layer**: every line that was in the contract section is now in `CONTRACT.md` or the snapshot. A contract line that reached only the log has been silently demoted from binding to history.
- Done when every targeted snapshot has been routed and reported, or named as skipped with the reason that is actually true of it — and when what the pass could not fix is stated rather than trimmed around.
+ Done when every targeted snapshot has been routed and reported, or named as skipped with the reason that is true of it — and what the pass could not fix is stated rather than trimmed around.