Skip to content

refactor(unic-archon-dlc): Step 7's CLAUDE.md block rots, and two dead lib modules still claim /setup writes agent docs #296

Description

@orioltf

What to build

Step 7 writes a marker-delimited block into the Consumer's CLAUDE.md. Rewrite it to point at what is
installed on that Consumer's disk, discovered live, instead of restating this plugin's own shape.
Then delete two dead lib/ modules, one of which still tells the reader that /setup writes agent
docs.

Blocked by

None.

#295 rewrites Steps 6 and 8 of commands/setup.md; this rewrites Steps 4 and 7 of the same file. The
two overlap in one file, not in one contract: whichever lands second rebases. Nothing in this issue
reads anything #295 builds — D4 cites #295 only to record that no hash store is coming.

#295 has moved since the round-1 amendment, which recorded it as needs-specs. Re-run for this
revision, gh issue view 295 --json state,labels reports OPEN, labels app:unic-archon-dlc, ready-for-agent, feature, p2, exit 0. The blocked-by call therefore rests on the criteria alone, not
on #295's readiness.

Drafter's call: None rather than #295, on the grounds that no criterion here depends on #295's
output. The maintainer may overturn it to #295 if the file overlap is worth serialising.

Why this issue was rewritten — 2026-08-13

The original body was specced on 2026-08-11 and re-verified against the pre-#294 tree. A night-shift
pre-audit (the first comment below) found the defect real and the criteria not dispatchable: two
contradict each other, four cannot fail, and two depended on #295's install record. That comment stays
as the audit trail; this body replaces the spec it audited.

Four further pre-dispatch audits followed. Round 1 returned needs-amendment on seven findings, round
2 on four, round 3 on three, round 4 on six: a live test pins one sentence of the Step 7 prose ACs 1-9
rewrite, criterion 20 refused a format rule the plugin's own ADR README imports and miscounted the
practice it rested on, its "two edits, and only two" left the ADR index row stale, the evidence heading
below said "three places" where two exist, and criterion 10 asserted the heading it asks to replace was
already right. This revision answers those six and changes nothing else. Every command it cites was
re-run at 9da6b23 before publishing.

Three things changed since the 2026-08-11 spec:

One claim in the first audit is wrong: /handoff is not missing from the block's box list. It is not
this plugin's box — README.md:35 files it as (+ /handoff, /prototype — Matt's, referenced).
/archon-upgrade is the only real omission.

Evidence (re-verified 2026-08-13 against develop at 9da6b23)

Every command below was re-run from the plugin root for this revision, not copied forward.
git diff --stat 1e6cfbd..9da6b23 -- . over the plugin still returns one file —
apps/claude-code/unic-archon-dlc/CONTEXT.md, 18 insertions, 1 file changed, exit 0 — so no
evidence below moved.

Cited by heading and quoted string, not by line number, wherever the string is unique — #329 moved the
numbers the 2026-08-11 body used, and this issue and #295 will move them again. Line numbers appear
only in pasted command output, where they are the output.

The block carries plugin shape, and it has already rotted

Step 7 instructs that the block "points readers at the box set (/specs → /tickets → /build → /pr-review → /qa; on-ramps /triage, /qa; off-line /setup, /explore, /improve-architecture,
/cleanup)". /archon-upgrade is missing. README.md's own box table carries it.

A false parenthetical about a step that does not do it

Step 4's docs field still reads _(Independent of the docs/agents/*.md files Step 6 always writes.)_. Step 6 installs the Methods bundle and the Box workflows. It writes no docs/agents/*.md.
That string is unique in the file.

The step is called a docs step in two places, and the block is called auto-managed in two

One command per file, each piped through cut -c1-190 so the long lines fit. All three below were run
from the plugin root for this revision, and what follows is exactly what they printed:

$ grep -n 'Step 7' commands/setup.md | cut -c1-190
15:Follow these steps in order. Do not skip any step. Do not write any files except through Step 5 (config), Step 6 (Methods bundle), and Step 7 (docs).
348:## Step 7 — Update agent docs (idempotent)
EXIT=0

Two sites, not three. The next command's pattern adds auto-managed, so it prints a third line from
the same file — :350 — which belongs to this heading's second clause, not its first.

