docs-compact · git:20260930.a0a686d · 2026-09-30 · sha256 da69258ccc8e8855
docs-compact git:20260930.a0a686dA
Immutable. This exact content never changes and is served at /api/v1/blob/da69258ccc8e8855.
---
name: docs-compact
description: "Compact the tree's documents to what holds at the head of the main branch: rewrite each ADR to its present decision with a status of one date, remove the ADRs that constrain nothing, cut the changelog to the latest release, clean the rows of specs/architecture.md, and rewrite the comments that tell what the code did before. With --migrations, fold each role's migration chain into one revision under the head's revision id, shown equal by a schema dump. Works on a branch, pushes nothing, and reports what it removed, rewrote, and kept."
allowed-tools: Read, Grep, Glob, Edit, Write, Bash(git status:*), Bash(git fetch:*), Bash(git symbolic-ref:*), Bash(git switch:*), Bash(git log:*), Bash(git diff:*), Bash(git rev-parse:*), Bash(git merge-base:*), Bash(git ls-files:*), Bash(git rm:*), Bash(git mv:*), Bash(git add:*), Bash(git commit:*), Bash(git restore:*), Bash(git clean:*), Bash(git grep:*), Bash(git tag:*), Bash(diff:*), Bash(mkdir:*), Bash(gh release:*), Bash(gh run:*), Bash(gh api:*), Bash(docker info:*), Bash(docker compose:*), Bash(uv run:*), Bash(make setup), Bash(make check), Bash(make infra-up), Bash(make migrate), Bash(make migrate-check), Bash(make test-integration)
---
# docs-compact
A document an agent reads says what holds at the head of the main
branch, in the present tense: a README, an ADR, a spec, a comment. What
was stays in git, the pull request, and the release notes (the
guideline's Documentation as Code). An agent acts on what it reads, so
text that also carries what was makes it sort the adopted from the
rejected before it acts. This skill cuts the tree's documents back to
what holds.
One test decides a rejected option. Could a reader at the head reach it
without knowing the past? A simpler design, a library's default, the
obvious other way: yes, so it stays as one sentence in the Decision, as
the rule's near miss with its reason ("a lock bound, never a statement
deadline: a long backfill would fail for running"). A former value, or
an option only the history explains: no, so it goes.
## Input
`[--migrations]`
Without the flag the skill rewrites text only, and never opens
`om/migrations/`. With it, it also folds each role's migration chain
into one revision, as step 7 says. It runs at the root of the checkout.
## Role and credential
None of the platform's: it reads no environment, and logs in to no
database but the two the fold makes on the local stack and drops. It
reads the repository host through `gh`, under the person's own sign-in:
each release's notes, and for the fold each environment's last deploy.
## One-time preparations
Each is a person's to do, once. A part whose preparation is missing is
left as it is, and the report names it under Kept.
- **The changelog.** Every release the changelog lists below its latest
has its notes on the repository host (`gh release view v<x.y.z>` exits
0). A release with none keeps its section. The skill saves that
section as `release-v<x.y.z>.md` in the evidence folder, and the
report gives the command that publishes it: `gh release create
v<x.y.z> --verify-tag --notes-file <that file>`.
- **The fold.** Every environment has deployed the commit that holds the
newest migration. The local stack is up (`make infra-up`), with `make
migrate` run once.
## Procedure
1. **Start clean, on a branch.** `git status --porcelain` prints
nothing, or refuse. `git fetch origin`. The main branch is the one
`git symbolic-ref --short refs/remotes/origin/HEAD` names. On it, cut
the work branch, named for the day: `git switch --no-track -c
docs-compact-<yyyy-mm-dd> origin/<main>`. The name is taken when
`git rev-parse --verify --quiet <name>` or `git rev-parse --verify
--quiet origin/<name>` prints a commit: add a suffix then (`-2`). On
another branch, work there only when `git log
--oneline origin/<main>..HEAD` prints nothing; otherwise refuse.
Make the evidence folder, `mkdir -p
~/Downloads/acme_docs_compact_<yyyy-mm-dd>/`.
2. **Take the inventory**, and keep it for the report. Read nothing
under `node_modules`, a lock file, a generated file
(`clients/typescript/openapi.json` and the two schemas `make openapi`
writes), or a skill folder that is a link.
- Every `docs/adr/NNNN-*.md`: its status line, its `##` headings, and
who cites its number (`git grep -n "NNNN"`: the code, the config,
and the Markdown).
- `CHANGELOG.md`: its release sections, when the tree has one.
- The Substitutions and Deviations rows of `specs/architecture.md`.
- The sentences that tell a past, in the Markdown and in the code's
comments and docstrings. `references/phrases.txt`, in this skill's
folder, lists the phrases that mark one, a pattern a line, each
matched as whole words:
```bash
git grep -nIiwE -f .agents/skills/docs-compact/references/phrases.txt -- . ':!.agents/skills/docs-compact'
```
The list is the sweep: the skill reads each hit in its paragraph,
and does not read every file.
3. **Compact the ADRs**, each once, then commit them alone.
- **Rewrite in place** an ADR whose decision holds. Its status is
`**Status**: accepted (<date>)` and nothing more, with the first
date the old status names, the day it was accepted. Every later
date in it goes. It keeps Context, Decision, and Consequences, in
that order, and any section that states a present fact, such as a
measurement. A section named for a past (Amended, Closed,
Alternatives, History) goes: what still holds in it moves into the
Decision or the Consequences, and a rejected option goes through
the test above. The text states the decision as it stands, with no
"since", "no longer", or former value, and names no ticket, pull
request, or person.
- **Remove** an ADR that constrains nothing at the head: one replaced
whole, one that is closed, one that records what a release asked or
that a pin moved. A decision in it that still stands moves first,
into the ADR that records that decision. When no ADR does, the
decision most cited stays in this file, rewritten, under its
number. The file then takes that decision's name (`git mv`, to
`NNNN-<the decision, as a slug>.md`), as any rewritten ADR does
whose name says another subject: the number stays, and every link
and every `adr =` path follows. Each other one gets a new ADR of
its own, numbered in turn: the first one above the highest the tree
held when the run began, the next one above that. A citation of the
kept number that meant a moved decision names the ADR that now
holds it.
- **Fold** a substitution that has an ADR of its own into the one ADR
that lists the substitutions, as one row and the sentences that row
needs, and remove the ADR.
- **Re-point every citation** of a removed number before its file
goes (`git rm`): a link in Markdown, an `adr =` entry in
`pyproject.toml`, an `ADR NNNN` in a comment. Each names the ADR
that now holds the decision, or goes when what it explained is
gone. `arch-check` fails on a number that code cites and no file
has.
- An ADR that only restates a rule of the guideline, and decides
nothing of the tree's own, constrains nothing. It is removed when
no code or config cites its number, its links in Markdown going
with it. While one does, it is kept, and listed. An ADR the test
leaves in doubt is kept and listed too.
- A file under `docs/adr/` that is not an ADR, such as a picture,
goes when no ADR links it. An ADR never goes for want of a link.
4. **Cut the changelog** to its latest release: the lines above the
first release, that one section, and one line that says every
release's notes stay on the repository host. Each older section goes
when its preparation holds. Commit.
5. **Clean the rows** of `specs/architecture.md`: each says what the
substitution or the deviation is, in the present tense, with its end
condition when it has one. A date, a release, and "ended with" go. A
row whose ADR step 3 removed goes, or names the ADR that holds it
now. The pin line stays as it is. Commit.
6. **Rewrite the sentences** of step 2's sweep, each hit judged once.
- A sentence about the code's past goes, or is rewritten to what the
code does: what a former release did, what changed, what a value
once held.
- A sentence about a running system stays: "raises `LeaseLost` when
the item is no longer this worker's" is state, not history. So does
a rule's near miss, and a lens's or a skill's own words for a
breach.
- A comment on code that serves the release before, in an expand and
contract still in flight, stays, in the present tense: what the
code tolerates, and what ends it. The test: find the commit that
added the piece (`git log -S'<its name>' --format=%H -- <file>`,
the last line it prints), and count the release tags that hold it
(`git tag --contains <commit>`). With fewer than two, an
environment may still run, or roll back to, the release the piece
serves: it is in flight. With two or more, it serves a release
long gone. In doubt, or in a tree that tags no release, it is in
flight.
- Only text changes: a comment, a docstring, a document. A name in
code is code. Code that seems to serve a release long gone is
listed in the report and left as it is.
Commit.
7. **With `--migrations`, fold each chain.** Read `references/fold.md`
first, and follow it: the precondition and how each part of it is
read, the two dumps that prove the fold, what else a fold moves, and
its commit. When the precondition does not hold, the chain stays as
it is and the report says which part failed.
8. **Run the gates.** `make setup` first, which installs the tree and
formats its Python; commit what it changes, apart. Then `make
check`. When `docker info` exits 0, also
`make infra-up`, `make migrate`, `make migrate-check`, and `make
test-integration`; otherwise the report names each one skipped. A
gate that fails is fixed in a commit of its own, and the gate runs
again from its first command: the first run plus at most 3 reruns,
then stop and say which gate fails and why.
9. **Write the report.**
## Bounds
- One pass: each document is rewritten once in a run. What a second
reading would change is a second run's.
- The gates, and the fold's proof, each take the first run plus at most
3 reruns.
- Its Next is the person's to run, never the session's: it pushes
nothing.
## What it never does
- Never drops a deviation's end condition: "until an operator task
needs a screen" is a trigger, not history.
- Never trims an expand and contract in flight, as step 6 tells one:
its comments, the column, the default, or the trigger it keeps stay
until the contract step lands. Its ADR is rewritten as any other is,
to the present tense and one date, and keeps every fact of the
contract: what the release before still reads or writes, the piece
that serves it, and the step that ends it.
- Never renumbers an ADR, and never gives a removed ADR's number to
another: a removed ADR leaves a gap.
- Never drops a reason that stops a plausible wrong change: it stays as
a near miss.
- Never changes a statement of code. A test changes only with
`--migrations`, and only one that pins a revision the fold removes,
tests a backfill it removes, or steps down from the head.
- Never opens `om/migrations/` without `--migrations`, and never edits
an applied migration file: a fold replaces a chain whole.
- Never writes to a shared database or to an environment: it logs in
only to the two databases it made on the local stack, and drops them.
- Never pushes, never opens a pull request, never publishes or edits a
release. It moves no pin.
## Output
The work branch, one commit per category, and
`~/Downloads/acme_docs_compact_<yyyy-mm-dd>.md`:
```markdown
# Acme: documents compacted to what holds
Branch <name> at <commit>, cut from <main> at <commit>. Migrations: <folded | not asked | kept: which part of the precondition failed>.
| category | removed | rewritten | kept |
|---|---|---|---|
| ADRs | | | |
| Changelog | | | |
| Table rows | | | |
| Comments and documents | | | |
| Migrations | | | |
## Removed
- <ADR NNNN, or a section, a row, a file>: <what held it, and where its live part went>
## Rewritten
- <file>: <what it says now, in a line>
## Kept
- <what, and why: a trigger, an expand and contract in flight, a near miss, a preparation still missing, a doubt, with the question>
## Code that serves a release long gone
- <file:line>: <what it does, and what would remove it>
## The fold (with `--migrations`)
| role | head id | revisions folded | backfills left out | dump of the chain against the fold's |
|---|---|---|---|---|
The last commit before the fold: <sha>. A snapshot older than the fold is restored at that commit's release, which migrates it to the head, and then moves to the current one.
## Gates
- <gate>: <result, or skipped and why>
## Next
Push the branch and open the pull request: a person's to run, never the session's.
```