$ grep -n 'Step 7 (docs)\|^## Step 7\|auto-managed' commands/setup.md | cut -c1-190
15:Follow these steps in order. Do not skip any step. Do not write any files except through Step 5 (config), Step 6 (Methods bundle), and Step 7 (docs).
348:## Step 7 — Update agent docs (idempotent)
350:Write/refresh the auto-managed `## Agent skills` block in the consumer's `CLAUDE.md`, delimited by `<!-- unic-archon-dlc:begin -->` / `<!-- unic-archon-dlc:end -->`. Replace only the con
EXIT=0

$ grep -n 'auto-managed' AGENTS.md | cut -c1-190
66:- **The `## Agent skills` block in a Consumer's `CLAUDE.md` is auto-managed.** Setup writes content between `<!-- unic-archon-dlc:begin -->` and `<!-- unic-archon-dlc:end -->` markers. Ev
EXIT=0

Do not fold these back into one two-path command. In this repo's development shell grep resolves
to a function wrapping ugrep 7.5.0, which searches paths in parallel and emits them in no fixed
order: six consecutive runs of
grep -n 'Step 7 (docs)\|^## Step 7\|auto-managed' commands/setup.md AGENTS.md printed
commands/setup.md first three times and AGENTS.md first three times. One path per command is
stable, and a reader can compare it to the body without the order being evidence of anything.

The step updates one block in one file and writes no agent doc — residue of the pre-b27d1e5
generator that wrote seven docs/agents/*.md files. AC10 covers the heading and the Step 7 (docs)
line; the Step 7 body prose is rewritten wholesale by ACs 1-9. AC17 covers AGENTS.md's
"auto-managed".

One sentence of Step 7's prose is pinned by a passing test

test/config-schema.test.mjs:511-532 — the test named
commands/setup.md keeps the classification.labels question and the CLAUDE.md marker sentence — reads
commands/setup.md and asserts three of its sentences. The third is Step 7's. One command per file,
from the plugin root, cut -c1-190 on the long line:

$ grep -n 'carries one sentence naming' test/config-schema.test.mjs
529:		/carries one sentence naming `classification\.labels`/,
EXIT=0

$ grep -n 'carries one sentence naming' commands/setup.md | cut -c1-190
352:The block also carries one sentence naming `classification.labels` as the Canonical role → tracker Label string mapping this project answered during setup, and pointing at `/unic-archon-
EXIT=0

The assertion's message at :530 is
'Step 7 must keep pointing the CLAUDE.md marker block at classification.labels'.

ACs 1-9 rewrite Step 7's prose wholesale and AC16 requires pnpm test to exit 0, so this is the one
place in the step where two criteria can collide. AC3 settles it, and ## Out of scope records that
D5's ban is on new tests, not on this one.

Two lib/ modules are dead, and their tests hold a falsehood in place

Neither module has an importer outside its own test file.
grep -rn 'prependBanner\|buildHandoff\|updateRoadmap\|SKILLS_BLOCK_BANNER\|AGENT_DOC_BANNER' .
(excluding node_modules and .git) returns hits in CHANGELOG.md, test/dogfood-banner.test.mjs,
test/handoff-generator.test.mjs and the two lib/ files themselves, exit 0. Nothing else.

lib/handoff-generator.mjs is on ADR-0018's dissolve list and survived the dissolution;
grep -n 'handoff-generator\|dogfood-banner' docs/adr/0018-generic-core-config-compose.md returns one
line, exit 0:

24:                     · setup-explorer · agent-docs-writer · handoff-generator · findings-writer

lib/dogfood-banner.mjs is not on that list — grep -rn 'dogfood-banner' docs/ returns nothing,
exit 1. It was written later, and its case for deletion rests on the dangling AGENT_DOC_BANNER
reference below, not on ADR-0018.

lib/dogfood-banner.mjs:

  • AGENT_DOC_BANNER names lib/agent-docs-writer.mjs as its source and runInstall() in
    lib/install-runner.mjs as its regenerator. Neither module exists. This is the live claim in
    lib/ that /setup writes agent docs.
  • SKILLS_BLOCK_BANNER is not used by Step 7. CHANGELOG.md:379 says it is; that was true of the
    deleted install-runner.
  • prependBanner has no caller.
  • test/dogfood-banner.test.mjs:12 asserts the banner names agent-docs-writer.mjs — a passing test
    pinning a dangling reference.

lib/handoff-generator.mjs:

  • buildHandoff has no caller. /handoff is Matt's skill, referenced and never implemented here.
  • updateRoadmap writes docs/workflow/ROADMAP.md, a file ADR-0013 retired.
  • test/handoff-generator.test.mjs:73 is the "existing idempotence test" the original AC4 pointed at.
    It covers a different writer, a different file, and a retired file.

Both test files are enumerated in package.json's test script, so both run and both report green.

Decisions

D1 — The block enumerates no Box and no pipeline stage

An agent reading a Consumer's CLAUDE.md splits into two halves, and only one is invisible to it:

Visible how
Interactive boxes (/specs, /tickets, /triage, …) Claude Code lists them — the plugin is installed in the session
Archon Boxes (unic-dlc-*.yaml in .archon/workflows/) Invisible — YAML on disk, run through the archon CLI

The block's payload is the second row. It reaches it as a rule, not a list: the directory, the
unic-dlc-*.yaml naming, archon workflow list to enumerate what is actually installed on this
Consumer, and archon workflow run <name> "<slug>" to run one. No Box is named.

The rule, in one line: the block enumerates no Box and no pipeline stage. Those two are what a
plugin release renames, reorders and drops. /archon-upgrade fell out of the box list and nobody
noticed; the pipeline changed twice (D2). Everything else the block carries is a path on the
Consumer's own disk, a discovery command, or a link.

One Box name is unavoidable: /unic-archon-dlc:setup. The block cannot say what wrote it without
naming it. D7 draws that line.

A rejected rule, recorded so nobody reinstates it. An earlier draft stated D1 as a test — "could a
plugin release make this false without touching the Consumer repo? If yes, it is a link, not a fact."
That test bans three lines the criteria require:

  • the unic-dlc-*.yaml naming (AC2),
  • .archon/methods/ being replaced wholesale on every run (AC4),
  • /unic-archon-dlc:setup regenerating the block (AC6).

Each is a claim about how /setup treats a Consumer's disk, so a plugin release falsifies it with no
Consumer change. Each is also the only surface a Consumer can learn the thing from. The test is
withdrawn. Rot lives in enumerations, not in every plugin-owned fact — and the three exemptions are
named here, in D1, not asserted downstream in D3 and D7. Do not carry the withdrawn test into
AGENTS.md; AC17 writes the one-line rule instead.

D2 — The pipeline order is a link, not a sentence

/specs → /tickets → /build → /pr-review → /qa is the most useful sentence in the block and the one
D1 bans. It changed twice in this plugin's short life — ADR-0014 set the box set, then ADR-0023 and
ADR-0026 moved refactoring out of /build. A Consumer that installed six months ago would read a
stale diagram with no signal that it is stale, which is docs/agents/workflow.md's failure repeating
at one-tenth the size.

D3 — The Methods tree gets one sentence, because nothing else tells a Consumer

installMethods clean-replaces .archon/methods/ wholesale on every run
(lib/methods-bundle.mjs:172entries: [{ kind: 'directory', destinationDir: join(repoRoot, INSTALL_DIR), items }]). An agent that edits a Method there loses the edit silently — unlike a Box
YAML, which carries a header warning. .archon/methods.local/ is the override tier, and docs/boxes/
and the plugin README are not installed, so the block is the only surface a Consumer can learn this
from.

It names no Box and no pipeline stage, so D1 permits it. It is one of the three plugin-behaviour facts
D1 names as deliberate.

D4 — Drop the auto-managed framing rather than enforce it

Nothing detects an edit between the markers, and nothing will. #295 builds no hash store, and D1
leaves a block with no fact an operator has a reason to edit.

The markers stay — Step 7 must find its own block and must not append a second one. What goes is the
wording that invites a reader to treat the block as a durable managed document: the word
"auto-managed" in Step 7's prose and in AGENTS.md's doctrine bullet, and any
AUTO-GENERATED — DO NOT EDIT banner. One sentence inside the block says /unic-archon-dlc:setup
regenerates it. That is all.

D5 — The block stays prose in commands/setup.md, and this issue adds no test over it

Under D1 the block is five lines of static text. A test that greps commands/setup.md would assert
the instruction, not the output: an agent that follows the instruction loosely still ships a block
full of box names with the test green.

This means Step 7's idempotence stays unguarded by code, as it is today, and every criterion over
Step 7's prose is checked by reading the rewritten file — with one exception that already exists.
test/config-schema.test.mjs:511-532 greps commands/setup.md and one of its three assertions reads
Step 7's classification.labels sentence. D5 governs what this issue writes, not what #329 already
left behind: that assertion stays, it constrains one clause of the rewrite, and AC3 says which. The
decision here is only that no further test is added. Accepted: the alternative is a lib/
renderer for five lines of static text, which is the over-engineering this issue is deleting
elsewhere.

D6 — Delete both dead modules here, in one commit

lib/dogfood-banner.mjs is unavoidable: it is the live claim that /setup writes agent docs.
lib/handoff-generator.mjs is the same corpse found while verifying that one, on ADR-0018's dissolve
list, with no possible future caller. Splitting it into its own issue means re-deriving the same proof
of deadness.

D7 — The block names one slash command and, separately, the archon CLI

D1 bans Box enumeration because Box lists rot. It cannot ban every command string: the block's whole
payload is archon workflow list and archon workflow run <name> "<slug>", and #329 requires
/unic-archon-dlc:setup reconfigure. /unic-archon-dlc:setup is itself an off-line Box in this
plugin's own vocabulary (README.md:35, AGENTS.md:7), so it is the one Box name the block must
carry — the block cannot say what regenerates it without naming it.

The line D1 actually draws is between slash commands, which the plugin owns and can rename, and
the archon CLI, which it does not own. archon workflow list and archon workflow run <name> "<slug>" are Archon's public interface (ADR-0036:12,117), stable independently of any plugin release.
Slash commands other than /unic-archon-dlc:setup are this plugin's to rename, and the block
enumerates none of them.

Drafter's call: this decision replaces the flat "names no command" that the round-1 audit found
unsatisfiable, taking the narrower of the two options it offered. The maintainer may overturn it.

The target block

The exact wording is the implementer's. Every line below obeys D1: no pipeline stage, and no Box name
but /unic-archon-dlc:setup.

<!-- unic-archon-dlc:begin -->

## unic-archon-dlc

This project is configured for `unic-archon-dlc`. `/unic-archon-dlc:setup` writes this block —
anything between the markers is replaced on the next run.

- **Configuration**`.archon/unic-dlc.config.yaml`. Its `classification.labels` map is the
  Canonical role → tracker Label string mapping every Box resolves a role through. Run
  `/unic-archon-dlc:setup reconfigure` to review or change it.
- **Interactive boxes** — this plugin's slash commands. Claude Code lists them in the session.
- **Archon Boxes** — the `unic-dlc-*.yaml` files in `.archon/workflows/`. List what is installed here
  with `archon workflow list`; run one with `archon workflow run <name> "<slug>"`. They are
  generated: `/unic-archon-dlc:setup` replaces them on every run.
- **Methods**`.archon/methods/` is replaced wholesale on every `/unic-archon-dlc:setup` run. Put a
  local override in `.archon/methods.local/` instead.
- **What each box does**<https://github.com/unic/unic-agents-plugins/blob/main/apps/claude-code/unic-archon-dlc/README.md>

<!-- unic-archon-dlc:end -->

The heading changes from ## Agent skills to ## unic-archon-dlc: nothing in the block is a
registered skill, and the Methods this plugin ships are read by path precisely so they are not
(ADR-0031). The markers are the anchor Step 7 matches, so the rename costs an existing Consumer
nothing.

Acceptance criteria

Three criteria are marked [guard]. Each already holds at 9da6b23, and each names something this
issue's own rewrite can drop — a guard fails when the rewrite drops what it names. Ticking a guard is
not evidence that anything was written; leaving one broken is a regression.

Two of the three are checked by reading the rewritten file, because D5 rules out writing a new test
over Step 7's prose. The third, AC3, is not: the sentence it guards is already pinned by a passing test,
test/config-schema.test.mjs:511-532. D5 says what this issue may add; it does not describe what is
already there. An earlier revision of this paragraph read "D5 rules out a test over Step 7's prose" flat,
which is false of the tree at 9da6b23.

Drafter's call: marking every criterion that fits this definition rather than none, which is the other
consistent option. All three sit over Step 7's rewritten prose. The maintainer may overturn it.

  • The block names no pipeline stage, and exactly one slash command: /unic-archon-dlc:setup, with
    its reconfigure argument. No other slash command and no other Box name appears anywhere in it.
    The archon CLI strings the next criterion requires do not count against this — they are
    Archon's interface, not a Box name. D1, D7.

  • The block tells a reader how to find the installed Archon Boxes without naming one: the
    .archon/workflows/ directory, the unic-dlc-*.yaml naming, archon workflow list, and
    archon workflow run <name> "<slug>".

  • [guard] The block keeps fix(unic-archon-dlc): /setup never asks for the tracker's labels, so classification.labels ships as an untested guess #329's sentence naming classification.labels and
    /unic-archon-dlc:setup reconfigure. Step 7's prose is rewritten wholesale, so the rewrite can
    lose it.

    This guard has a live test behind it, and the test constrains the wording.
    `test/config-schema.test.mjs:511-532` matches `commands/setup.md` against a regex at `:529`, with
    the message at `:530`:
    
    ```
    /carries one sentence naming `classification\.labels`/,
    'Step 7 must keep pointing the CLAUDE.md marker block at classification.labels'
    ```
    
    **The rewritten Step 7 must still contain, verbatim, the literal string that regex matches:**
    
    ```
    carries one sentence naming `classification.labels`
    ```
    
    Today's `:352` opens "The block also carries one sentence naming `classification.labels` as the
    Canonical role → tracker Label string mapping …". Everything after that string is the
    implementer's, and the rest of the paragraph may be rewritten freely. Do not weaken, retarget or
    delete the assertion: AC16 requires `pnpm test` to exit 0, and Step 7 has no other sentence a
    test reads.
    _Drafter's call: preserving the wording rather than retargeting the assertion. Preserving costs
    one clause of a sentence the block must carry anyway; retargeting means editing a passing test to
    match prose that does not exist yet, in the same commit that writes the prose. The maintainer may
    overturn it — the retarget is `test/config-schema.test.mjs:527-530`, whose regex becomes whatever
    clause the rewritten Step 7 uses to require the `classification.labels` sentence, with the message
    at `:530` left as it stands._
    
  • The block carries one sentence naming .archon/methods/ as replaced wholesale on every run and
    .archon/methods.local/ as the override tier.

  • For what each Box does, the block links the plugin README at its public URL —
    https://github.com/unic/unic-agents-plugins/blob/main/apps/claude-code/unic-archon-dlc/README.md
    — and states no Box's role itself. Not a repo-relative path: D3 records that the plugin README is
    never installed, so a relative link is the dangling pointer this issue exists to delete. The URL
    is plugin.json's homepage (https://github.com/unic/unic-agents-plugins) plus the plugin
    path; gh api 'repos/unic/unic-agents-plugins/contents/apps/claude-code/unic-archon-dlc/README.md?ref=main' -q '.html_url'
    returns exactly that URL, exit 0, and gh repo view unic/unic-agents-plugins --json visibility
    returns {"visibility":"PUBLIC"}, exit 0, so it resolves for a Consumer with no access to this
    repo's checkout.
    Drafter's call: the public URL rather than another pointer. The maintainer may overturn it.

  • The block's own wording says /unic-archon-dlc:setup regenerates it. It does not describe
    itself as a document to maintain, and it carries no AUTO-GENERATED — DO NOT EDIT banner.

  • The block heading is ## unic-archon-dlc.

  • [guard] The <!-- unic-archon-dlc:begin --> / <!-- unic-archon-dlc:end --> markers are
    unchanged. They are the anchor Step 7 matches on an existing Consumer's file, so the heading
    rename must not move or reword them.

  • [guard] Step 7 still carries an in-place-replacement instruction. At 9da6b23 it reads
    "Keep the edit idempotent: re-running /setup replaces the block in place, never appends a
    second one." This issue rewrites Step 7, so that sentence is one the rewrite can drop — it must
    survive, in that wording or a clearer one. Read the rewritten step to check it.

  • Step 7 is no longer called a docs step. At 9da6b23 its heading reads ## Step 7 — Update agent docs (idempotent), which is the wording to replace; the new heading names what the step actually
    does — update the Consumer's CLAUDE.md block. The same correction lands in the one other place
    the file calls it a docs step, the "Follow these steps in order" paragraph: "Do not write any
    files except through Step 5 (config), Step 6 (Methods bundle), and Step 7 (docs)." Those two are
    the whole set — grep -n 'Step 7' commands/setup.md returns :15 and :348, exit 0.

  • The Step 4 docs field no longer carries the parenthetical
    (Independent of the docs/agents/*.md files Step 6 always writes.).

  • grep -rn 'docs/agents' commands/setup.md lib/, run from the plugin root, returns nothing and
    exits 1. At 9da6b23 it returns one line and exits 0:

    ```
    commands/setup.md:165:- **docs** — `docs.type` (`confluence | markdown | none`) — where the team's **product specs** live; `docs.publish` (default `false`, opt-in). `docs.access` from Step 3. _(Independent of the `docs/agents/*.md` files Step 6 always writes.)_
    EXIT=0
    ```
    
    Scoped to `commands/setup.md`, not all of `commands/`: the wider
    `grep -rn 'docs/agents' commands/ lib/` also returns three `commands/triage.md` hits, which are
    ADR-0024's deliberate single-source rule and stay (see `## Out of scope`). _Drafter's call:
    narrowing the path list rather than widening the issue to touch `triage.md`. The maintainer may
    overturn it._
    
    The `lib/` half of the path list carries **no [guard] marker**. `grep -rn 'docs/agents' lib/`
    already returns nothing and exits 1 at `9da6b23`, so the Step 4 edit is what makes this criterion
    pass; `lib/` is in the path list to hold ground, not to be changed. It is not a guard as defined
    above: no criterion here writes to `lib/`, the only `lib/` work is the two deletions below, and
    deleting a file cannot introduce a `docs/agents` reference. Nothing is left unverified either —
    the grep this criterion already names covers it.
    _Drafter's call: dropping the marker rather than widening the guard definition to "holds today
    and must still hold". The definition above is exact for the three criteria that keep it, all of
    which sit over prose this issue rewrites; widening it would change what those three mean without
    changing a word of them. The maintainer may overturn it._
    
  • lib/dogfood-banner.mjs and test/dogfood-banner.test.mjs are deleted.

  • lib/handoff-generator.mjs and test/handoff-generator.test.mjs are deleted.

  • Both test file names are removed from package.json's test script.
    test/test-enumeration.test.mjs fails otherwise.

  • pnpm test and pnpm typecheck pass with no reference to either deleted module anywhere in
    lib/, commands/, test/ or .archon/. Baseline at 9da6b23, both run from the plugin root:
    pnpm test exits 0 with tests 293 / pass 293 / fail 0, pnpm typecheck exits 0. After the
    deletions the pass count drops; both must still exit 0.

  • The plugin's AGENTS.md doctrine bullet is corrected. At 9da6b23 it opens "The ## Agent skills block in a Consumer's CLAUDE.md is auto-managed." — both halves are wrong after this
    issue. The heading is ## unic-archon-dlc, and "auto-managed" is the framing D4 drops. The
    bullet gains D1's rule in the form D1 states it: the block enumerates no Box and no pipeline
    stage
    — it gives paths on the Consumer's disk, archon workflow list, and a link, and it
    names /unic-archon-dlc:setup alone. Do not write D1's withdrawn falsifiability test into
    AGENTS.md: it bans three lines the block is required to carry.

  • CONTEXT.md names the new heading in both places it calls the block ## Agent skills — the
    Setup glossary entry and the Setup line under ## Relationships.

  • AGENTS.md and CONTEXT.md stop listing /handoff inside this Plugin's own off-line Box set.
    Both opening paragraphs name it the way README.md:53 already does: one of Matt's skills,
    referenced in prose and never implemented here. The doctrine bullet that reads "the /handoff
    command/skill" gains the same qualifier. Do not add commands/handoff.md: a wrapper that
    adds nothing to a Method fails ADR-0021.

  • docs/adr/0024-triage-intake-on-ramp.md records that its known item is settled. The item, a
    bullet under ## Consequences at :97-99, reads "the block-ownership overlap remains for a
    later /setup/finalize step". The heading rename is that step, so the sentence stops being true
    the moment this merges. Four edits, across two files, and no others:

    1. **Append a dated `> **Amended (YYYY-MM-DD):**` blockquote** to
       `docs/adr/0024-triage-intake-on-ramp.md`, below the one the file already carries at `:5`,
       dated the day the change lands, saying that this issue performs the later step the known item
       waits on and that `/setup` now writes a `## unic-archon-dlc` block.
    2. **Extend the bare status line** at `docs/adr/0024-…:3` —
       `**Status:** Accepted (2026-07-02)` — in the form its siblings use:
       `; amended YYYY-MM-DD — <what>`, plain text, no anchor link. `ADR-0023:3` and `ADR-0026:3`
       are the worked examples.
    3. **Mark the row in the ADR index**, `docs/adr/README.md`, whose 0024 entry reads `Accepted`.
       Every plugin ADR whose own status line records an amendment also carries it in that column.
       The five, from the plugin root — file order is `ugrep`'s and means nothing, the set is the
       claim:
    
       ```
       $ grep -rln '^\*\*Status:\*\*.*amended' docs/adr/
       docs/adr/0023-build-generic-red-green-refactor-loop.md
       docs/adr/0021-earns-its-place-compose-verbatim.md
       docs/adr/0026-pr-review-generic-archon-harvest.md
       docs/adr/0029-explore-research-spike-onramp.md
       docs/adr/0016-dlc-thin-process-layer.md
       EXIT=0
       ```
    
       All five carry `amended` in their index row: `Accepted; amended by ADR-0030` for 0016 and
       0021, `Accepted (amended #281)` for 0023, 0026 and 0029. Extending 0024's status line without
       its row makes 0024 the sole exception — the drift `docs/process/ai-development.md` §6 forbids,
       and the same drift this criterion exists to close. Use the `Accepted (amended #296)` form.
    4. **Write the format exception down** in `docs/adr/README.md`, beside the sentence at `:3` that
       imports the root's rules — "See the root `docs/adr/README.md` for format and numbering
       conventions." One sentence is enough, and it must set a rule going forward rather than
       describe the tree as it stands: amendments recorded in this plugin's ADRs **from this point**
       take the `> **Amended (YYYY-MM-DD):**` blockquote plus an extended status line, not the
       root's `## Amendment (YYYY-MM)` section. Do not write it as a summary of what the existing
       files already do — they do not, as the paragraph below records — and the sentence has to be
       true the day it lands and stay true as later amendments follow it. Without it the next
       amender reads the import sentence, follows the root README, and nothing in the tree
       contradicts them.
    
       _Drafter's call, the wording. Forward-looking, because a descriptive sentence would assert a
       practice no plugin ADR follows today, leaving an index that claims a shape the tree does not
       have — the defect class this issue exists to delete. The maintainer considered dropping edit
       4 and filing the convention as its own ticket, and rejected it: the import sentence at `:3`
       sends the next amender to the root form today, and nothing else in this ticket closes that._
    
    **Why the plugin shape and not root `docs/adr/README.md:34`'s.** The root README prescribes a
    dated `## Amendment (YYYY-MM)` **section** and a status line ending
    `see [Amendment](#amendment-yyyy-mm)`. Because the plugin README imports the root's conventions,
    choosing otherwise is an exception rather than a gap — which is what edit 4 records. The case for
    it is that no plugin ADR follows the root form and thirteen amendment notes follow another: from
    the plugin root, `grep -rn '^## Amendment' docs/adr/` returns nothing and exits 1, while
    `grep -rn '^> \*\*Amended' docs/adr/` returns thirteen lines across eleven files, exit 0. **Nine
    of those files** — 0015, 0016, 0017, 0018, 0019, 0020, 0022, 0024, 0027 — carry the blockquote
    directly under the status line and above `## Context`, which is the placement edit 1 prescribes.
    The other two hits sit mid-body, below their own `## Context`: `0023:45`, and `0026:62` with
    `0026:77`. Those are the same two ADRs edit 2 cites for its status-line form, so read 0023 and
    0026 for the status line and read the nine for the placement.
    
    No plugin ADR yet pairs both halves exactly as prescribed. 0016 has a top blockquote and a status
    line reading `; amended by [ADR-0030](…)`, not a date. 0021 and 0029 have an amended status line
    and no `> **Amended` blockquote at all. 0023 and 0026 have the dated status-line form with the
    blockquote mid-body. Each half is established practice here; the pairing is new. From the repo
    root, `grep -rn '^## Amendment' docs/adr/` returns `docs/adr/0032-label-taxonomy.md:83` and
    `:118`, exit 0 — the section shape exists, in root ADRs only. Writing the root form here would
    leave `see [Amendment](#amendment-2026-08)` pointing at a heading no plugin ADR has unless the
    implementer also creates it: a dangling pointer, which is the defect class this issue exists to
    delete.
    
    **Leave the `## Consequences` bullet at `:97-99` standing, word for word.** Inside
    `docs/adr/0024-triage-intake-on-ramp.md`, Context, Decision and Consequences all stay as written
    on 2026-07-02; the new blockquote and the status line are the whole change to that file, and edits
    3 and 4 touch only `docs/adr/README.md`. The blockquote is what says the item is settled, and it
    names this issue.
    _Drafter's call, three times over. **One:** the plugin's blockquote shape rather than the root
    README's section, because nine plugin ADRs place a blockquote where edit 1 puts one and none uses
    the section. The maintainer may overturn it to the root shape, which then means writing the
    `## Amendment (YYYY-MM)` heading so the anchor resolves, and dropping edit 4. **Two:** leaving the
    `## Consequences` bullet standing rather than editing it, because the plugin's pattern adds notes
    and never rewrites body text. The maintainer may overturn it to editing the bullet in place to say
    the overlap is resolved. **Three:** edit 3 permits the index row rather than accepting the drift.
    The maintainer may overturn it and drop edit 3, at the price of one ADR whose status line and
    index row disagree._
    _Drafter's call, carried from the round-2 amendment and unchanged: a criterion rather than a note
    in `## Out of scope`. `docs/process/ai-development.md` §6 says "Never let ADRs drift", and the
    known item is a forward-looking TODO this issue completes, not a record of a past decision —
    leaving it makes the ADR false rather than historical. The maintainer may overturn it: ADR-0027
    gives `/improve-architecture` the ADR-superseding job and could pick this up in its next pass._
    
  • pnpm --filter unic-archon-dlc bump minor is run and CHANGELOG.md carries a dated entry
    naming both deletions.

Out of scope

  • Any new test over the block. D5. No lib/ renderer, and no new grep over commands/setup.md
    prose. This bans additions only. The grep that already exists —
    test/config-schema.test.mjs:511-532, whose third assertion reads Step 7 — is not in scope to
    remove, weaken or retarget; AC3 requires it to keep passing on the rewritten prose.
  • Detecting a hand-edited block. D4. feat(unic-archon-dlc): /setup never says which version it upgraded from, or which Boxes are new #295 builds no hash store, and there is nothing left in the
    block worth protecting.
  • An ADR for D1's rule. It goes in the plugin's AGENTS.md doctrine, beside the bullet that
    already owns this block. A five-line static block is not a hard-to-reverse decision. This does not
    cover ADR-0024's known item, which is a criterion above.
  • commands/triage.md's three docs/agents/* references. They are ADR-0024's single-source rule
    working as designed — /triage composes Matt's triage Method but is forbidden to read his
    docs/agents/triage-labels.md / issue-tracker.md, so it must name the files it refuses. Deleting
    them would delete the prohibition. This is why the grep criterion above is scoped to
    commands/setup.md.
  • docs/agents/*.md in this monorepo. Repo-owned since root ADR-0033; /setup never runs here.
  • The historical references to handoff-generator in docs/adr/0018-… and
    docs/redesign/PLAN.md.
    Both are records of a past decision and stay accurate as history. Unlike
    ADR-0024's known item, neither promises a future step this issue performs.

Body rewritten 2026-08-13 in a /grill-with-docs session with the maintainer, replacing the
2026-08-11 spec. Amended 2026-08-13 against the pre-dispatch audits in four rounds — seven findings,
then four, then three, then six. The comments below are the audits and amendments, oldest first.

Metadata

Metadata

Assignees

Labels

app:unic-archon-dlcclosedPR has been mergedp2Medium prioritytech-debtInternal restructuring; no behaviour change

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions