diff --git a/apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-build.yaml b/apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-build.yaml index 6a5b1396..95c2f6e9 100644 --- a/apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-build.yaml +++ b/apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-build.yaml @@ -4,16 +4,15 @@ description: > implements every slice test-first with structural anti-cheating: a single generic loop advances each slice through two FRESH-context phases — RED (write a provably-failing test) and GREEN (minimum implementation) — serially in dependency order. The baton between phases is artefacts on - disk (committed test, committed impl), never session memory (ADR-0012). Procedure comes from the + disk (committed test, committed impl), never session memory. Procedure comes from the `tdd` and `implement` Methods, read by path from `.archon/methods/`; refactoring is deliberately NOT in the loop — `tdd` puts it in the review stage, so it lives in /pr-review's `code-review` - Fowler smells (#281, amending ADR-0023). Then a local non-posting code-review pre-check, verify, + Fowler smells. Then a local non-posting code-review pre-check, verify, goals-check, evidence, report, and a commit and push of the work on every verdict. Only a "pass" verdict opens a PR to the run's base branch, Archon's $BASE_BRANCH, and gates it; any other - verdict cancels the run with the work on the pushed branch - (ADR-0011/0022/0023/0030/0031/0039/0040). + verdict cancels the run with the work on the pushed branch. -# Required at the workflow level so the build-pr-gate approval message reaches the user (ADR-0011). +# Required at the workflow level so the build-pr-gate approval message reaches the user. interactive: true # The engine refuses terminal `completed` unless $ARTIFACTS_DIR/evidence.json exists. The @@ -21,16 +20,16 @@ interactive: true # policy no longer refuses a red run. Two guards cover `evidence` ending without writing. # push-branch refuses a Session mirror that is missing at HEAD, so the run ends `failed`. This # policy catches the one case left: the mirror is committed but the $ARTIFACTS_DIR copy is absent. -# The verdict decides how the run ends, at guard-not-pass and open-pr (ADR-0034, ADR-0040). +# The verdict decides how the run ends, at guard-not-pass and open-pr. evidence_policy: required: true nodes: # --------------------------------------------------------------------------------------------- # bootstrap — parse the slug from $ARGUMENTS, read config, confirm issues.json exists. - # A prompt node (NOT a script) so it needs no plugin-lib import and no $CLAUDE_PLUGIN_ROOT - # (ADR-0023 §5): the agent reads .archon/unic-dlc.config.yaml with its own tools. It also passes the - # whole `sdlc_needs` block downstream and runs the declared install once for the run (#430). + # A prompt node (NOT a script) so it needs no plugin-lib import and no $CLAUDE_PLUGIN_ROOT: + # the agent reads .archon/unic-dlc.config.yaml with its own tools. It also passes the + # whole `sdlc_needs` block downstream and runs the declared install once for the run. # --------------------------------------------------------------------------------------------- - id: bootstrap depends_on: [] @@ -116,7 +115,7 @@ nodes: required: [status, slug, artifacts_dir, gate, sdlc_needs, install_report, message] # --------------------------------------------------------------------------------------------- - # guard — expected precondition failures cancel cleanly (ADR-0011 / schema: cancel vs fail). One + # guard — expected precondition failures cancel cleanly. One # guard, because there is no repository to resolve: `docs/agents/issue-tracker.md` names it. # --------------------------------------------------------------------------------------------- - id: guard-not-ready @@ -129,15 +128,13 @@ nodes: # --------------------------------------------------------------------------------------------- # slopcheck — verify every NEW package against the npm registry before any code runs. - # Self-contained (ADR-0023 §5): imports nothing from the plugin. It once mirrored a tested - # lib/slopcheck.mjs in the unic-archon-dlc Plugin's own tree; #381 deleted that module, so the path - # is history and resolves nowhere in either repository, and this node is the only copy of the gate. + # Self-contained: imports nothing from the plugin. This node is the only copy of the gate. # --------------------------------------------------------------------------------------------- - id: slopcheck depends_on: [bootstrap] when: "$bootstrap.output.status == 'ready'" # always_run: true — a resume must re-verify package.json's CURRENT contents; exit 0 says - # nothing about packages added since the last completed attempt (ADR-0033). + # nothing about packages added since the last completed attempt. always_run: true runtime: bun timeout: 120000 @@ -213,11 +210,11 @@ nodes: # --------------------------------------------------------------------------------------------- # run-build — THE keystone. One fresh session per iteration advances ONE slice by ONE phase. - # Red and green never share a session; the baton is committed artefacts + build-state.json - # (ADR-0012 / ADR-0023). Serial in the dependency order already baked into issues.json. + # Red and green never share a session; the baton is committed artefacts + build-state.json. + # Serial in the dependency order already baked into issues.json. # # The loop's PROCEDURE is not written here: `tdd` and `implement` own it, read by path from - # `.archon/methods/` (ADR-0030/0031). What stays below is Harness-only — the exit-code anti-cheat + # `.archon/methods/`. What stays below is Harness-only — the exit-code anti-cheat # proof, the per-phase commit convention and build-state.json, none of which a Method can supply. # --------------------------------------------------------------------------------------------- - id: run-build @@ -244,8 +241,8 @@ nodes: `.archon/methods/tdd/mocking.md` - `.archon/methods/implement/SKILL.md` Read them at those literal paths and import nothing: an Archon node cannot import anything - from the Plugin (ADR-0023 §5), and the config / `.local` override tiers are retired - (ADR-0031, amended). If a file is missing, that is FATAL for this + from the Plugin, and the config / `.local` override tiers are retired. + If a file is missing, that is FATAL for this node — print "tdd/implement Method not found under .archon/methods/ — run /unic-archon-dlc:setup" and stop. Do not proceed from memory of what these Methods say. @@ -267,11 +264,11 @@ nodes: `docs/agents/issue-tracker.md` is absent. `/unic-archon-dlc:setup` owns that file and `docs/agents/triage-labels.md`, and `setup-matt-pocock-skills` is not a Plugin dependency — a run writes another host's template over the first and reverts the second to a five-role - vocabulary (ADR-0024). Never run it. If either file is missing, say so and stop. + vocabulary. Never run it. If either file is missing, say so and stop. Note what `tdd` says about refactoring: it is NOT part of the red → green loop, it belongs to the review stage. This loop therefore has no REFACTOR phase — /pr-review's `code-review` axis - carries the Fowler smell baseline instead (#281). + carries the Fowler smell baseline instead. ## Step 1 — Load state Read issues.json (an ordered array; blockers come first — honour that order). @@ -308,7 +305,7 @@ nodes: PR. The node that commits the Session artefacts after `report` commits it ONCE. That single commit is the durable proof of this loop's anti-cheat record (`red_exit`, `red_unexpected_pass`, the per-slice phase order), which otherwise dies when `/cleanup` - prunes this worktree (ADR-0012). + prunes this worktree. After each `git add`, run `git status --porcelain` and confirm the staged set is exactly the file(s) you named. Unstage anything else with `git restore --staged ` before committing. @@ -361,10 +358,10 @@ nodes: # --------------------------------------------------------------------------------------------- # implement-review-precheck — realises `implement`'s closing "once done, use /code-review" step, # once, after the whole loop. A LOCAL PRE-CHECK THAT POSTS NOTHING, so /pr-review keeps sole posting - # authority (#281 AC 4). Its prose `findings` go into report.md. Its `status` and `hard_findings` + # authority. Its prose `findings` go into report.md. Its `status` and `hard_findings` # are gate inputs that `evidence` reads, and its `notes` reach evidence.json and the pull request - # description (ADR-0034). Runs `code-review`'s own two-axis parallelism internally rather than the - # Harness re-implementing it (ADR-0030). + # description. Runs `code-review`'s own two-axis parallelism internally rather than the + # Harness re-implementing it. # --------------------------------------------------------------------------------------------- - id: implement-review-precheck depends_on: [run-build] @@ -374,8 +371,8 @@ nodes: You are the implement-review-precheck node of /build for slug "$bootstrap.output.slug". Read `.archon/methods/code-review/SKILL.md` in full, by that literal repo-relative path. That is the - one path a Method lives at: an Archon node cannot import anything from the Plugin (ADR-0023 §5), - and the config and `.local` override tiers are retired (ADR-0031, amended). If the file is missing that + one path a Method lives at: an Archon node cannot import anything from the Plugin, + and the config and `.local` override tiers are retired. If the file is missing that is FATAL for this node: print "code-review Method not found at .archon/methods/code-review/SKILL.md — run /unic-archon-dlc:setup" and stop. @@ -405,14 +402,14 @@ nodes: - **The "/setup-matt-pocock-skills if `docs/agents/issue-tracker.md` is missing" fallback never applies.** `/unic-archon-dlc:setup` owns that file and `docs/agents/triage-labels.md`, and `setup-matt-pocock-skills` is not a Plugin dependency — a run writes another host's template over - the first and reverts the second to a five-role vocabulary (ADR-0024). Never run it. + the first and reverts the second to a five-role vocabulary. Never run it. ## The tracker contract `docs/agents/issue-tracker.md` and `docs/agents/triage-labels.md` in this repository are the tracker contract. This node needs the first. Read it before the first tracker call. - **Access** — its § Access names the MCP server or skill that serves this tracker. Read that server's own current tool list and build every call from it. Write no command, subcommand or - flag here and name no provider: the DLC owns the what and none of the how (ADR-0016), and a + flag here and name no provider: the DLC owns the what and none of the how, and a flag table frozen in this file is stale the moment the tool changes. - **Addressing** — its § Addressing names the repository this run acts on. Name that repository explicitly in every call, and derive nothing from a remote URL. @@ -506,13 +503,12 @@ nodes: required: [findings, status, blocked_reason, hard_findings, notes] # --------------------------------------------------------------------------------------------- - # verification — full suite + stub scan on the diff. Self-contained prompt (ADR-0023 §5). + # verification — full suite + stub scan on the diff. Self-contained prompt. # --------------------------------------------------------------------------------------------- - id: verification depends_on: [implement-review-precheck] # always_run: true — the exit code is a prose report, not a promise; a resume must re-run the - # suite against the CURRENT tree, never replay a cached PASSED from before a since-applied fix - # (ADR-0033). + # suite against the CURRENT tree, never replay a cached PASSED from before a since-applied fix. always_run: true context: fresh allowed_tools: [Read, Bash, Glob, Grep] @@ -620,7 +616,7 @@ nodes: - id: goals-check depends_on: [verification] # always_run: true — same reason as verification: the coverage matrix is a fact about the - # CURRENT diff, and a resume must recompute it rather than reuse a cached verdict (ADR-0033). + # CURRENT diff, and a resume must recompute it rather than reuse a cached verdict. always_run: true context: fresh allowed_tools: [Read, Bash, Glob, Grep] @@ -662,19 +658,18 @@ nodes: # failures that produced it, and prints the verdict as JSON on stdout. It reads verification, # goals-check and implement-review-precheck. A pre-check hard finding is a `fail`. A pre-check # that did not run is `unresolved` when nothing else failed. guard-not-pass and open-pr branch on - # that printed verdict; workflow-level evidence_policy checks only that the file exists (ADR-0034, - # ADR-0040). A SCRIPT, never a prompt, because a prompt that both judges and certifies grades its + # that printed verdict; workflow-level evidence_policy checks only that the file exists. + # A SCRIPT, never a prompt, because a prompt that both judges and certifies grades its # own homework. # always_run: true, because its exit code is a write op, not a verdict. A resumed run must # re-derive the verdict from the CURRENT verification, goals-check and pre-check output, never - # trust a stale file (also why it deletes any existing evidence.json first, below) - # (ADR-0033/0034). + # trust a stale file (also why it deletes any existing evidence.json first, below). # The pre-check arrives through `with:`, never through the script source. A node-output reference # in the source substitutes raw, so a pre-check string holding a quote would end this script with # a syntax error. Each `with:` binding reaches the script as an INPUTS_ environment # variable, so no pre-check text is ever parsed as code. This node's `with:` binds only the four # fields it reads, never `findings`, so the prose `findings` never counts against the environment - # size limit (ADR-0034, measured on 0.12.1). `with:` on a script node needs Archon >= 0.10.0. + # size limit (measured on 0.12.1). `with:` on a script node needs Archon >= 0.10.0. # --------------------------------------------------------------------------------------------- - id: evidence depends_on: [implement-review-precheck, verification, goals-check] @@ -696,12 +691,12 @@ nodes: // not throw, so this node logs "wrote evidence.json" while the engine's presence gate reads // the real ARTIFACTS_DIR and finds nothing — a run failing closed with a success line in its // log. Do NOT fall back to the Session dir: the gate reads only this path, so a fallback - // would make that silent case permanent (ADR-0033/0034). + // would make that silent case permanent. const artifactsDir = process.env.ARTIFACTS_DIR if (!artifactsDir) { console.error( 'evidence: ARTIFACTS_DIR is unset or empty — the engine did not export it to this script node. ' + - 'The evidence gate requires Archon >= 0.7.0 (ADR-0033/0034).' + 'The evidence gate requires Archon >= 0.7.0.' ) process.exit(1) } @@ -724,7 +719,7 @@ nodes: // (Never write a placeholder node id anywhere in this body, comments included. The DAG // loader reads every dollar-prefixed node-output token here as a real edge, so a placeholder // makes the whole Box fail to load with "references unknown node". A comment on this very - // spot once did exactly that. Nothing guards it now — read for it (#381).) + // spot once did exactly that. Nothing guards it now — read for it.) const verificationPassed = $verification.output.passed const goalsCheckPassed = $goals-check.output.passed const verificationFailures = $verification.output.failures @@ -735,12 +730,12 @@ nodes: // `passed: true` with a non-empty `failures` array write a certificate whose own body listed // the failures. Both prompts define `failures` as blockers only, so a non-empty list is a // red verdict whatever the boolean says. This does not make the gate independent of the - // judge — only re-running the suite would, and ADR-0023 §5 rules that out (ADR-0034). + // judge. Only re-running the suite would do that. const verificationGreen = verificationPassed === true && verificationFailures.length === 0 const goalsCheckGreen = goalsCheckPassed === true && goalsCheckFailures.length === 0 // A check that could not run is `unresolved`, and unresolved is never a pass: an absent result - // and a green result are not the same fact (#430). `test` is the only need whose outcome is + // and a green result are not the same fact. `test` is the only need whose outcome is // mandatory here — every other need reports and none of them holds this gate. const testOutcome = '$verification.output.test_outcome' const unresolvedNeeds = $verification.output.unresolved_needs @@ -821,7 +816,7 @@ nodes: // `when:` expression with nowhere to put a parse failure. Three readers: the `when:` of // guard-not-pass, the `when:` of open-pr, and the cancel message of guard-not-pass, which names // the verdict. Both `when:` expressions compare the `verdict` field with 'pass' and nothing - // else, so `fail` and `unresolved` take the same branch (ADR-0040). + // else, so `fail` and `unresolved` take the same branch. console.log(JSON.stringify({ verdict: verdictState, test_outcome: testOutcome, unresolved_needs: unresolvedNeeds })) console.error(`evidence: verdict=${verdictState} verification(passed=${verificationPassed}, failures=${verificationFailures.length}, test=${testOutcome}) goals-check(passed=${goalsCheckPassed}, failures=${goalsCheckFailures.length}) precheck(status=${precheckStatus}, hard=${hardFindings.length}, notes=${precheckNotes.length})`) @@ -832,7 +827,7 @@ nodes: // arrays and `hard_findings` are the reason for a `fail`. `test_outcome` with // `unresolved_needs`, and `precheck_status` with `precheck_blocked_reason`, are the reason for // an `unresolved`; a null `precheck_status` means this node could not read the pre-check. - // Never return before this write (ADR-0040). + // Never return before this write. const evidence = { slug: '$bootstrap.output.slug', verdict: verdictState, @@ -906,7 +901,7 @@ nodes: # --------------------------------------------------------------------------------------------- # commit-session — runs on EVERY verdict. Stages the named paths and commits them, so the work and - # the Session artefacts are committed before the verdict decides anything (ADR-0040). A prompt, + # the Session artefacts are committed before the verdict decides anything. A prompt, # because telling the loop's uncommitted source and test files from scratch files is a judgement. # --------------------------------------------------------------------------------------------- - id: commit-session @@ -940,7 +935,7 @@ nodes: SESSION/build-state.json is committed HERE and ONLY here — the loop never commits it. This one commit is the durable proof of the loop's anti-cheat record (`red_exit`, `red_unexpected_pass`, the per-slice phase order), which otherwise dies when `/cleanup` - prunes this worktree (ADR-0012). + prunes this worktree. ## Staging — named paths only Run one `git add ` per path in the list above. NEVER `git add -A`, `git add .` or @@ -967,8 +962,8 @@ nodes: # build-state.json and evidence.json. A miss has two causes. commit-session did not commit, which a # prompt node cannot report by failing. Or a resumed run re-ran `evidence` after the commit and the # rewritten evidence.json differs, which needs a new run. It prints `git status --porcelain` to stderr before the push. Archon 0.12.1 - # substitutes $BASE_BRANCH in a bash body (measured for #439). Its stdout is JSON only, read field - # by field by guard-not-pass and open-pr. git's own lines go to stderr (ADR-0040). + # substitutes $BASE_BRANCH in a bash body. Its stdout is JSON only, read field + # by field by guard-not-pass and open-pr. git's own lines go to stderr. # --------------------------------------------------------------------------------------------- - id: push-branch depends_on: [commit-session] @@ -1009,7 +1004,7 @@ nodes: # guard-not-pass — the sibling of open-pr. Its `when` is the exact negation of open-pr's, and both # compare the verdict with 'pass' only, so `fail` and `unresolved` both end here and no third # branch exists. It opens no pull request and writes nothing to the tracker. It ends the run - # `cancelled`, with the work already on the branch push-branch pushed (ADR-0040). + # `cancelled`, with the work already on the branch push-branch pushed. # --------------------------------------------------------------------------------------------- - id: guard-not-pass depends_on: [push-branch] @@ -1024,7 +1019,7 @@ nodes: # --------------------------------------------------------------------------------------------- # open-pr — the sibling of guard-not-pass. It runs only on a "pass" verdict. It sets no trigger # rule. On any other verdict it is skipped, and so is build-pr-gate below. It stages and commits - # nothing. It opens the pull request from the pushed branch and links it (ADR-0040). + # nothing. It opens the pull request from the pushed branch and links it. # --------------------------------------------------------------------------------------------- - id: open-pr depends_on: [push-branch] @@ -1046,7 +1041,7 @@ nodes: tracker contract. This node needs the first. Read it before the first tracker call. - **Access** — its § Access names the MCP server or skill that serves this tracker. Read that server's own current tool list and build every call from it. Write no command, subcommand or - flag here and name no provider: the DLC owns the what and none of the how (ADR-0016), and a + flag here and name no provider: the DLC owns the what and none of the how, and a flag table frozen in this file is stale the moment the tool changes. - **Addressing** — its § Addressing names the repository this run acts on. Name that repository explicitly in every call, and derive nothing from a remote URL. @@ -1092,8 +1087,8 @@ nodes: - id: build-pr-gate depends_on: [open-pr] when: "$bootstrap.output.gate == 'hitl'" - # Archon 0.12.1 substitutes node outputs in an approval message but not $BASE_BRANCH (measured - # on #505), so this message names the base through bootstrap's message, which starts with it. + # Archon 0.12.1 substitutes node outputs in an approval message but not $BASE_BRANCH, so + # this message names the base through bootstrap's message, which starts with it. approval: message: > Build implementation, goals-check matrix, and report are ready. $bootstrap.output.message diff --git a/apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-explore.yaml b/apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-explore.yaml index 1f3c633d..cb2e1e17 100644 --- a/apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-explore.yaml +++ b/apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-explore.yaml @@ -4,19 +4,19 @@ description: > / pitfalls) → synthesize into //findings.md → one AFK spike (verdicts) → file a spike ticket → optionally preserve the spike code on a branch. findings.md is the /specs baton: its Integrated Brief carries three named lenses (Domain Model / Established Decisions / Prior Research) - that /specs' load-context reads verbatim. Never required; a precursor to /specs, off the main line - (PLAN decision #3/#8). Ported to the key-discriminated node schema (ADR-0011); self-contained prompt - nodes, no plugin-lib import (ADR-0023 §5); artefacts at // (ADR-0015). Interactive + that /specs' load-context reads verbatim. Never required; a precursor to /specs, off the main line. + Ported to the key-discriminated node schema; self-contained prompt + nodes, no plugin-lib import; artefacts at //. Interactive prototyping stays Matt's /prototype skill (referenced, never invoked — nodes have no live - conversation). See ADR-0029. + conversation). -# Required at the workflow level so the spike-branch approval message reaches the user (ADR-0011). +# Required at the workflow level so the spike-branch approval message reaches the user. interactive: true nodes: # --------------------------------------------------------------------------------------------- # bootstrap — parse the slug from $ARGUMENTS, read config. A prompt node (NOT a script) so it needs - # no plugin-lib import and no $CLAUDE_PLUGIN_ROOT (ADR-0023 §5): the agent reads + # no plugin-lib import and no $CLAUDE_PLUGIN_ROOT: the agent reads # .archon/unic-dlc.config.yaml with its own tools. No PRD precondition — /explore WRITES findings.md, # it is not a consumer of a prior baton. # --------------------------------------------------------------------------------------------- @@ -63,7 +63,7 @@ nodes: required: [status, slug, artifacts_dir, gate, branching, message] # --------------------------------------------------------------------------------------------- - # guard — expected precondition failures cancel cleanly (ADR-0011: cancel vs fail). One guard, + # guard — expected precondition failures cancel cleanly. One guard, # because there is no repository to resolve: `docs/agents/issue-tracker.md` names it. # --------------------------------------------------------------------------------------------- - id: guard-not-ready @@ -89,8 +89,8 @@ nodes: Goal: understand the technology stack of this project. Read `.archon/methods/research/SKILL.md` in full, by that literal repo-relative path. That is the - one path a Method lives at: an Archon node cannot import anything from the Plugin (ADR-0023 §5), - and the config and `.local` override tiers are retired (ADR-0031, amended). If it is missing that is FATAL for this node: + one path a Method lives at: an Archon node cannot import anything from the Plugin, + and the config and `.local` override tiers are retired. If it is missing that is FATAL for this node: print "research Method not found at .archon/methods/research/SKILL.md — run /unic-archon-dlc:setup" and stop. The Method opens by spinning up a background agent to do the reading; this node's own fresh-context execution IS that agent, so do not spawn another. Apply its @@ -126,8 +126,8 @@ nodes: Goal: identify the key features and capabilities of this project. Read `.archon/methods/research/SKILL.md` in full, by that literal repo-relative path. That is the - one path a Method lives at: an Archon node cannot import anything from the Plugin (ADR-0023 §5), - and the config and `.local` override tiers are retired (ADR-0031, amended). If it is missing that is FATAL for this node: + one path a Method lives at: an Archon node cannot import anything from the Plugin, + and the config and `.local` override tiers are retired. If it is missing that is FATAL for this node: print "research Method not found at .archon/methods/research/SKILL.md — run /unic-archon-dlc:setup" and stop. The Method opens by spinning up a background agent to do the reading; this node's own fresh-context execution IS that agent, so do not spawn another. Apply its @@ -166,8 +166,8 @@ nodes: Goal: understand the structural and architectural decisions of this project. Read `.archon/methods/research/SKILL.md` in full, by that literal repo-relative path. That is the - one path a Method lives at: an Archon node cannot import anything from the Plugin (ADR-0023 §5), - and the config and `.local` override tiers are retired (ADR-0031, amended). If it is missing that is FATAL for this node: + one path a Method lives at: an Archon node cannot import anything from the Plugin, + and the config and `.local` override tiers are retired. If it is missing that is FATAL for this node: print "research Method not found at .archon/methods/research/SKILL.md — run /unic-archon-dlc:setup" and stop. The Method opens by spinning up a background agent to do the reading; this node's own fresh-context execution IS that agent, so do not spawn another. Apply its @@ -192,7 +192,7 @@ nodes: required: [findings] # --------------------------------------------------------------------------------------------- - # research-pitfalls — parallel research dimension 4 of 4. (HANDOFF.md is retired — ADR-0013 — so it + # research-pitfalls — parallel research dimension 4 of 4. (HANDOFF.md is retired, so it # is no longer a source here.) # --------------------------------------------------------------------------------------------- - id: research-pitfalls @@ -206,8 +206,8 @@ nodes: Goal: surface known pitfalls, edge cases, and areas of technical debt. Read `.archon/methods/research/SKILL.md` in full, by that literal repo-relative path. That is the - one path a Method lives at: an Archon node cannot import anything from the Plugin (ADR-0023 §5), - and the config and `.local` override tiers are retired (ADR-0031, amended). If it is missing that is FATAL for this node: + one path a Method lives at: an Archon node cannot import anything from the Plugin, + and the config and `.local` override tiers are retired. If it is missing that is FATAL for this node: print "research Method not found at .archon/methods/research/SKILL.md — run /unic-archon-dlc:setup" and stop. The Method opens by spinning up a background agent to do the reading; this node's own fresh-context execution IS that agent, so do not spawn another. Apply its @@ -231,9 +231,9 @@ nodes: # --------------------------------------------------------------------------------------------- # synthesize — depends on all four research nodes; writes //findings.md directly - # with the Write tool (ADR-0023 §5 — no findings-writer lib). The Integrated Brief is written as THREE + # with the Write tool (no findings-writer lib). The Integrated Brief is written as THREE # explicitly-named lenses (Domain Model / Established Decisions / Prior Research) that /specs' - # load-context reads verbatim (ADR-0029) — this is the /explore → /specs contract. + # load-context reads verbatim — this is the /explore → /specs contract. # --------------------------------------------------------------------------------------------- - id: synthesize depends_on: [research-stack, research-features, research-architecture, research-pitfalls] @@ -296,8 +296,8 @@ nodes: # spike — one AFK experiment pass. Build/measure a throwaway experiment where AFK-feasible, else # reason it through; assign exactly one verdict per unknown and APPEND a "## Spike verdicts" section # to findings.md (Edit/Write — no spike-verdicts lib). Interactive prototyping is NOT done here — it - # is Matt's /prototype skill, which needs a live conversation and so cannot run in an Archon node - # (ADR-0017/0029). This node only references it. + # is Matt's /prototype skill, which needs a live conversation and so cannot run in an Archon node. + # This node only references it. # --------------------------------------------------------------------------------------------- - id: spike depends_on: [synthesize] @@ -351,7 +351,7 @@ nodes: # durable output survives a "discard" (the approval schema only supports on_reject, which # cancels/reworks — it never proceeds past a reject). Reads the tracker contract at # docs/agents/issue-tracker.md and docs/agents/triage-labels.md, which is where every host word - # lives (ADR-0024, amended). + # lives. # --------------------------------------------------------------------------------------------- - id: spike-ticket depends_on: [spike] @@ -371,7 +371,7 @@ nodes: - **Access** — `issue-tracker.md` § Access names the MCP server or skill that serves this tracker. Read that server's own current tool list and build every call from it. Write no command, subcommand or flag here and name no provider: the DLC owns the what and none of the - how (ADR-0016), and a flag table frozen in this file is stale the moment the tool changes. + how, and a flag table frozen in this file is stale the moment the tool changes. - **Addressing** — its § Addressing names the repository this run acts on. Name that repository explicitly in every call, and derive nothing from a remote URL. - **Work-item scope** — its § Work-item scope names the one filter every search applies. Apply diff --git a/apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-pr-review.yaml b/apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-pr-review.yaml index 25f9fde3..e5ca24d0 100644 --- a/apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-pr-review.yaml +++ b/apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-pr-review.yaml @@ -9,17 +9,17 @@ description: > after a config-gated human confirm — posts/updates one structured summary discussion plus per-line discussions on the current PR, through the tracker its contract at `docs/agents/issue-tracker.md` names. Harvests unic-pr-review's review - learnings without its host-specific code or any dependency (ADR-0016/0017). Ported to the key-discriminated node - schema (ADR-0011); inherits /build's self-contained-node conventions (ADR-0023 §5). This Box holds the - only posting authority in the lifecycle. See ADR-0026, ADR-0030, ADR-0031. + learnings without its host-specific code or any dependency. Ported to the key-discriminated node + schema; inherits /build's self-contained-node conventions. This Box holds the + only posting authority in the lifecycle. -# Required at the workflow level so the review-gate approval message reaches the user (ADR-0011). +# Required at the workflow level so the review-gate approval message reaches the user. interactive: true nodes: # --------------------------------------------------------------------------------------------- # bootstrap — parse the slug from $ARGUMENTS, read config. A prompt node (NOT a script) so it needs - # no plugin-lib import and no $CLAUDE_PLUGIN_ROOT (ADR-0023 §5): it reads .archon/unic-dlc.config.yaml + # no plugin-lib import and no $CLAUDE_PLUGIN_ROOT. It reads .archon/unic-dlc.config.yaml # with its own tools. Posting is AFK-safe; the human checkpoint here is the review-gate, and the real # merge gate lives in /qa. # --------------------------------------------------------------------------------------------- @@ -62,11 +62,11 @@ nodes: arrives null stays null. What happens next depends on the node: one that wants that need reports an **unresolved** check, one that does not want it reports nothing at all, and neither fabricates a command — a guessed command reports a result that means nothing. - **This Box runs no build, lint, type-check or test command by instruction** (ADR-0037 §8). It + **This Box runs no build, lint, type-check or test command by instruction**. It carries the block so that `reconcile` can tell the reader which checks the project declares and that this Box instructed none of them. `install` is the exception and is not a check. You run it below, once, because a sub-agent that decides on its own that it needs to run something should - fail on that decision rather than on which worktree the run drew (ADR-0037 §6). + fail on that decision rather than on which worktree the run drew. ## Install once, and say what you did One Archon worktree serves this whole run and may or may not already carry this project's @@ -123,7 +123,7 @@ nodes: required: [status, slug, artifacts_dir, gate, confidence_threshold, inline_comments, sdlc_needs, install_report, message] # --------------------------------------------------------------------------------------------- - # guard — expected precondition failures cancel cleanly (ADR-0011: cancel vs fail). One guard, + # guard — expected precondition failures cancel cleanly. One guard, # because there is no repository to resolve: `docs/agents/issue-tracker.md` names it. # --------------------------------------------------------------------------------------------- - id: guard-not-ready @@ -138,12 +138,12 @@ nodes: # prep — the shared context builder. Identifies the open PR, computes the diff, categorises the # changed files, composes ONE Intent Brief from every available source, detects the prior review # iteration, and writes everything to //pr-review/ so the review node reads it - # off disk (fresh nodes share no memory — ADR-0012/0015). Composing intent once and injecting it into - # both review axes is the primary quality lever (ADR-0026): each axis judges the diff against what the + # off disk (fresh nodes share no memory). Composing intent once and injecting it into + # both review axes is the primary quality lever, because each axis judges the diff against what the # PR is SUPPOSED to do. # # The five changed-file category booleans no longer gate node spawning — the seven conditionally - # spawned aspect nodes collapsed into one always-running `review` node (#281). They stay because they + # spawned aspect nodes collapsed into one always-running `review` node. They stay because they # are durable diff metadata in prep.json that a reader (and a future spawn decision) can use; nothing # reads them today. Retire them or find them a consumer in a follow-up, not in a rewiring slice. # --------------------------------------------------------------------------------------------- @@ -166,7 +166,7 @@ nodes: tracker contract. This node needs the first. Read it before the first tracker call. - **Access** — its § Access names the MCP server or skill that serves this tracker. Read that server's own current tool list and build every call from it. Write no command, subcommand or - flag here and name no provider: the DLC owns the what and none of the how (ADR-0016), and a + flag here and name no provider: the DLC owns the what and none of the how, and a flag table frozen in this file is stale the moment the tool changes. - **Addressing** — its § Addressing names the repository this run acts on. Name that repository explicitly in every call, and derive nothing from a remote URL. @@ -342,9 +342,8 @@ nodes: # and upstream now maintains. The Method implements its own parallelism — its step 4 spawns two # sub-agents — so the Harness delegating to it is the whole point: nothing about running two # sub-agents needs the Harness, and re-implementing step 4 as two Archon nodes is the exact defect - # ADR-0030's structural bar forbids. The Harness keeps what no Method supplies: the Intent Brief, - # the finding contract below, hash-keyed re-review, the config gate and the two posting surfaces - # (#281, amending ADR-0026). + # to avoid, because upstream maintains the Method's procedure and a copy here drifts. The Harness + # keeps only what no Method supplies: the Intent Brief, the finding contract below, hash-keyed re-review, the config gate and the two posting surfaces. # # The finding contract lives in the node's own prompt below, under "## The finding contract". A YAML # comment is not part of a prompt, so a rule stated only here is invisible at run time. Every rule @@ -387,8 +386,8 @@ nodes: and `reconcile` tell the two apart. Read `.archon/methods/code-review/SKILL.md` in full, by that literal repo-relative path. That is the - one path a Method lives at: an Archon node cannot import anything from the Plugin (ADR-0023 §5), - and the config and `.local` override tiers are retired (ADR-0031, amended). If the file is missing that + one path a Method lives at: an Archon node cannot import anything from the Plugin, + and the config and `.local` override tiers are retired. If the file is missing that is FATAL for this node: print "code-review Method not found at .archon/methods/code-review/SKILL.md — run /unic-archon-dlc:setup", write SESSION/findings/review.json as the stop rule above says, and stop. Do not review from @@ -410,13 +409,13 @@ nodes: - **The "/setup-matt-pocock-skills if `docs/agents/issue-tracker.md` is missing" fallback never applies.** `/unic-archon-dlc:setup` owns that file and `docs/agents/triage-labels.md`, and `setup-matt-pocock-skills` is not a Plugin dependency — a run writes another host's template over - the first and reverts the second to a five-role vocabulary (ADR-0024). Never run it. + the first and reverts the second to a five-role vocabulary. Never run it. Then steps 3–5 verbatim: - Step 3: gather this repo's standards sources (CLAUDE.md / AGENTS.md / CONTRIBUTING.md / CODING_STANDARDS.md — whatever exists) and take the Method's twelve-item Fowler smell baseline as written. This baseline is where refactoring now lives: /build's loop has no REFACTOR phase, - because `tdd` puts refactoring in the review stage (#281). + because `tdd` puts refactoring in the review stage. - Step 4: send ONE message with two `Agent` tool calls, `general-purpose` subagent for both. **Paste the twelve-item smell baseline IN FULL into the Standards sub-agent's prompt** — step 4 is explicit that the sub-agent has no other access to it, and an abridged paste silently @@ -642,10 +641,10 @@ nodes: then the one whose `anchored` is "true", then the lexically smallest hash. A prior finding you did not pick stays unmatched, and the rule for an unmatched prior below gives its verdict. Two one-off notes cover the prior iterations already live on real pull requests: - - A prior iteration posted before #281 carries the retired seven aspect names (code-quality, + - A prior iteration posted by an earlier version of this Box carries the retired seven aspect names (code-quality, tests, silent-failure, type-design, comment-rot, simplifier, intent-check) where this run carries "standards" / "spec". Match those on semantic title alone, ignoring the aspect, so - the first re-review after the rewiring does not report every finding as new. + the first re-review after the switch to two axes does not report every finding as new. - A prior iteration posted by a Box older than the anchorable/scoped rule gave a scoped finding an invented `file` — a path that merely sat near the problem. Its prior `file` is a path and this run's is `pull request`, `work item` or `repository`, so they differ by @@ -770,8 +769,7 @@ nodes: never a sub-agent's claim. Then write these parts, in this order: - **This Box instructed none of the project's declared checks**, so nothing in this review verifies a claim that a build, lint, type-check or test passes. That is deliberate, - because running a check against a claim is a Method's procedure, not this Harness's - (ADR-0030). + because running a check against a claim is a Method's procedure, not this Harness's. - Which **checks** the project declares. Name the keys of `$bootstrap.output.sdlc_needs` whose value is set, `install` excluded. Leave `install` out of that sentence. This Box does run it, and the last line reports what happened. Name the keys, never their values, @@ -931,7 +929,7 @@ nodes: writes a review — so read it before the first call. - **Access** — its § Access names the MCP server or skill that serves this tracker. Read that server's own current tool list and build every call from it. Write no command, subcommand or - flag here and name no provider: the DLC owns the what and none of the how (ADR-0016), a flag + flag here and name no provider: the DLC owns the what and none of the how, a flag table frozen in this file is stale the moment the tool changes, and inventing a subcommand is the one defect no test without a live tenant can catch. Ask what the tracker supports; do not assume. diff --git a/apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-qa.yaml b/apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-qa.yaml index 2367adb6..6332a0e5 100644 --- a/apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-qa.yaml +++ b/apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-qa.yaml @@ -3,22 +3,22 @@ description: > QA box + issue-producing on-ramp. Runs after /build's PR is approved: pr-check → test → e2e → coverage-gate → UAT sign-off → verify-pr-base → merge, config-driven and generic. `test` is the floor the merge gate cannot advance without. Every path that does not merge on a result ends cancelled, - never completed (#652). A node that fails ends the run failed. Two human gates (UAT + merge) + never completed. A node that fails ends the run failed. Two human gates (UAT + merge) honour gates.qa — HITL by default, AFK opt-in. When UAT surfaces a defect, it is filed directly as an agent-ready tracker item, through the contract at `docs/agents/issue-tracker.md` and - `docs/agents/triage-labels.md` (ADR-0016/0024), so the finding feeds /tickets rather than only + `docs/agents/triage-labels.md`, so the finding feeds /tickets rather than only halting. Ported to the key-discriminated node - schema (ADR-0011); inherits /build's self-contained-node conventions (ADR-0023 §5). See ADR-0025. + schema; inherits /build's self-contained-node conventions. -# Required at the workflow level so the UAT + merge approval messages reach the user (ADR-0011). +# Required at the workflow level so the UAT + merge approval messages reach the user. interactive: true nodes: # --------------------------------------------------------------------------------------------- # bootstrap — parse the slug from $ARGUMENTS, read config, confirm the QA baton exists. - # A prompt node (NOT a script) so it needs no plugin-lib import and no $CLAUDE_PLUGIN_ROOT - # (ADR-0023 §5): the agent reads .archon/unic-dlc.config.yaml with its own tools. Every command - # comes from the one `sdlc_needs` block (#430); only the coverage threshold still falls back + # A prompt node (NOT a script) so it needs no plugin-lib import and no $CLAUDE_PLUGIN_ROOT. + # The agent reads .archon/unic-dlc.config.yaml with its own tools. Every command + # comes from the one `sdlc_needs` block; only the coverage threshold still falls back # qa.* → build.*, so a team can hold a heavier QA bar than the build's. # --------------------------------------------------------------------------------------------- - id: bootstrap @@ -117,7 +117,7 @@ nodes: required: [status, slug, artifacts_dir, gate, sdlc_needs, install_report, branching, message] # --------------------------------------------------------------------------------------------- - # guard — expected precondition failures cancel cleanly (ADR-0011: cancel vs fail). One guard, + # guard — expected precondition failures cancel cleanly. One guard, # because there is no repository to resolve: `docs/agents/issue-tracker.md` names it, which matters # most here — this is the Box that MERGES. # --------------------------------------------------------------------------------------------- @@ -130,7 +130,7 @@ nodes: needs /specs + /tickets), so the acceptance criteria the UAT checklist reads from exist. # --------------------------------------------------------------------------------------------- - # pr-check — read the PR state before any test runs (#652). A /qa on a branch with no open PR can + # pr-check — read the PR state before any test runs. A /qa on a branch with no open PR can # merge nothing, so it must not spend the test, e2e and coverage runs, and it must not end completed. # `test` runs only on `pr_state == 'open'`, and the cancel below ends the run on every other state. # verify-pr-base reads the state again, because a PR can be merged or closed during UAT. @@ -139,7 +139,7 @@ nodes: depends_on: [bootstrap] when: "$bootstrap.output.status == 'ready'" # always_run: true. The PR state is a fact about the remote, not about this node's exit code. A - # resume must query it again (ADR-0033). + # resume must query it again. always_run: true context: fresh allowed_tools: [Read, Bash] @@ -150,7 +150,7 @@ nodes: `docs/agents/issue-tracker.md` in this repository is the tracker contract. Read it before the query. Its § Access names the MCP server or skill that serves this tracker. Read that server's own current tool list and build the call from it. Write no command, subcommand or flag here, and name - no provider (ADR-0016). Its § Addressing names the repository to query. Name that repository + no provider. Its § Addressing names the repository to query. Name that repository explicitly, and derive nothing from a remote URL. Query the PRs whose head is the current feature branch on that repository, in every state. Set @@ -195,8 +195,8 @@ nodes: PR state: "$pr-check.output.pr_state". $pr-check.output.message # --------------------------------------------------------------------------------------------- - # test — the floor. This Box ran no test suite at all before #430 and merged on an e2e result that - # was almost always a skip. A prompt node (ADR-0023 §5): it reads the declared command from + # test — the floor. An earlier version of this Box ran no test suite and merged on an e2e + # result that was almost always a skip. It is a prompt node that reads the declared command from # bootstrap and runs it with its own tools. It REPORTS a verdict rather than hard-failing, and the # merge `when` below requires that verdict to be `pass` — the one clause there that is not `!= fail`. # --------------------------------------------------------------------------------------------- @@ -204,7 +204,7 @@ nodes: depends_on: [pr-check] when: "$pr-check.output.pr_state == 'open'" # always_run: true — the result is a fact about the CURRENT branch; a resume must re-run it - # rather than replay a cached pass from before the code changed underneath it (ADR-0033). + # rather than replay a cached pass from before the code changed underneath it. always_run: true context: fresh allowed_tools: [Read, Bash] @@ -244,7 +244,7 @@ nodes: depends_on: [test] when: "$bootstrap.output.status == 'ready'" # always_run: true — the result is a fact about the CURRENT branch; a resume must re-run it - # rather than replay a cached pass from before the code changed underneath it (ADR-0033). + # rather than replay a cached pass from before the code changed underneath it. always_run: true context: fresh allowed_tools: [Read, Bash] @@ -278,13 +278,13 @@ nodes: # --------------------------------------------------------------------------------------------- # coverage-gate — enforce the coverage threshold against a declared coverage command. It wants a - # figure always, so a null on either is `unresolved`, never a skip — `skip` left this enum with #430. + # figure always, so a null on either is `unresolved`, never a skip. This enum has no `skip`. # Reports a verdict like e2e (fail-closes the merge `when`, never hard-fails the run). # --------------------------------------------------------------------------------------------- - id: coverage-gate depends_on: [e2e] # always_run: true — same reason as e2e: coverage is a fact about the CURRENT tree, not a - # promise carried by exit code 0 (ADR-0033). + # promise carried by exit code 0. always_run: true context: fresh allowed_tools: [Read, Bash] @@ -386,7 +386,7 @@ nodes: # --------------------------------------------------------------------------------------------- # uat-gate — HITL by default; skipped when gates.qa == afk. On REJECT, on_reject captures the - # failing criteria as agent-ready tracker issues (finding-capture, ADR-0025) BEFORE the run halts, + # failing criteria as agent-ready tracker issues (finding-capture) BEFORE the run halts, # so the defect is durably tracked and feeds /tickets — not lost when the workflow cancels. # max_attempts: 1 → capture once, then a second reject cancels the run. # @@ -394,9 +394,7 @@ nodes: # blocked by / additional context) and the thin-issues heuristic above it were originally Matt # Pocock's `qa` Method. Upstream v1.1.0 moved `qa` to `skills/deprecated/` with no replacement, so # there is nothing left to resolve by name: the shape is inlined verbatim here and this Harness owns - # it from now on. It is deliberately absent from the Method table in the `unic-archon-dlc` Plugin's - # own README.md § Dependencies — not this repository's README, which is a Consumer's — because an - # entry there would point at a dead upstream branch (#281, #381, #401). + # it from now on. It is deliberately not a listed Method, because its upstream branch is gone. # --------------------------------------------------------------------------------------------- - id: uat-gate depends_on: [uat-prep] @@ -416,14 +414,14 @@ nodes: The reviewer rejected UAT for "$bootstrap.output.slug" with this feedback: $REJECTION_REASON - FINDING-CAPTURE (ADR-0025) — turn each distinct defect into an agent-ready tracker issue so + FINDING-CAPTURE — turn each distinct defect into an agent-ready tracker issue so it feeds /tickets. This is an on-ramp: file directly (a human is present — no PR gate). 1. Read the tracker contract first: `docs/agents/issue-tracker.md` and `docs/agents/triage-labels.md` in this repository. - **Access** — `issue-tracker.md` § Access names the MCP server or skill that serves this tracker. Read that server's own current tool list and build every call from it. Write - no command, subcommand or flag here and name no provider (ADR-0016): a flag table + no command, subcommand or flag here and name no provider, because a flag table frozen in this file is stale the moment the tool changes. - **Addressing** — its § Addressing names the repository these findings belong to. Name that repository explicitly in every call, and derive nothing from a remote URL. @@ -447,7 +445,7 @@ nodes: 3. For each finding, create a tracker issue: - Title: "QA: — " - Roles: type `bug`, state `ready-for-agent`. The reviewer at this gate already vetted - the defect, so it is agent-ready — it needs no second /triage pass (ADR-0025). + the defect, so it is agent-ready — it needs no second /triage pass. - Body (the finding-capture brief shape): ## What happened / ## What I expected / ## Steps to reproduce / ## Blocked by (issue #s or "None — can start immediately") / ## Additional context (reference the failing AC-N and the test/e2e/coverage evidence, naming any that came @@ -473,7 +471,7 @@ nodes: trigger_rule: all_done # always_run: true — pr_state and base_ok are facts about the remote PR, not about this node's # own exit code; a resume must re-query them, never reuse a cached verdict for a PR retargeted, - # merged or closed since (the exact hole ADR-0033 closes). Independent of trigger_rule above; both + # merged or closed since. Independent of trigger_rule above; both # apply. always_run: true context: fresh @@ -484,7 +482,7 @@ nodes: Expected base branch: $BASE_BRANCH UAT checklist from uat-prep, for reference only: $uat-prep.output - @@ -493,7 +491,7 @@ nodes: `docs/agents/issue-tracker.md` in this repository is the tracker contract. Read it before the query. Its § Access names the MCP server or skill that serves this tracker. Read that server's own current tool list and build the call from it. Write no command, subcommand or flag here, and name - no provider (ADR-0016). Its § Addressing names the repository to query. Name that repository + no provider. Its § Addressing names the repository to query. Name that repository explicitly, and derive nothing from a remote URL. ## 1. The PR state @@ -559,7 +557,7 @@ nodes: # --------------------------------------------------------------------------------------------- # guard-not-mergeable — its `when` is the exact negation of the `when` on `merge`, written against # the same outputs, so one of the two always holds. A run that cannot merge ends cancelled here - # instead of skipping `merge` and ending completed (#652). The message carries the results as well + # instead of skipping `merge` and ending completed. The message carries the results as well # as verify-pr-base's sentences, so the causes stay readable even if `blockers` came back short. # --------------------------------------------------------------------------------------------- - id: guard-not-mergeable @@ -577,8 +575,8 @@ nodes: - id: merge-gate depends_on: [verify-pr-base] when: "$bootstrap.output.gate == 'hitl' && $test.output.result == 'pass' && $e2e.output.result != 'fail' && $coverage-gate.output.result != 'fail' && $verify-pr-base.output.pr_state == 'open' && $verify-pr-base.output.base_ok == 'true'" - # Archon 0.12.1 substitutes node outputs in an approval message but not $BASE_BRANCH (measured - # on #505), so this message names the PR target through verify-pr-base's actual_base and the run + # Archon 0.12.1 substitutes node outputs in an approval message but not $BASE_BRANCH, so + # this message names the PR target through verify-pr-base's actual_base and the run # base through bootstrap's message, which starts with it. approval: message: > @@ -595,7 +593,7 @@ nodes: # node (max_attempts). # # The `test` clause reads `== 'pass'` while e2e and coverage read `!= 'fail'`, and that asymmetry is - # the floor (#430): `test` is the one need this gate cannot advance without, so an `unresolved` test + # the floor: `test` is the one need this gate cannot advance without, so an `unresolved` test # holds the merge, while an unresolved e2e or coverage reports and lets it through. Every node here # reports three states and `skip` is gone, so `!= 'fail'` no longer means "ran or was skipped" — it # means "did not fail", unresolved included, deliberately. @@ -614,7 +612,7 @@ nodes: tracker contract. This node is the one irreversible act in the lifecycle, and step 2 below writes a role, so read both before the merge call. Its § Access names the MCP server or skill that serves this tracker — read that server's own current tool list and build the call from it, - writing no command, subcommand or flag here and naming no provider (ADR-0016). Its § Addressing + writing no command, subcommand or flag here and naming no provider. Its § Addressing names the repository to merge in; name that repository explicitly, and derive nothing from a remote URL. If the file is absent, merge nothing, set `merged` to "false", and set `reason` to "BLOCKED: this repository has no tracker contract at docs/agents/issue-tracker.md. Add it with @@ -690,7 +688,7 @@ nodes: # guard-not-merged — `merge` can run and still not confirm a merge (no tracker contract, no merge # capability, a branch policy that refuses, an error, a PR state it could not read again, or a # call that succeeded while the PR is not merged yet, as under a merge queue or auto-merge). Its - # `when` is the exact negation of "merged", so such a run ends cancelled instead of completed (#652). + # `when` is the exact negation of "merged", so such a run ends cancelled instead of completed. # --------------------------------------------------------------------------------------------- - id: guard-not-merged depends_on: [merge] diff --git a/apps/claude-code/unic-archon-dlc/.claude-plugin/marketplace.json b/apps/claude-code/unic-archon-dlc/.claude-plugin/marketplace.json index d94aafd0..83ea86c0 100644 --- a/apps/claude-code/unic-archon-dlc/.claude-plugin/marketplace.json +++ b/apps/claude-code/unic-archon-dlc/.claude-plugin/marketplace.json @@ -21,7 +21,7 @@ "name": "unic-archon-dlc", "source": "./", "tags": ["productivity", "workflow", "ai-development"], - "version": "0.36.0" + "version": "0.36.1" } ] } diff --git a/apps/claude-code/unic-archon-dlc/.claude-plugin/plugin.json b/apps/claude-code/unic-archon-dlc/.claude-plugin/plugin.json index d75de833..20e45a28 100644 --- a/apps/claude-code/unic-archon-dlc/.claude-plugin/plugin.json +++ b/apps/claude-code/unic-archon-dlc/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "unic-archon-dlc", - "version": "0.36.0", + "version": "0.36.1", "description": "A config-driven Harness for the SDLC — the AI development lifecycle — as an installable Claude Code plugin — main line /specs → /tickets → /build → /pr-review → /qa, plus /triage, /explore, /improve-architecture, and /cleanup. Four Archon workflows (build, qa, pr-review, explore) with human approval gates; the rest are commands/skills composing Matt Pocock's methods.", "author": { "name": "Unic AG", diff --git a/apps/claude-code/unic-archon-dlc/AGENTS.md b/apps/claude-code/unic-archon-dlc/AGENTS.md index b72d04eb..f8fd7dee 100644 --- a/apps/claude-code/unic-archon-dlc/AGENTS.md +++ b/apps/claude-code/unic-archon-dlc/AGENTS.md @@ -85,7 +85,7 @@ Load-bearing invariants. These either originate in a Plugin ADR or are policy de **An extra row in `triage-labels.md` changes no Box.** A Box names its roles literally — `/tickets` writes `ready-for-agent` — so a team-added role is inert, and that is by design: the Canonical roles are the protocol the Boxes share ([`CONTEXT.md`](CONTEXT.md)). The team owns each role's value, its axis and its cardinality; it never owns the role set. A team that wants a Box to behave differently forks the Method, because a transition is procedure, not a parameter. -- **The `## unic-archon-dlc` block in a Consumer's `CLAUDE.md` enumerates no Box and no pipeline stage.** Setup replaces the whole block delimited by `` and `` in place, markers included, and preserves everything outside it verbatim across re-runs. When it finds a block under the pre-0.30.0 `unic-archon-dlc` markers, it rewrites that block in place under the new ones, so a re-run leaves one block, never two ([ADR-0038](docs/adr/0038-practice-packs-stack-by-prefix.md)). A Box list and a pipeline order are what a Plugin release renames, reorders and drops with no Consumer-side change — `/archon-upgrade` fell out of the old block and nobody noticed — so the block carries only paths on the Consumer's own disk (`.archon/unic-dlc.config.yaml`, the tracker contract at `docs/agents/issue-tracker.md` and `docs/agents/triage-labels.md`, `.archon/workflows/` and its `unic-dlc-*.yaml` naming, and `.archon/methods/` — `.archon/methods.local/` left the block with the override tier it advertised, #381), `archon workflow list` and `archon workflow run ""` to discover and run what is actually installed there, and a link to this Plugin's README for what each Box does. The contract pair earns its line because the block is a Consumer's only pointer to the two files a Box refuses to run without, and because those two are tenant-owned: the block says nothing regenerates them once they exist (#383). It names `/unic-archon-dlc:setup` alone, because it cannot say what regenerates it without naming it. Nothing detects a hand-edit between the markers and nothing will, so the block never presents itself as a managed document and carries no `AUTO-GENERATED — DO NOT EDIT` banner (#296). +- **The `## unic-archon-dlc` block in a Consumer's `CLAUDE.md` carries one hand-kept line per Box and no pipeline order.** Setup replaces the whole block delimited by `` and `` in place, markers included, and preserves everything outside it verbatim across re-runs. When it finds a block under the pre-0.30.0 `unic-archon-dlc` markers, it rewrites that block in place under the new ones, so a re-run leaves one block, never two ([ADR-0038](docs/adr/0038-practice-packs-stack-by-prefix.md)). A Box list is what a Plugin release renames and drops with no Consumer-side change, and `/archon-upgrade` once fell out of the block unnoticed. So a pull request that adds, renames or drops a Box changes the Box lines in `commands/setup.md` too, and `/setup` rewrites the block on every run, so the change reaches a Consumer on its next run. Beside the Box lines, the block carries paths on the Consumer's own disk (`.archon/unic-dlc.config.yaml`, the tracker contract at `docs/agents/issue-tracker.md` and `docs/agents/triage-labels.md`, `.archon/workflows/` and its `unic-dlc-*.yaml` naming, and `.archon/methods/` — `.archon/methods.local/` left the block with the override tier it advertised, #381), `archon workflow list` and `archon workflow run ""` to discover and run what is actually installed there. Each Box line says what the Box does and which `gates.*` key decides its human pauses. The contract pair earns its line because the block is a Consumer's only pointer to the two files a Box refuses to run without, and because those two are tenant-owned: the block says nothing regenerates them once they exist (#383). It names `/unic-archon-dlc:setup` alone, because it cannot say what regenerates it without naming it. Nothing detects a hand-edit between the markers and nothing will, so the block never presents itself as a managed document and carries no `AUTO-GENERATED — DO NOT EDIT` banner (#296). - **Slopcheck before build.** Every new package referenced in `package.json` is verified against the npm registry before any RED/GREEN phase runs. Packages that fail are flagged `[ASSUMED]` and require explicit human approval. - **Nyquist map gates the build.** Every issue in Issues JSON must carry a `test_command` (or `test_command_planned`) before `/build` consumes it — the gate runs in `/tickets` ([ADR-0022](docs/adr/0022-tickets-slice-to-build.md)); `/build` reads the build-ready `issues.json` directly ([ADR-0023](docs/adr/0023-build-generic-red-green-refactor-loop.md)). - **The evidence gate is a deterministic script writer, never a self-judging prompt.** `/build` declares `evidence_policy: { required: true }`; `verification` and `goals-check` report a boolean `passed` alongside their existing prose verdicts, and `verification` adds a three-state `test_outcome` — `pass`, `fail` or `unresolved` — because a check that could not run is not a green one, and `test` is the one need this gate cannot advance without (#430); a dedicated `evidence` script node deletes any stale file left by a prior resumed attempt, prints its own three-state verdict as JSON (a `script:` node has no `output_format`, so only stdout resolves downstream), then writes `$ARTIFACTS_DIR/evidence.json` on every verdict, with the verdict and the failures behind it, mirroring it to `//evidence.json` so the Session commit carries it. The verdict is `pass` only when both booleans are true and the test outcome is `pass`. Only a `pass` verdict opens a pull request; any other verdict cancels the run with the work pushed, and two guards cover `evidence` ending without writing. `push-branch` refuses a missing Session mirror, and `evidence_policy` catches a committed mirror with no `$ARTIFACTS_DIR` copy ([ADR-0040](docs/adr/0040-build-verdict-decides-the-pull-request.md)). `always_run: true` on `slopcheck`, `verification`, `goals-check`, `evidence` (and on `/qa`'s `pr-check`, `verify-pr-base`, `e2e`, `coverage-gate`) opts each out of Archon's resume cache, because their exit code reports a fact about external or mutable state, not about itself — the same hole that let a resumed `/qa` run merge against a since-retargeted PR base. See [ADR-0033](docs/adr/0033-archon-070-schema-target.md) and [ADR-0034](docs/adr/0034-evidence-gate-deterministic-writer.md). @@ -97,6 +97,8 @@ Load-bearing invariants. These either originate in a Plugin ADR or are policy de - **`/explore` is the off-line, optional research + AFK-spike on-ramp — an Archon workflow whose `findings.md` is the `/specs` baton.** Never required; a precursor to `/specs` (PLAN #3/#8). The pipeline (bootstrap → guard → four parallel research nodes, each reading the `research` Method for its primary-source citation discipline (#281) → synthesize → spike → spike-ticket → spike-branch-gate → preserve-spike) writes `//findings.md`, where the **Integrated Brief** carries three explicitly-named lenses — **Domain Model / Established Decisions / Prior Research** — that `/specs`' load-context reads verbatim (the tightened handoff contract). The `spike` node is **AFK** (build/measure where feasible, else reason → VALIDATED/INVALIDATED/PARTIAL verdicts); **interactive prototyping stays Matt's `/prototype` skill**, referenced but never invoked (nodes have no live conversation — [ADR-0017](docs/adr/0017-container-follows-structural-need.md)). The `spike-branch-gate` is a config-gated `approval:` node (`gates.explore`, HITL default): APPROVE preserves the spike on `spike/`, AFK skips it (worktree left for `/cleanup`); the **spike ticket is filed before the gate** (through the tracker contract in `docs/agents/`, never a `tracker-adapter`/`labels-config` lib) so the durable output survives a discard. Every node is a self-contained prompt node — no plugin-`lib/` import ([ADR-0023](docs/adr/0023-build-generic-red-green-refactor-loop.md) §5); this step dissolved `findings-writer` + `spike-verdicts` and added no config key. See [ADR-0029](docs/adr/0029-explore-research-spike-onramp.md). - **This monorepo is not a Consumer.** `/unic-archon-dlc:setup` must never run against it. An earlier dogfooding run left generated artefacts under `docs/agents/` and a marker-delimited block in the root `AGENTS.md`, which collided with `setup-matt-pocock-skills` over the same paths — the collision this Plugin's own `/triage` doctrine forbids. Both were removed and `docs/agents/*.md` is now hand-owned by the repo; Matt's skills are its only agent-skill driver. Test the Plugin against a scratch Consumer clone instead. See [root ADR-0033](../../../docs/adr/0033-de-dogfood-unic-archon-dlc.md). +- **What a Consumer session reads carries its content inline, never a reference back to this repository.** That is every file in `commands/`, every Box in `.archon/workflows/`, `README.md`, `vendor/mattpocock-skills/README.md`, and any text `/setup` writes into a Consumer file. None of them may hold a link to this repository, a path in it, or a citation by number such as `ADR-0023` or `#281`. A command runs from the Plugin cache and resolves a relative link against the Consumer's working directory, and a copied Box reads `ADR-0023` as the Consumer's own ADR of that number. When a command or a Box needs a rule from a Plugin ADR, state the rule in one or two sentences. Two exceptions hold. A relative link in either README that resolves inside the Plugin stays, because `/setup` and the agent read both READMEs from ``, where the link resolves. A path `/setup` resolves through `installPath` stays too. A step that tells the agent to read the Consumer's own `docs/adr/` is not a reference back, so it stays. This rule is the whole guard. Nothing checks it, so a diff that adds a reference merges green unless a reviewer reads it. + ## External dependencies - **A project-scoped MCP server in the Consumer's `.mcp.json` reaches a Box.** Every Box that composes "the server § Access names" depends on this, and nothing had tested it until 2026-08-18: an Archon run under `~/.archon/workspaces///worktrees/…` loaded the Consumer's registered tracker server and read work items, pull requests and threads. Project scope travels with the worktree, so a node gets the access an interactive session gets — at a path no human approved. A **personal**-scope server does not travel, which is why `/setup` tells a team to register theirs at project scope. diff --git a/apps/claude-code/unic-archon-dlc/CHANGELOG.md b/apps/claude-code/unic-archon-dlc/CHANGELOG.md index cfabcdd3..fdc2b32d 100644 --- a/apps/claude-code/unic-archon-dlc/CHANGELOG.md +++ b/apps/claude-code/unic-archon-dlc/CHANGELOG.md @@ -11,6 +11,23 @@ ### Fixed - (none) +## [0.36.1] — 2026-10-28 + +### Breaking +- (none) + +### Added +- (none) + +### Fixed +- The commands and the Boxes no longer refer back to this repository. A Consumer session could follow none of those references, and a copied Box read a Plugin ADR number as the Consumer's own ADR. Every link to a Plugin ADR, every citation of a Plugin ADR or issue by number, and every path in this repository is gone from `commands/` and `.archon/workflows/`. Where a command or a Box needed the rule behind a citation, it now states the rule. The steps that read the Consumer's own `docs/adr/` stay (#556). +- `/setup` reads § Dependencies, § Configuration reference and § The tracker contract from `/README.md`, and checks that the file is present. The block it writes into the Consumer's `CLAUDE.md` replaces the URL to this repository with one line per Box that says what the Box does (#556). +- `/improve-architecture` picks the ADR home from the `docs/adr/` directories the Consumer already has and confirms it with the user. With none, it proposes the root `docs/adr/`. It no longer names this repository's layout (#556). +- `/setup` stops when `/README.md` lacks § Dependencies, § Configuration reference or § The tracker contract, and names the missing section. Without § Dependencies, the check for a missing Method passed with nothing to compare (#556). +- The `CLAUDE.md` block says that `unic-dlc-pr-review` asks for a confirmation only when `gates.pr-review` is `hitl`, and that `unic-dlc-qa` asks for UAT sign-off and a merge confirmation only when `gates.qa` is `hitl`. It also says that `unic-dlc-build` pauses for PR review only when `gates.build` is `hitl`, that `unic-dlc-explore` offers to keep the spike code only when `gates.explore` is `hitl`, and that `unic-dlc-qa` merges only when the checks pass and the PR is open against the right base. `/setup` and `AGENTS.md` now say that the block lists the Boxes and that a pull request that adds, renames or drops a Box updates that list (#556). +- `/archon-upgrade` ties DEFER to the locked precedents it states, and offers **file an issue** or **nothing** as the next step. It no longer asks the reader to cite or amend a Plugin ADR (#556). +- The Plugin `README.md` turns every bare ADR citation into a link into its own `docs/adr/`, which resolves inside the installed Plugin (#556). + ## [0.36.0] — 2026-10-28 ### Breaking diff --git a/apps/claude-code/unic-archon-dlc/README.md b/apps/claude-code/unic-archon-dlc/README.md index 3c9533e8..ebbe4d98 100644 --- a/apps/claude-code/unic-archon-dlc/README.md +++ b/apps/claude-code/unic-archon-dlc/README.md @@ -63,19 +63,19 @@ OFF-LINE /setup · /explore · /improve-architecture · /cleanup · /archon-u -| Box | Container | Gate | Role | -| ---------------------------------------------------------------------------------------------------------- | --------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------ | -| `/setup` ([diagram](docs/architecture/20260925-unic-dlc-setup-command.html)) | skill | HITL | Conversational config: detects the stack, writes `.archon/unic-dlc.config.yaml` (ADR-0019) | -| `/explore` | Archon | `gates.explore` | Off-line, optional research + AFK spike → `findings.md` (ADR-0029) | -| `/specs` ([diagram](docs/architecture/20260925-unic-dlc-specs-command.html)) | skill | HITL | Branch-on-input → `PRD.md`, plus one design contract per component when `design.type` is set (ADR-0020) | -| `/tickets` ([diagram](docs/architecture/20260925-unic-dlc-tickets-command.html)) | skill | HITL | Slice the PRD into build-ready `issues.json` with a `test_command` each (ADR-0022) | -| `/triage` ([diagram](docs/architecture/20260925-unic-dlc-triage-command.html)) | skill | HITL | Intake on-ramp: raw work → agent-ready tracker issues, DLC-config labels (ADR-0024) | -| `/build` | Archon | `gates.build` | Anti-cheat red/green loop over `issues.json` (ADR-0012 / ADR-0023) | -| `/pr-review` | Archon | `gates.pr-review` | Fan-out review of the open PR, intent-grounded; posts summary + inline (ADR-0026) | -| `/qa` | Archon | `gates.qa` | test → e2e → coverage → UAT → merge; a UAT reject files agent-ready issues (ADR-0025) | -| `/improve-architecture` ([diagram](docs/architecture/20260925-unic-dlc-improve-architecture-command.html)) | skill | HITL | Arch-health + intent-drift + ADR superseding → `arch-review.md` (ADR-0027) | -| `/cleanup` ([diagram](docs/architecture/20260925-unic-dlc-cleanup-command.html)) | command | HITL | Repo-global janitor: prune stale worktrees / branches / PRs / slug dirs, report-first (ADR-0028) | -| `/archon-upgrade` ([diagram](docs/architecture/20260925-unic-dlc-archon-upgrade-command.html)) | command | — | Report what a new Archon release means for this Plugin; writes nothing here, probes config keys in a throwaway repo (ADR-0035) | +| Box | Container | Gate | Role | +| ---------------------------------------------------------------------------------------------------------- | --------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `/setup` ([diagram](docs/architecture/20260925-unic-dlc-setup-command.html)) | skill | HITL | Conversational config: detects the stack, writes `.archon/unic-dlc.config.yaml` ([ADR-0019](docs/adr/0019-conversational-setup.md)) | +| `/explore` | Archon | `gates.explore` | Off-line, optional research + AFK spike → `findings.md` ([ADR-0029](docs/adr/0029-explore-research-spike-onramp.md)) | +| `/specs` ([diagram](docs/architecture/20260925-unic-dlc-specs-command.html)) | skill | HITL | Branch-on-input → `PRD.md`, plus one design contract per component when `design.type` is set ([ADR-0020](docs/adr/0020-specs-branch-on-input.md)) | +| `/tickets` ([diagram](docs/architecture/20260925-unic-dlc-tickets-command.html)) | skill | HITL | Slice the PRD into build-ready `issues.json` with a `test_command` each ([ADR-0022](docs/adr/0022-tickets-slice-to-build.md)) | +| `/triage` ([diagram](docs/architecture/20260925-unic-dlc-triage-command.html)) | skill | HITL | Intake on-ramp: raw work → agent-ready tracker issues, DLC-config labels ([ADR-0024](docs/adr/0024-triage-intake-on-ramp.md)) | +| `/build` | Archon | `gates.build` | Anti-cheat red/green loop over `issues.json` ([ADR-0012](docs/adr/0012-fresh-context-red-green-separation.md) / [ADR-0023](docs/adr/0023-build-generic-red-green-refactor-loop.md)) | +| `/pr-review` | Archon | `gates.pr-review` | Fan-out review of the open PR, intent-grounded; posts summary + inline ([ADR-0026](docs/adr/0026-pr-review-generic-archon-harvest.md)) | +| `/qa` | Archon | `gates.qa` | test → e2e → coverage → UAT → merge; a UAT reject files agent-ready issues ([ADR-0025](docs/adr/0025-qa-pipeline-onramp.md)) | +| `/improve-architecture` ([diagram](docs/architecture/20260925-unic-dlc-improve-architecture-command.html)) | skill | HITL | Arch-health + intent-drift + ADR superseding → `arch-review.md` ([ADR-0027](docs/adr/0027-improve-architecture-skill-superseding.md)) | +| `/cleanup` ([diagram](docs/architecture/20260925-unic-dlc-cleanup-command.html)) | command | HITL | Repo-global janitor: prune stale worktrees / branches / PRs / slug dirs, report-first ([ADR-0028](docs/adr/0028-cleanup-operational-janitor.md)) | +| `/archon-upgrade` ([diagram](docs/architecture/20260925-unic-dlc-archon-upgrade-command.html)) | command | — | Report what a new Archon release means for this Plugin; writes nothing here, probes config keys in a throwaway repo ([ADR-0035](docs/adr/0035-archon-upgrade-report.md)) | Archon boxes gate via config (`gates.: hitl | afk`, HITL default); interactive skill boxes are inherently HITL. `/handoff` and `/prototype` are **referenced** Matt skills, named in prose for a @@ -168,17 +168,17 @@ The Archon boxes ship as key-discriminated workflow YAMLs in `.archon/workflows/ | `unic-dlc-explore` ([diagram](docs/architecture/20260925-unic-dlc-explore-pipeline.html)) | `bootstrap → guard-not-ready → {research-stack · research-features · research-architecture · research-pitfalls} → synthesize → spike → spike-ticket → spike-branch-gate ✓ → preserve-spike` | > **✓** = config-gated `approval:` node — it pauses for a human when the box's gate is `hitl` and -> auto-proceeds when `afk` (ADR-0017). Parallel nodes are shown in `{…}`. +> auto-proceeds when `afk` ([ADR-0017](docs/adr/0017-container-follows-structural-need.md)). Parallel nodes are shown in `{…}`. > > `/pr-review`'s `review` and `/build`'s `implement-review-precheck` each run the `code-review` Method's > own two parallel sub-agents (Standards · Spec) **inside one node**, so their parallelism does not appear -> in the DAG (ADR-0026 §8). +> in the DAG ([ADR-0026](docs/adr/0026-pr-review-generic-archon-harvest.md) §8). > > `evidence` writes `$ARTIFACTS_DIR/evidence.json` on every verdict. The verdict is `pass` only when > `verification` and `goals-check` both report `passed: true` with an empty `failures` list, the test > outcome is `pass`, and the code-review pre-check reports `ran` with no hard finding. Only then > does `open-pr` run; any other verdict reaches `guard-not-pass`, which cancels the run with the work on -> the pushed branch (ADR-0034, ADR-0040). `{guard-not-pass · open-pr}` are siblings, and the verdict picks +> the pushed branch ([ADR-0034](docs/adr/0034-evidence-gate-deterministic-writer.md), [ADR-0040](docs/adr/0040-build-verdict-decides-the-pull-request.md)). `{guard-not-pass · open-pr}` are siblings, and the verdict picks > one. Each workflow name links its pipeline diagram, made with Archify from the workflow YAML. Its source @@ -256,7 +256,7 @@ A rename wave is now found by running a Box against a live Consumer, not by a te `/unic-archon-dlc:setup` **verifies the bundle by reading it** — every Method directory carries its `SKILL.md` and the companion files that Method reads, and `LICENSE` is present — and stops if either check fails, because that means the shipped plugin is incomplete. The licence hash and the manifest -closure it used to compare against are gone with the plugin's code (#381); nothing replaces them. +closure it used to compare against are gone with the plugin's code; nothing replaces them. > **Do _not_ run Matt's `setup-matt-pocock-skills`.** Both it and `/unic-archon-dlc:setup` write > `docs/agents/issue-tracker.md` and `docs/agents/triage-labels.md` — this repository's **tracker @@ -311,40 +311,40 @@ flows into `/tickets` next. The `/unic-archon-dlc:setup` command writes the rich `.archon/unic-dlc.config.yaml` ([ADR-0018](docs/adr/0018-generic-core-config-compose.md), [ADR-0019](docs/adr/0019-conversational-setup.md)). It is the config substrate every box reads, and `/setup` is its sole writer. The file is **tenant-owned**: `/setup` writes it on the first run, and on a later run reports what differs from what it would write and changes nothing — pass `reconfigure` to be offered the change file by file. A present-but-malformed config stops the run rather than being overwritten, and so does a legacy flat `.archon/unic-dlc.config.json`: no migration ships any more, and reading such a file as "no config" would write a second config beside it. Top-level sections: -| Path | Default | Valid values | Description | -| -------------------------------------------------------- | ---------------------- | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `project.name` | asked | any string | Project name | -| `project.repo_layout` | auto-detected | `single-context` · `multi-context` | `multi-context` when the repository holds more than one independently-releasable project | -| `project.branching` | asked | `gitflow` · `github-flow` | Branching model (mandatory). `/qa` reads it only to decide whether to delete the merged `feature/*` branch. A run's base branch is Archon's `$BASE_BRANCH`, which `/unic-archon-dlc:setup` reports | -| `docs.type` | `markdown` | `markdown` · docs system name · `none` | Where the team's product specs live (drives `/specs` publishing) | -| `docs.access` · `design.access` | auto-detected | `{mcp, cli}` | Which surface serves the docs and design systems, filled from setup's verify-only discovery | -| `docs.publish` | `false` | `true` · `false` | Opt-in publishing of the PRD to the docs system | -| `design.type` | `none` | design system name · `none` | Design system source; boxes test set-versus-`none` and never compare the value to a literal — `design.access.mcp` resolves the tool | -| `templates.prd` | 7-section scaffold | template string | Config-driven PRD template `/specs` fills (ADR-0018); override to change PRD shape. The `Confirmations` section sits outside it and no override removes it | -| `templates.{issue,bug}` | `null` | template string | Config-driven artifact templates (ADR-0018) | -| `specs.discuss_mode` | `discuss` | `discuss` · `assumptions` | `/specs` grilling style: `discuss` composes `grilling` + `domain-modeling`; `assumptions` enumerates upfront (ADR-0020) | -| `specs.gate` | `open-pr` | `open-pr` · `stage-only` | `/specs` PRD gate: `open-pr` commits + opens a PR to `develop` (never merged); `stage-only` stages and stops. Both refuse when a halt's `Confirmations` entry is absent or unanswered | -| `tickets.gate` | `open-pr` | `open-pr` · `stage-only` | `/tickets` gate: `open-pr` commits `issues.json` + opens a PR to `develop` (never merged); `stage-only` stages and stops (ADR-0022) | -| `triage.out_of_scope_dir` | `.out-of-scope` | dir name | Where `/triage` records rejected enhancements (the out-of-scope KB) (ADR-0024) | -| `triage.external_prs` | `auto` | `auto` · `always` · `never` | Whether `/triage` treats external PRs as a request surface; `auto` = ask the tracker whether it carries them at all (ADR-0024) | -| `gates.{build,qa,pr-review,explore}` | `hitl` | `hitl` · `afk` | Per-Archon-box gate mode (ADR-0017); interactive boxes are HITL | -| `build.fresh_context_red_green` | `true` | `true` · `false` | Anti-cheat fresh-context red/green separation (ADR-0012) | -| `build.{tdd_mode,nyquist_validation,slopsquatting_gate}` | `true` | `true` · `false` | Build discipline toggles | -| `build.coverage_threshold` | `null` | number (0–100) or `null` | Minimum % coverage for `/build`, and the fallback `/qa` uses when `qa.coverage_threshold` is unset. `null` means `/build`'s `verification` wants no coverage figure and reports nothing about it — which is silence, not a passing check (ADR-0037 §5) | -| `qa.coverage_threshold` | `null` | number (0–100) or `null` | `/qa`'s own minimum % coverage, falling back to `build.coverage_threshold` when unset, so the QA gate can hold a different bar from the build's. `/qa`'s `coverage-gate` wants a figure always, so a null on both keys is `unresolved` there rather than a skip (ADR-0037 §5) | -| `sdlc_needs.install` | `null` | shell command string | Installs this project's dependencies. `/build`, `/qa` and `/pr-review` each run it once, at `bootstrap`; `/explore` does not, since it runs no checks and so has no dependencies to prepare | -| `sdlc_needs.build` | `null` | shell command string | Builds the project. No node reads it yet — see the note below the table | -| `sdlc_needs.test` | `null` | shell command string | Runs the test suite. The one need that is mandatory: `/qa`'s merge gate and `/build`'s evidence verdict require an outcome for it | -| `sdlc_needs.e2e` | `null` | shell command string | Runs the end-to-end suite. Read by `/qa`'s `e2e` node and by `/build`'s `verification` | -| `sdlc_needs.lint` | `null` | shell command string | Lints the project. No node reads it yet — see the note below the table | -| `sdlc_needs.format` | `null` | shell command string | Formats the project. No node reads it yet — see the note below the table | -| `sdlc_needs.typecheck` | `null` | shell command string | Type-checks the project. Read by `/build`'s per-slice GREEN phase | -| `sdlc_needs.dev` | `null` | shell command string | Starts the development server. No node reads it yet — see the note below the table | -| `sdlc_needs.coverage` | `null` | shell command string | Produces a coverage figure, compared against the resolved threshold — `qa.coverage_threshold ?? build.coverage_threshold` in `/qa`, `build.coverage_threshold` in `/build` | -| `estimations` | `off` | `off` · `provisional` · `definitive` · `both` | Estimation waves (ADR-0020) | -| `cleanup.{stale_days,dry_run,prune_slug_dirs}` | `7` · `true` · `false` | number · bool · bool | `/cleanup` thresholds; report-first, never auto-deletes (ADR-0028) | -| `artifacts_dir` | `workflows` | dir name | Session artifact home base (`//`) | -| `model_profile` | `balanced` | `fast` · `balanced` · `max` | Model tier for workflow nodes | +| Path | Default | Valid values | Description | +| -------------------------------------------------------- | ---------------------- | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `project.name` | asked | any string | Project name | +| `project.repo_layout` | auto-detected | `single-context` · `multi-context` | `multi-context` when the repository holds more than one independently-releasable project | +| `project.branching` | asked | `gitflow` · `github-flow` | Branching model (mandatory). `/qa` reads it only to decide whether to delete the merged `feature/*` branch. A run's base branch is Archon's `$BASE_BRANCH`, which `/unic-archon-dlc:setup` reports | +| `docs.type` | `markdown` | `markdown` · docs system name · `none` | Where the team's product specs live (drives `/specs` publishing) | +| `docs.access` · `design.access` | auto-detected | `{mcp, cli}` | Which surface serves the docs and design systems, filled from setup's verify-only discovery | +| `docs.publish` | `false` | `true` · `false` | Opt-in publishing of the PRD to the docs system | +| `design.type` | `none` | design system name · `none` | Design system source; boxes test set-versus-`none` and never compare the value to a literal — `design.access.mcp` resolves the tool | +| `templates.prd` | 7-section scaffold | template string | Config-driven PRD template `/specs` fills ([ADR-0018](docs/adr/0018-generic-core-config-compose.md)); override to change PRD shape. The `Confirmations` section sits outside it and no override removes it | +| `templates.{issue,bug}` | `null` | template string | Config-driven artifact templates ([ADR-0018](docs/adr/0018-generic-core-config-compose.md)) | +| `specs.discuss_mode` | `discuss` | `discuss` · `assumptions` | `/specs` grilling style: `discuss` composes `grilling` + `domain-modeling`; `assumptions` enumerates upfront ([ADR-0020](docs/adr/0020-specs-branch-on-input.md)) | +| `specs.gate` | `open-pr` | `open-pr` · `stage-only` | `/specs` PRD gate: `open-pr` commits + opens a PR to `develop` (never merged); `stage-only` stages and stops. Both refuse when a halt's `Confirmations` entry is absent or unanswered | +| `tickets.gate` | `open-pr` | `open-pr` · `stage-only` | `/tickets` gate: `open-pr` commits `issues.json` + opens a PR to `develop` (never merged); `stage-only` stages and stops ([ADR-0022](docs/adr/0022-tickets-slice-to-build.md)) | +| `triage.out_of_scope_dir` | `.out-of-scope` | dir name | Where `/triage` records rejected enhancements (the out-of-scope KB) ([ADR-0024](docs/adr/0024-triage-intake-on-ramp.md)) | +| `triage.external_prs` | `auto` | `auto` · `always` · `never` | Whether `/triage` treats external PRs as a request surface; `auto` = ask the tracker whether it carries them at all ([ADR-0024](docs/adr/0024-triage-intake-on-ramp.md)) | +| `gates.{build,qa,pr-review,explore}` | `hitl` | `hitl` · `afk` | Per-Archon-box gate mode ([ADR-0017](docs/adr/0017-container-follows-structural-need.md)); interactive boxes are HITL | +| `build.fresh_context_red_green` | `true` | `true` · `false` | Anti-cheat fresh-context red/green separation ([ADR-0012](docs/adr/0012-fresh-context-red-green-separation.md)) | +| `build.{tdd_mode,nyquist_validation,slopsquatting_gate}` | `true` | `true` · `false` | Build discipline toggles | +| `build.coverage_threshold` | `null` | number (0–100) or `null` | Minimum % coverage for `/build`, and the fallback `/qa` uses when `qa.coverage_threshold` is unset. `null` means `/build`'s `verification` wants no coverage figure and reports nothing about it — which is silence, not a passing check ([ADR-0037](docs/adr/0037-config-declares-sdlc-needs.md) §5) | +| `qa.coverage_threshold` | `null` | number (0–100) or `null` | `/qa`'s own minimum % coverage, falling back to `build.coverage_threshold` when unset, so the QA gate can hold a different bar from the build's. `/qa`'s `coverage-gate` wants a figure always, so a null on both keys is `unresolved` there rather than a skip ([ADR-0037](docs/adr/0037-config-declares-sdlc-needs.md) §5) | +| `sdlc_needs.install` | `null` | shell command string | Installs this project's dependencies. `/build`, `/qa` and `/pr-review` each run it once, at `bootstrap`; `/explore` does not, since it runs no checks and so has no dependencies to prepare | +| `sdlc_needs.build` | `null` | shell command string | Builds the project. No node reads it yet — see the note below the table | +| `sdlc_needs.test` | `null` | shell command string | Runs the test suite. The one need that is mandatory: `/qa`'s merge gate and `/build`'s evidence verdict require an outcome for it | +| `sdlc_needs.e2e` | `null` | shell command string | Runs the end-to-end suite. Read by `/qa`'s `e2e` node and by `/build`'s `verification` | +| `sdlc_needs.lint` | `null` | shell command string | Lints the project. No node reads it yet — see the note below the table | +| `sdlc_needs.format` | `null` | shell command string | Formats the project. No node reads it yet — see the note below the table | +| `sdlc_needs.typecheck` | `null` | shell command string | Type-checks the project. Read by `/build`'s per-slice GREEN phase | +| `sdlc_needs.dev` | `null` | shell command string | Starts the development server. No node reads it yet — see the note below the table | +| `sdlc_needs.coverage` | `null` | shell command string | Produces a coverage figure, compared against the resolved threshold — `qa.coverage_threshold ?? build.coverage_threshold` in `/qa`, `build.coverage_threshold` in `/build` | +| `estimations` | `off` | `off` · `provisional` · `definitive` · `both` | Estimation waves ([ADR-0020](docs/adr/0020-specs-branch-on-input.md)) | +| `cleanup.{stale_days,dry_run,prune_slug_dirs}` | `7` · `true` · `false` | number · bool · bool | `/cleanup` thresholds; report-first, never auto-deletes ([ADR-0028](docs/adr/0028-cleanup-operational-janitor.md)) | +| `artifacts_dir` | `workflows` | dir name | Session artifact home base (`//`) | +| `model_profile` | `balanced` | `fast` · `balanced` · `max` | Model tier for workflow nodes | **Every `sdlc_needs` key names a need of the development process, never a tool.** `test` is the need; whichever runner a project uses is the tool that serves it, and no Box names one. A `null` value means the diff --git a/apps/claude-code/unic-archon-dlc/commands/archon-upgrade.md b/apps/claude-code/unic-archon-dlc/commands/archon-upgrade.md index 32ec5785..0259b95a 100644 --- a/apps/claude-code/unic-archon-dlc/commands/archon-upgrade.md +++ b/apps/claude-code/unic-archon-dlc/commands/archon-upgrade.md @@ -1,16 +1,14 @@ --- allowed-tools: ['Bash', 'Read', 'Glob'] -description: 'Report what a new Archon release means for this Plugin: compare the installed version against the 0.7.0 floor, classify each upstream change as ADOPT / DEFER / VERIFY-ONLY / BREAKS-US against the four installed Box YAMLs, check for changed upstream defaults, re-assert ADR-0011 trap conformance, and probe that the Archon config keys this Plugin depends on are still read. Read-only in this repository — the key probe writes a throwaway repository outside every clone.' +description: 'Report what a new Archon release means for this Plugin: compare the installed version against the 0.7.0 floor, classify each upstream change as ADOPT / DEFER / VERIFY-ONLY / BREAKS-US against the four installed Box YAMLs, check for changed upstream defaults, re-assert the four node-schema traps, and probe that the Archon config keys this Plugin depends on are still read. Read-only in this repository — the key probe writes a throwaway repository outside every clone.' --- # unic-archon-dlc:archon-upgrade -> Design rationale: [ADR-0035 — `/archon-upgrade` reports what a new Archon release means for this Plugin](docs/adr/0035-archon-upgrade-report.md) (container per [ADR-0017](docs/adr/0017-container-follows-structural-need.md); floor, node-schema conventions and the four silent-failure traps per [ADR-0011](docs/adr/0011-archon-schema-target.md); the two locked classification precedents per [ADR-0033](docs/adr/0033-archon-070-schema-target.md); the evidence-gate shape a future release may touch per [ADR-0034](docs/adr/0034-evidence-gate-deterministic-writer.md)). - `/archon-upgrade` answers one question: **Archon shipped a new release — what does it mean for this Plugin?** It compares the installed `archon` against this Plugin's floor, reads the release notes for everything in between, classifies each notable change against the four installed Box YAMLs, and -re-asserts [ADR-0011](docs/adr/0011-archon-schema-target.md)'s silent-failure traps. The output is one +re-asserts the four node-schema silent-failure traps of Step 5. The output is one decision table. **It is read-only here, absolutely.** There is no apply mode — this is a stronger claim than @@ -27,8 +25,7 @@ Follow these steps in order. Do not skip any step. ## Step 1 — Compare installed against the floor This Plugin's floor is **Archon `0.7.0`** — the version the key-discriminated schema needs: gates, -loops, `context: fresh`, `evidence_policy` and `always_run` -([ADR-0033](docs/adr/0033-archon-070-schema-target.md)). Run: +loops, `context: fresh`, `evidence_policy` and `always_run`. Run: ```bash archon --version @@ -63,7 +60,7 @@ GitHub URL. If this fails for any reason — no `brew` on `PATH` (expected on Windows), Archon installed another way, a non-zero exit, or a changed JSON shape — **do not guess**. Print one line explaining what failed and **ask the user, in this conversation, for the `owner/repo` to read release notes from.** This command -runs with a human present ([ADR-0017](docs/adr/0017-container-follows-structural-need.md)); asking costs +runs with a human present; asking costs one turn, guessing costs a wrong report. If the user declines or does not know, skip to Steps 5 and 6 and say in the final report that the classification table could not be produced. @@ -98,29 +95,27 @@ Walk every kept release's notes. Emit one row per notable change: The four classifications: - **ADOPT** — a new capability this Plugin should take on. Name the file and node that would change. -- **DEFER** — recognised as valuable, blocked on a condition already recorded in an ADR. Cite the - recorded condition; never invent one. +- **DEFER** — recognised as valuable, blocked on a condition one of the locked precedents below + records. Cite that precedent; never invent one. - **VERIFY-ONLY** — a deliberate, already-documented divergence or an area we track but do not follow. Confirm it still holds. Do not re-litigate it. - **BREAKS-US** — something this Plugin currently relies on has changed behaviour or been removed. Every row names an **affected file and node** (for example `.archon/workflows/unic-dlc-build.yaml:evidence`) -and one suggested next step: **file an issue**, **amend an ADR**, or **nothing**. +and one suggested next step: **file an issue** or **nothing**. -### Two locked precedents — cite them, never re-derive them +### Two locked precedents — apply them, never re-derive them - **`workflow:` sub-runs (dynamic fan-out, `with:` parameter mapping over a dynamic list) → - classify DEFER.** The rationale in that row is a citation and nothing else: _see ADR-0033 § Sub-runs - (`workflow:` nodes): deferred, with the trigger to revisit_. Do not restate the trigger, do not - paraphrase it, and do not invent a second one. Reclassify the row as ADOPT **only** when the release - notes show upstream has shipped what that section already records as the trigger — nothing else - moves it. + classify DEFER.** The rationale in that row is this sentence and nothing else: _sub-runs stay + deferred until upstream ships fan-out and `with:` parameter mapping over a dynamic list_. Do not + invent a second trigger. Reclassify the row as ADOPT **only** when the release notes show upstream + has shipped both. - **Archon's own repository / remote-resolution algorithm (the remote key in Step 6's table, an `origin`-then-sole-remote fallback, or similar) → classify VERIFY-ONLY, never BREAKS-US.** This Harness resolves no repository from a remote at all: `docs/agents/issue-tracker.md` § Addressing names it, so Archon's algorithm and - this Harness answer different questions and cannot disagree - ([ADR-0024](docs/adr/0024-triage-intake-on-ramp.md), which retired the derivation - ADR-0033 § "Repository derivation" recorded as a deliberate divergence). Cite that. Classifying it as + this Harness answer different questions and cannot disagree. The Harness once derived the + repository from a remote and has retired that derivation. Say so in the row. Classifying it as BREAKS-US makes every run re-raise a decision that has already been superseded once. ### Mandatory sub-pass — changed upstream defaults, not just new fields @@ -136,12 +131,12 @@ only asks "is there a new field?" is blind to a removed default a Box still assu Report each hit as its own row, marked `default-change`, in the same table. -## Step 5 — Re-assert ADR-0011's traps against the installed Boxes +## Step 5 — Re-assert the node-schema traps against the installed Boxes This step runs **unconditionally**, even when Steps 2–4 failed. Read every `.archon/workflows/unic-dlc-*.yaml` in this repository — the Boxes actually installed here, which is what a run would use — and check each one against -[ADR-0011](docs/adr/0011-archon-schema-target.md)'s node-schema conventions 1–4: +these four node-schema conventions: 1. No node carries a `type:` discriminator. 2. Every node with an `approval:` key sits in a workflow whose top level declares `interactive: true`. @@ -153,7 +148,7 @@ wrong`. If you cannot read a file, that file is a FAIL naming the read error — run is never a silent PASS. A FAIL here is not caused by the new Archon release: it means an installed Box has drifted from -ADR-0011. Nothing else guards these four conventions, so this read is the only place they are +these conventions. Nothing else guards these four conventions, so this read is the only place they are re-asserted — say which file drifted and stop short of fixing it, because this command changes nothing in this repository. @@ -249,7 +244,7 @@ One block, in this order: | ------- | ------ | -------------- | ------------------ | ------------------- | ...one row per notable change, default-change rows included... - ADR-0011 traps (installed Boxes) + Node-schema traps (installed Boxes) unic-dlc-build.yaml PASS unic-dlc-explore.yaml PASS unic-dlc-pr-review.yaml PASS @@ -267,4 +262,4 @@ One block, in this order: Close with this line, verbatim: > This command wrote nothing in this repository — only the throwaway repository Step 6 built, now -> deleted. Adoption is a human decision — file an issue or amend an ADR by hand. +> deleted. Adoption is a human decision. File an issue. diff --git a/apps/claude-code/unic-archon-dlc/commands/cleanup.md b/apps/claude-code/unic-archon-dlc/commands/cleanup.md index 69f4c6ec..30835b69 100644 --- a/apps/claude-code/unic-archon-dlc/commands/cleanup.md +++ b/apps/claude-code/unic-archon-dlc/commands/cleanup.md @@ -5,25 +5,22 @@ description: 'Repo-global operational janitor: report (and, on explicit opt-in, # unic-archon-dlc:cleanup -> Design rationale: [ADR-0028 — `/cleanup` is the repo-global operational janitor](docs/adr/0028-cleanup-operational-janitor.md) (container per [ADR-0017](docs/adr/0017-container-follows-structural-need.md); compose-don't-reimplement per [ADR-0016](docs/adr/0016-dlc-thin-process-layer.md); tracker is the single source of truth per [ADR-0013](docs/adr/0013-tracker-single-source-of-truth.md); artifact home per [ADR-0015](docs/adr/0015-workflows-slug-artifact-home.md)). - **Arguments:** "$ARGUMENTS" `/cleanup` is the **off-line operational janitor**: it prunes the debris an Archon-driven lifecycle accumulates — **merged/stale worktrees**, **stale branches/PRs**, and **stale `workflows//` artifact dirs**. It is a **repo-global** box: it inspects and mutates sibling worktrees, branches, and PRs, so it **cannot** run inside an isolated worktree — that is exactly why it is a **Claude -Code command, not an Archon workflow** ([ADR-0017](docs/adr/0017-container-follows-structural-need.md)). +Code command, not an Archon workflow**. It is a **thin composing wrapper**: it **owns the _what_** — deciding what is prunable and enforcing the report-first / per-category-confirm posture — and **composes the _how_**: Archon's own `archon isolation` / `archon complete` commands for worktree/branch lifecycle, and the tracker that `docs/agents/issue-tracker.md` § Access names, for PR and branch state. -Compose those tools — never reimplement them, and never introduce a `tracker-adapter` lib -([ADR-0016](docs/adr/0016-dlc-thin-process-layer.md) / [ADR-0018](docs/adr/0018-generic-core-config-compose.md)). +Compose those tools — never reimplement them, and never introduce a `tracker-adapter` lib. > **This is not `/improve-architecture`.** The name `cleanup` was repointed: the old arch-review + -> ADR-consolidation content moved to `/improve-architecture` ([ADR-0027](docs/adr/0027-improve-architecture-skill-superseding.md)). +> ADR-consolidation content moved to `/improve-architecture`. > `/cleanup` is git/Archon hygiene only — it touches no code, no ADRs, and no `arch-review.md`. **Destructive-action posture (load-bearing).** `/cleanup` **defaults to a report-only dry-run** and @@ -37,8 +34,7 @@ Follow these steps in order. Do not skip any step. `/cleanup` reads (never writes) `.archon/unic-dlc.config.yaml`. Read it with your own tools. Do not shell out to Node, do not import a Plugin module, and do not read `$CLAUDE_PLUGIN_ROOT`: an installed -Plugin ships no `node_modules`, and that variable is not set inside the Bash tool -([ADR-0023](docs/adr/0023-build-generic-red-green-refactor-loop.md) §5). The four Archon Boxes read +Plugin ships no `node_modules`, and that variable is not set inside the Bash tool. The four Archon Boxes read their config this way already; this is the same shape. Like `/improve-architecture` this is an **off-line** box, so an absent or unreadable config is @@ -63,8 +59,7 @@ this is non-blocking. Read `docs/agents/issue-tracker.md`. Its § Access names the MCP server or skill that serves this tracker and its § Addressing names the repository — read that server's own current tool list and build -each call from it, naming no provider and writing no command, subcommand or flag -([ADR-0016](docs/adr/0016-dlc-thin-process-layer.md)). Keep `TRACKER_READY` = whether the file +each call from it, naming no provider and writing no command, subcommand or flag. Keep `TRACKER_READY` = whether the file resolved. If it did not, warn that PR/branch-state detection and slug-dir pruning will be skipped (they need the tracker), then continue — this box never halts on it. @@ -115,7 +110,7 @@ the merge itself — surface only genuine leftovers. Only if `TRACKER_READY` (a slug dir's disposition depends on its PR/branch state). Using `node:fs`, list the immediate child directories of `/` (default `workflows/`). Each -child dir name is a Slug ([ADR-0015](docs/adr/0015-workflows-slug-artifact-home.md)). For each: +child dir name is a Slug. For each: - Resolve its PR/branch via the tracker + the isolation list from Step 3. - A slug dir is **prunable only if** its PR/branch is **merged or closed**. A slug with an **open diff --git a/apps/claude-code/unic-archon-dlc/commands/improve-architecture.md b/apps/claude-code/unic-archon-dlc/commands/improve-architecture.md index b61f64f4..4985d7cc 100644 --- a/apps/claude-code/unic-archon-dlc/commands/improve-architecture.md +++ b/apps/claude-code/unic-archon-dlc/commands/improve-architecture.md @@ -5,15 +5,12 @@ description: 'Off-line architecture health: surface technical + intent drift and # unic-archon-dlc:improve-architecture -> Design rationale: [ADR-0027 — `/improve-architecture` is a skill that composes Matt's method and owns ADR superseding](docs/adr/0027-improve-architecture-skill-superseding.md) (container per [ADR-0017](docs/adr/0017-container-follows-structural-need.md); compose-don't-reimplement per [ADR-0016](docs/adr/0016-dlc-thin-process-layer.md); earns-its-place per [ADR-0021](docs/adr/0021-earns-its-place-compose-verbatim.md); artifact home per [ADR-0015](docs/adr/0015-workflows-slug-artifact-home.md); tracker/ADRs are the source of truth per [ADR-0013](docs/adr/0013-tracker-single-source-of-truth.md)). - **Arguments:** "$ARGUMENTS" `/improve-architecture` is an **off-line, on-demand** box: it surfaces architectural drift + deepening opportunities and **consolidates ADRs (including superseding older ones)**. It runs off the main line — periodically or when you sense drift, **not** per-feature and **not** as an end-of-cycle -auto-hook. It is an **in-session command/skill** because design grilling needs the live conversation -(inherently HITL — [ADR-0017](docs/adr/0017-container-follows-structural-need.md)). +auto-hook. It is an **in-session command/skill** because design grilling needs the live conversation. It is a **thin composing wrapper**: it **owns the _what_** — the DLC config binding, the durable `arch-review.md` artifact, the intent-drift pass against the PRD, and the ADR-superseding gate — and @@ -22,11 +19,11 @@ Method **verbatim**, with `codebase-design` for the architecture vocabulary, `gr walk, and `domain-modeling` to keep `CONTEXT.md` current. All four are read by path, per Step 1. -**What the DLC adds over the raw Method (why this box earns its place — [ADR-0021](docs/adr/0021-earns-its-place-compose-verbatim.md)):** +**What the DLC adds over the raw Method:** The Method produces an ephemeral HTML deepening report + a design grill for **technical** drift. On top of that this box adds (a) an **intent-drift** pass comparing the PRD's stories/acceptance criteria against what shipped, (b) a **durable `arch-review.md`** committed under the artifacts dir, -and (c) an **ADR-consolidation gate with superseding** across both ADR homes. +and (c) an **ADR-consolidation gate with superseding** across every ADR home the repository has. Follow these steps in order. Do not skip any step. @@ -34,8 +31,7 @@ Follow these steps in order. Do not skip any step. `/improve-architecture` reads (never writes) `.archon/unic-dlc.config.yaml`. Read it with your own tools. Do not shell out to Node, do not import a Plugin module, and do not read `$CLAUDE_PLUGIN_ROOT`: -an installed Plugin ships no `node_modules`, and that variable is not set inside the Bash tool -([ADR-0023](docs/adr/0023-build-generic-red-green-refactor-loop.md) §5). The four Archon Boxes read +an installed Plugin ships no `node_modules`, and that variable is not set inside the Bash tool. The four Archon Boxes read their config this way already; this is the same shape. Unlike the tracker-bound boxes this one is **off-line and touches no tracker**, so an absent or @@ -64,7 +60,7 @@ _parameters_ (which, where, whether) and this Box can sensibly default those; a _procedure_, and there is no default for that. When all four are present, print nothing and continue. That text **is** the procedure — the steps below add only the DLC layers named above, and never -restate, summarise or improve a Method ([ADR-0030](docs/adr/0030-harness-hosts-methods.md)). A Method's +restate, summarise or improve a Method. A Method's sub-files sit beside its `SKILL.md`, in the same directory: `HTML-REPORT.md` for `improve-codebase-architecture`; `DEEPENING.md` and `DESIGN-IT-TWICE.md` for `codebase-design`. @@ -102,8 +98,9 @@ Bind that procedure to the DLC: **capture-only**. Do **not** accept, number, or write any ADR during Step 3, and do not let the delegated procedure write one — instead record each proposed decision (the "accept as ADR" candidates and load-bearing rejections) as a candidate and hand it to Step 6. Step 6 is the **single place** - ADRs are written, so the A/R/E gate, MADR-lite format, both-homes numbering, and superseding/index - mechanics always apply and ADRs can never drift into an inconsistent format or bypass the gate. + ADRs are written, so the A/R/E gate, the chosen home's format and numbering, and the + superseding/index mechanics always apply. No ADR bypasses the gate or departs from its home's + format. ## Step 4 — Intent drift (DLC value-add — per-slug mode only) @@ -126,7 +123,7 @@ available for ` and continue. ## Step 5 — Write the durable arch-review report Complement the Method's ephemeral HTML (which lands in the OS temp dir) with a durable markdown artifact -committed to the repo ([ADR-0015](docs/adr/0015-workflows-slug-artifact-home.md)). All file IO via +committed to the repo. All file IO via Node `node:fs`/`node:path`. - **Per-slug mode** → `//arch-review.md` @@ -177,7 +174,7 @@ Present each candidate and wait for **A / R / E**: ``` --- ADR Candidate N of M -Proposed file: /docs/adr/NNNN-.md (home = plugin-local | repo-root) +Proposed file: /NNNN-.md (home = a docs/adr/ directory of this repository) Status: Proposed Supersedes: ADR-NNNN (omit if it supersedes nothing) Context: @@ -187,14 +184,16 @@ Consequences: Accept (A) / Reject (R) / Edit (E)? ``` -- **Choose the ADR home.** Infer from what the decision concerns and **confirm with the user**: a - decision about one plugin → that plugin's `docs/adr/` (e.g. - `apps/claude-code//docs/adr/`); a cross-cutting / monorepo-wide decision → the repo-root - `docs/adr/`. Both homes use MADR-lite (`# NNNN. Title` · `**Status:** Accepted (YYYY-MM)` · - `## Context` / `## Decision` / `## Consequences`) and per-directory zero-padded numbering — see the - root `docs/adr/README.md`. +- **Choose the ADR home** from the `docs/adr/` directories this repository already has. Find them + with your own tools, skipping `node_modules/` and other dependency trees. If there are several, + offer each one, propose the one closest to what the decision concerns, and **confirm with the + user**. If there is one, propose it and confirm. If there is none, propose the root `docs/adr/`, + which `/specs` already reads, and confirm. Follow the format and numbering the chosen home's + existing ADRs use. In an empty home, use MADR-lite + (`# NNNN. Title` · `**Status:** Accepted (YYYY-MM)` · `## Context` / `## Decision` / + `## Consequences`) and zero-padded numbering from `0001`. - **A (Accept):** compute the next `NNNN` = highest existing number in the **chosen home** + 1 (scan - that dir's files). Write the ADR. Print `ADR written: /docs/adr/NNNN-.md`. + that dir's files). Write the ADR. Print `ADR written: /NNNN-.md`. - **R (Reject):** skip. Print `ADR skipped: `. - **E (Edit):** re-show the draft, let the user revise Context / Decision / Consequences / home / Supersedes, then re-present for A/R. @@ -205,11 +204,10 @@ When an accepted ADR supersedes an existing one: 1. In the **old** ADR file, change its status line to `**Status:** Superseded by ADR-NNNN`. 2. In the **new** ADR, add a `Supersedes ADR-NNNN` reference (in the status area or Context). -3. Update the **matching home's** `README.md` index: set the **old** row's Status cell to - `Superseded by ADR-NNNN`, and add a **new** row for `NNNN`. (Each home has its own index — - plugin-local `docs/adr/README.md` and repo-root `docs/adr/README.md`.) +3. If the **matching home** has a `README.md` index, update it: set the **old** row's Status cell to + `Superseded by ADR-NNNN`, and add a **new** row for `NNNN`. Each home keeps its own index. -An ADR in one home may supersede an ADR in the other; amend whichever home(s) the two files live in. +An ADR in one home may supersede an ADR in another home. Amend each home the two files live in. ## Step 7 — Summary diff --git a/apps/claude-code/unic-archon-dlc/commands/setup.md b/apps/claude-code/unic-archon-dlc/commands/setup.md index 219d2689..f1cc003e 100644 --- a/apps/claude-code/unic-archon-dlc/commands/setup.md +++ b/apps/claude-code/unic-archon-dlc/commands/setup.md @@ -6,17 +6,12 @@ description: 'Install unic-archon-dlc into this project: copy the Boxes and the # unic-archon-dlc:setup -> Design rationale: [ADR-0019 — Conversational `/setup`](../docs/adr/0019-conversational-setup.md); -> [ADR-0036 — `/setup` owns a named install set](../docs/adr/0036-setup-owns-a-named-install-set.md) for what -> it owns and how it replaces it; [ADR-0016 — a thin process layer](../docs/adr/0016-dlc-thin-process-layer.md) -> for why this command reads the project instead of holding a list of tools. - **Arguments:** "$ARGUMENTS" `/setup` is this Plugin's installer and its sole configuration entry point. It is prose: do every action below with your own tools — Read, Write, Edit, Glob, Grep and Bash. Import nothing, shell out to no Node script, and do not read `$CLAUDE_PLUGIN_ROOT`: an installed Plugin ships no `node_modules`, and that -variable is not set inside the Bash tool ([ADR-0023](../docs/adr/0023-build-generic-red-green-refactor-loop.md) §5). +variable is not set inside the Bash tool. ## What `/setup` owns, and what it only visits @@ -33,25 +28,24 @@ every action below names which one it takes: rewrites a tenant file. **This Plugin's prefix is `unic-dlc`, and `/setup` touches no name that carries another prefix.** A -Consumer may hold Practice Packs beside this Plugin, each with its own prefix and its own installer -([ADR-0038](../docs/adr/0038-practice-packs-stack-by-prefix.md)). In `.claude/skills/`, in `.archon/packs/`, +Consumer may hold Practice Packs beside this Plugin, each with its own prefix and its own installer. In `.claude/skills/`, in `.archon/packs/`, in `CLAUDE.md` and in every formatter ignore file, `/setup` writes, overwrites or removes only these names: - a `.claude/skills/unic-dlc-*/` directory. Today `/setup` writes, overwrites or removes nothing in `.claude/skills/`. -- `.archon/packs/unic-dlc.config.yaml`. `/setup` writes nothing in `.archon/packs/` until - [Build the layered Practice Pack config](https://github.com/unic/unic-agents-plugins/issues/647) lands. The +- `.archon/packs/unic-dlc.config.yaml`. `/setup` writes nothing in `.archon/packs/` until a + later Plugin version adds the layered Practice Pack config. The Consumer's config stays at `.archon/unic-dlc.config.yaml`, as Step 6 says. - the block between the `unic-dlc:begin` and `unic-dlc:end` markers in `CLAUDE.md` and in each ignore file. Leave every other skill directory, config file and marked block as you found it, whatever it contains. The one exception is the legacy `unic-archon-dlc:begin` and `unic-archon-dlc:end` markers. They are reserved to -this Plugin (ADR-0038 §5), and Step 7 migrates a block under them. +this Plugin, and Step 7 migrates a block under them. Whether one prefix may begin another is still open, and this rule does not settle it. A pack prefixed `unic-dlc-e2e` would own `unic-dlc-e2e-*` skill directories, which also match `unic-dlc-*`. That overlap is -an open risk until ADR-0038 decides the boundary. +an open risk until a later Plugin version decides the boundary. ## Step 1 — Preflight @@ -59,8 +53,7 @@ Two checks, in this order. Each one stops the run when it fails, before any ques anything is written. **Archon.** Run `archon --version`. This Plugin's floor is **`0.7.0`** — the version whose schema carries -gates, loops, `context: fresh`, `evidence_policy` and `always_run` -([ADR-0033](../docs/adr/0033-archon-070-schema-target.md)). Compare the three numbers, never the raw strings: +gates, loops, `context: fresh`, `evidence_policy` and `always_run`. Compare the three numbers, never the raw strings: the output may carry a program name or a `v` prefix. Three ways this stops: the command is not found; the version parses and sits below the floor, so print both versions; or the output yields no three numbers at all, so print it raw and say the floor could not be checked against it. @@ -85,6 +78,9 @@ Then verify it before trusting it, and keep `PLUGIN_VERSION` from the manifest y 1. `.claude-plugin/plugin.json` there names `unic-archon-dlc`, at the same version as the registry entry. 2. `vendor/mattpocock-skills/` is present. 3. `.archon/workflows/` holds at least one `unic-dlc-*.yaml`. +4. `README.md` is present and holds all three sections later steps read from `<installPath>/README.md`: + § Dependencies, § Configuration reference and § The tracker contract. A missing section fails the + check. Name it in the stop. Print what you found and stop on any of: no entry for this Plugin, a registry whose top-level `version` is not `2`, or a failed check above. The registry entry and the manifest agreeing is the whole of the version @@ -129,7 +125,7 @@ file, so it never stops the run; the rule two reads above stops the run because destroy it. **The base branch Archon will use, verify-only.** Every Box reads a run's base branch from Archon's -`$BASE_BRANCH` and from nothing else (ADR-0039). Archon resolves it from `archon workflow run --base +`$BASE_BRANCH` and from nothing else. Archon resolves it from `archon workflow run --base <branch>`, then `worktree.baseBranch` in `.archon/config.yaml`, then the codebase's stored default branch. Each dispatch passes its own `--base`, so this command cannot see it. From the same file, keep `worktree.baseBranch` as `ARCHON_BASE_CONFIGURED`. It is empty when the key is unset or the file is @@ -147,7 +143,7 @@ independently-releasable project (a `packages/` or `apps/` tree with its own man Then set `STATE`: `fresh` when `CURRENT` is null, `partial` when `CURRENT` exists with `project.branching` unset, `full` otherwise. `project.branching` is the one key a config needs before the Boxes can read it; -every other key has a default, named in the § Configuration reference in [README.md](../README.md). +every other key has a default, named in § Configuration reference in `<installPath>/README.md`. ## Step 3 — Read the arguments @@ -177,7 +173,7 @@ and fail with their own message. Never abort the run for a missing capability. Do not probe for the Methods here. They ship inside this Plugin and Step 5 installs them; their presence is bundle integrity, not discovery. Which Method each Box reads is recorded once, in -[README.md § Dependencies](../README.md#dependencies). +§ Dependencies in `<installPath>/README.md`. **What this project runs.** One read, two harvests — read the manifests, task files and scripts this project actually runs, whatever the language, and keep both of these from that one read: @@ -207,16 +203,14 @@ board already carries. Through whichever tracker surface Step 4 found, read what Both trees come out of the directory Step 1 verified. This is the **replace** treatment: overwrite silently, every run. Every installed **Box** carries a header naming this Plugin and its version and saying that `/setup` replaces it, which is what makes an overwrite legible — an operator's edit shows up as a -tracked `git diff` after a run, not as a warning dialog -([ADR-0036](../docs/adr/0036-setup-owns-a-named-install-set.md) D3). **No Method file carries one**, and the +tracked `git diff` after a run, not as a warning dialog. **No Method file carries one**, and the Methods bullet below says why. **The Methods.** Verify the bundle at `vendor/mattpocock-skills/`, then copy it into `.archon/methods/` — the one path every Box and command reads a Method from. This Plugin alone owns `.archon/methods/`. A Practice Pack never ships a Method, and a skill a pack installs -under `.claude/skills/` is not a Method ([ADR-0038](../docs/adr/0038-practice-packs-stack-by-prefix.md) -§1 to §3). So the wholesale replace below removes nothing another installer wrote. +under `.claude/skills/` is not a Method. So the wholesale replace below removes nothing another installer wrote. **The copy flattens.** The bundle groups Methods by category, so a Method sits at `vendor/mattpocock-skills/skills/<category>/<name>/`; a Box reads `.archon/methods/<name>/SKILL.md`, one @@ -237,7 +231,7 @@ installed. - `vendor/mattpocock-skills/README.md` records the upstream repository, tag and commit this bundle was copied from. Read it and keep the tag as `BUNDLE_TAG`. - Check what the bundle **lacks**, not only what it holds: compare the Method names in it against the table - under [README.md § Dependencies](../README.md#dependencies). A Method that table names and the bundle does + under § Dependencies in `<installPath>/README.md`. A Method that table names and the bundle does not hold is a fault — report it by name and stop here, before anything is written. Keep the names you do install as `METHODS_INSTALLED` for the summary. - Copy clean: replace `.archon/methods/` wholesale, so a Method dropped from a later Plugin version cannot @@ -252,16 +246,16 @@ installed. path anything reads. Report each one you find, once, as retired, and change neither — both are the team's own work: a `.archon/methods.local/` directory, and any `methods.<name>.source` key in the config. When you report one, say that the route to replace a Box step is now an `include:` slot, decided and not yet - built, and name [ADR-0038](../docs/adr/0038-practice-packs-stack-by-prefix.md) §7 as where it is - recorded. + built. **The Boxes.** Install every `unic-dlc-*.yaml` this Plugin ships into `.archon/workflows/`, discovered by -reading the Plugin's own `.archon/workflows/` — no Box name is a literal in this file. +reading the Plugin's own `.archon/workflows/`. The install takes no Box name from this file. Only the +`CLAUDE.md` block below lists the Boxes by name. Install is **name-scoped, never a whole-directory replace**: `.archon/workflows/` is shared with the Consumer's own workflows, so only names matching `unic-dlc-*.yaml` are read, written, overwritten or swept. A file named outside that pattern stays untouched whatever it contains — that is what makes the variant -escape hatch in [README.md](../README.md) true. The sweep retires a `unic-dlc-*.yaml` this Plugin version +escape hatch in `<installPath>/README.md` true. The sweep retires a `unic-dlc-*.yaml` this Plugin version no longer ships, whether or not it carries the header: ownership is decided by name alone. Before overwriting, read the first line of each `unic-dlc-*.yaml` already on disk and keep the version it @@ -279,8 +273,7 @@ a fresh project and on a Box carrying no such line. Boxes naming **different** v install: report every version you found rather than picking one, because picking one claims an install state that never existed. -`/setup` writes nothing into `.archon/commands/`. The Box command docs live at `docs/boxes/` in this -Plugin's own repository, as operator documentation. +`/setup` writes nothing into `.archon/commands/`. Keep `WORKFLOWS_WRITTEN`, `WORKFLOWS_ADDED` and `WORKFLOWS_REMOVED` for Step 8. @@ -307,7 +300,7 @@ Which gaps: `STATE = 'fresh'` → every field; `STATE = 'partial'` → the missi decide which already-set fields to revisit. Surface `GIT_REMOTE` as a hint while asking. Pass `REPO_LAYOUT` through without asking. -The fields, mapped onto the schema paths in the § Configuration reference in [README.md](../README.md), +The fields, mapped onto the schema paths in § Configuration reference in `<installPath>/README.md`, which is the single source of truth for every default: - **project** — `project.name`; `project.branching` (`gitflow | github-flow`, mandatory); @@ -360,7 +353,7 @@ human reads this file. Keep the path as `CONFIG_PATH`. ### The tracker contract Two files: `docs/agents/issue-tracker.md` and `docs/agents/triage-labels.md`. Every Box reads a tracker -fact from these and from nothing else. § **The tracker contract** in [README.md](../README.md) states what +fact from these and from nothing else. § **The tracker contract** in `<installPath>/README.md` states what each file carries, the `Axis`/`Holds` columns, the rule that a row with no axis writes nothing, and a table shape that satisfies it. Read it and follow it: those columns and their rules are stated there, and this step does not repeat them. @@ -452,15 +445,27 @@ anything between the markers is replaced on the next run. `/unic-archon-dlc:setup` replaces them on every run. - **Methods** — `.archon/methods/` is replaced wholesale on every `/unic-archon-dlc:setup` run. To change a Method, edit the file there and expect the next run to overwrite it. -- **What each box does** — - <https://github.com/unic/unic-agents-plugins/blob/main/apps/claude-code/unic-archon-dlc/README.md> +- **What each box does**: + - `unic-dlc-explore` researches a topic in parallel, writes `findings.md` for `/specs` and runs one + spike. It is optional. It offers to keep the spike code on a branch only when `gates.explore` is + `hitl`. + - `unic-dlc-build` implements each slice in `issues.json` test-first, then verifies, pushes, and + opens a PR when the verdict is `pass`. It pauses for a human to review that PR only when + `gates.build` is `hitl`. + - `unic-dlc-pr-review` reviews a PR against the repository's standards and the linked work items, + and posts the findings. It asks a human to confirm first only when `gates.pr-review` is `hitl`. + - `unic-dlc-qa` runs the tests, e2e and coverage checks, and merges the PR only when the tests pass, + no other check fails, and the PR is open against the right base. It asks for UAT sign-off and a + merge confirmation only when `gates.qa` is `hitl`. It files a UAT defect as an agent-ready + tracker item. <!-- unic-dlc:end --> ``` -The block names one command, `/unic-archon-dlc:setup`, and no pipeline stage: a Plugin release renames and -reorders both without touching this repository. Everything it carries is a path the reader can open, a -command they can run, or a link. +The block names one command, `/unic-archon-dlc:setup`, and one hand-kept line per Box. `/setup` rewrites +the block on every run, so a Box renamed or dropped in a Plugin release reaches this repository on its +next run. Everything it carries is a path the reader can open, a command they can run, or a line that +says what a Box does. ### The formatter exclusions @@ -561,8 +566,7 @@ The line is informational and gates nothing. Step 5 runs unattended on the upgra becomes a prompt. Close with three things. Every `ACTION REQUIRED` entry, from the formatters or the blocks. These are the -open items that outlive a successful run. Then: **commit what this run wrote.** The installed trees are committed generated files -([ADR-0036](../docs/adr/0036-setup-owns-a-named-install-set.md) D4) — that is what gives a Plugin upgrade a +open items that outlive a successful run. Then: **commit what this run wrote.** The installed trees are committed generated files — that is what gives a Plugin upgrade a diff and a reviewer, and what makes an operator's edit to a Box legible as a `git diff` after the next run. This command stages nothing itself. And: **re-run `/unic-archon-dlc:setup` after updating the plugin.** It refreshes the Boxes and the Methods and leaves every tenant-owned file alone. diff --git a/apps/claude-code/unic-archon-dlc/commands/specs.md b/apps/claude-code/unic-archon-dlc/commands/specs.md index 04f85cfb..70f51bbb 100644 --- a/apps/claude-code/unic-archon-dlc/commands/specs.md +++ b/apps/claude-code/unic-archon-dlc/commands/specs.md @@ -5,13 +5,11 @@ description: 'Turn an idea (or an existing spec / design / UX) into one human-ap # unic-archon-dlc:specs -> Design rationale: [ADR-0020 — `/specs` reaches an aligned PRD by branch-on-input](docs/adr/0020-specs-branch-on-input.md) (container per [ADR-0017](docs/adr/0017-container-follows-structural-need.md); compose-don't-reimplement per [ADR-0016](docs/adr/0016-dlc-thin-process-layer.md); template-in-config per [ADR-0018](docs/adr/0018-generic-core-config-compose.md)). - **Arguments:** "$ARGUMENTS" `/specs` is the **first main-line box**: it turns an idea into **one human-approved PRD** by the cheapest path given what already exists, then hands off to `/tickets`. It is an **in-session -command/skill** (grilling needs the live conversation — ADR-0017), and it **owns the _what_** (the +command/skill** (grilling needs the live conversation), and it **owns the _what_** (the branch-on-input flow, the seam-approval halt, the PRD shape) while **composing the _how_**: the `to-spec`, `grilling` and `domain-modeling` Methods for the conversation — read by path, per Step 1 — and the configured docs / design / tracker system-skill (MCP-first, CLI-fallback) to read an @@ -26,8 +24,7 @@ its screenshot beside it. Everything else is conversation, until the gate in Ste `/specs` reads (never writes) `.archon/unic-dlc.config.yaml`. Read it with your own tools. Do not shell out to Node, do not import a Plugin module, and do not read `$CLAUDE_PLUGIN_ROOT`: an installed Plugin -ships no `node_modules`, and that variable is not set inside the Bash tool -([ADR-0023](docs/adr/0023-build-generic-red-green-refactor-loop.md) §5). The four Archon Boxes read +ships no `node_modules`, and that variable is not set inside the Bash tool. The four Archon Boxes read their config this way already; this is the same shape. If the file is absent or unreadable, print @@ -53,7 +50,7 @@ tracker item. Read it then: - **Access** — its § Access names the MCP server or skill that serves this tracker. Read that server's own current tool list and build the call from it. Name no provider and write no command, subcommand - or flag ([ADR-0016](docs/adr/0016-dlc-thin-process-layer.md)). + or flag. - **Addressing** — its § Addressing names the repository this run acts on. Name it explicitly, and derive nothing from a remote URL. - **Work-item scope** — its § Work-item scope names the filter every search applies. @@ -108,7 +105,7 @@ three is absent, print that exact path followed by `Run /unic-archon-dlc:setup.` cannot run a procedure it cannot read. When all three are present, print nothing and continue. That text **is** the procedure — the steps below add only what the Harness owns, and never restate, -summarise or improve a Method ([ADR-0030](docs/adr/0030-harness-hosts-methods.md)). A Method's +summarise or improve a Method. A Method's sub-files sit beside its `SKILL.md`, in the same directory. ## Step 2 — Slug + re-entry @@ -128,7 +125,7 @@ Ground yourself before grilling. Read, if present: root `CONTEXT.md` / `CONTEXT- prior `/explore` run). Summarise the **Domain Model**, **Established Decisions**, and **Prior Research** you found — this is the backdrop every question and the PRD must respect. -## Step 4 — Branch on input (ADR-0020) +## Step 4 — Branch on input Classify `SOURCE` into one of **two** values, and keep the one you chose as `INPUT`: @@ -246,7 +243,7 @@ Two things in `to-spec` are **overridden** here, because the Harness owns them: `/setup-matt-pocock-skills` if not" fallback never applies. `docs/agents/issue-tracker.md` and `docs/agents/triage-labels.md` are that vocabulary, and `setup-matt-pocock-skills` must not be run over them: it writes another host's template over the first and reverts the second to a five-role - `wontfix` vocabulary ([ADR-0024](docs/adr/0024-triage-intake-on-ramp.md)). + `wontfix` vocabulary. Check the rendered PRD against the active template before you write anything: every `##` heading in `PRD_TEMPLATE` must appear in the content. When `PRD_TEMPLATE` is unset, these seven are the required @@ -286,7 +283,7 @@ _Generated by unic-archon-dlc /specs._ <!-- Anything else worth recording. --> ``` -A team overrides the shape in `templates.prd` ([ADR-0018](docs/adr/0018-generic-core-config-compose.md)); +A team overrides the shape in `templates.prd`; the default text lives here, in the one Box that writes a PRD. If a heading is missing, fill that section and check again. Never write a partial PRD. @@ -414,7 +411,7 @@ tool: them reads as though someone looked and found nothing. - **A component is keyed on the stable identity `DESIGN_DOC` names, never on its name.** One name repeats inside a single design file — measured 2026-08-25 on the Consumer's file: one name carried by - four distinct components ([#404](https://github.com/unic/unic-agents-plugins/issues/404)) — so a name + four distinct components — so a name key is ambiguous today, not in theory. Record the name as a label. #### What a contract holds @@ -548,8 +545,7 @@ Both gates stage the **same named paths**, and nothing else: - each design contract Step 7 wrote, by its own path, and the screenshot beside it — one `git add` per file. A contract is staged with the PRD it belongs to and reaches the same review, which is the only place a human sees it before it is used. **An asset a contract needs is committed as bytes, never as - a link**: an exported asset URL expires seven days after it is issued (measured 2026-08-25, - [#405](https://github.com/unic/unic-agents-plugins/issues/405)), so a + a link**: an exported asset URL expires seven days after it is issued (measured 2026-08-25), so a committed link is dead within the week and dead in a way that looks like an asset nobody drew. **Staging rule — named paths only.** Run one `git add <path>` per path above. Never `git add -A`, @@ -576,8 +572,7 @@ the named paths. Unstage anything else with `git restore --staged <path>` and sa `develop`, title `plan(<SLUG>): PRD and ADRs`, body `<why + summary>`. Name that repository explicitly and derive nothing from a remote URL. Reach the host through the server its § Access names, reading that server's own current tool list to build the call: write no command, subcommand - or flag here and name no provider — this Box owns the _what_ and none of the _how_ - ([ADR-0016](docs/adr/0016-dlc-thin-process-layer.md)). If the tracker contract is absent, or the + or flag here and name no provider — this Box owns the _what_ and none of the _how_. If the tracker contract is absent, or the server cannot target a repository explicitly, stop and say which of the two it was rather than opening the PR. diff --git a/apps/claude-code/unic-archon-dlc/commands/tickets.md b/apps/claude-code/unic-archon-dlc/commands/tickets.md index b3d94d05..652413f0 100644 --- a/apps/claude-code/unic-archon-dlc/commands/tickets.md +++ b/apps/claude-code/unic-archon-dlc/commands/tickets.md @@ -5,22 +5,19 @@ description: 'Decompose an approved PRD into independently-grabbable vertical-sl # unic-archon-dlc:tickets -> Design rationale: [ADR-0022 — `/tickets` slices a PRD into build-ready issues](docs/adr/0022-tickets-slice-to-build.md) (container per [ADR-0017](docs/adr/0017-container-follows-structural-need.md); compose-don't-reimplement per [ADR-0016](docs/adr/0016-dlc-thin-process-layer.md); generic-core + config per [ADR-0018](docs/adr/0018-generic-core-config-compose.md); red/green contract per [ADR-0012](docs/adr/0012-fresh-context-red-green-separation.md)). - **Arguments:** "$ARGUMENTS" `/tickets` is the **second main-line box**: it turns one approved PRD into a set of **independently-grabbable vertical tracer-bullet slices**, makes each slice build-ready (a test seam per slice), validates the whole set, publishes the issues to the team's tracker, and stops at the -tickets gate. It is an **in-session command/skill** (slicing is a live conversation — ADR-0017), and +tickets gate. It is an **in-session command/skill** (slicing is a live conversation), and it **owns the _what_** (the slicing flow, the build-ready checks, the DAG of `blocked_by` edges) while **composing the _how_**: the `to-tickets` Method for slicing — read by path, per Step 1 — and the configured **tracker system-skill** (MCP-first, CLI-fallback) for publishing. `/tickets` **stops at a build-ready `issues.json`** (dependency-ordered, each slice carrying its acceptance criteria + test command) plus the published tracker issues. It does **not** generate a -build workflow: `/build` (step 06) consumes `issues.json` directly via a generic loop -([ADR-0022](docs/adr/0022-tickets-slice-to-build.md)). Intent lives on the tracker issue (contract C) +build workflow: `/build` consumes `issues.json` directly via a generic loop. Intent lives on the tracker issue **and** in `issues.json` (the durable baton `/build` reads). Follow these steps in order. Do not skip any step. The only files you write are `issues.json` @@ -31,8 +28,7 @@ the gate in Step 10. `/tickets` reads (never writes) `.archon/unic-dlc.config.yaml`. Read it with your own tools. Do not shell out to Node, do not import a Plugin module, and do not read `$CLAUDE_PLUGIN_ROOT`: an installed -Plugin ships no `node_modules`, and that variable is not set inside the Bash tool -([ADR-0023](docs/adr/0023-build-generic-red-green-refactor-loop.md) §5). The four Archon Boxes read +Plugin ships no `node_modules`, and that variable is not set inside the Bash tool. The four Archon Boxes read their config this way already; this is the same shape. If the file is absent or unreadable, print @@ -57,7 +53,7 @@ print `This repository has no tracker contract at docs/agents/. Run /unic-archon - **Access** — `issue-tracker.md` § Access names the MCP server or skill that serves this tracker. Read that server's own current tool list and build every call from it. Name no provider and write no - command, subcommand or flag ([ADR-0016](docs/adr/0016-dlc-thin-process-layer.md)). + command, subcommand or flag. - **Addressing** — its § Addressing names the repository this run publishes to and opens its PR against. Name it explicitly in every call, and derive nothing from a remote URL. - **Work-item scope** — its § Work-item scope names the one filter every search applies, and the scope @@ -84,7 +80,7 @@ absent, print that exact path followed by `Run /unic-archon-dlc:setup.` and **st a procedure it cannot read. When it is present, print nothing and continue. That text **is** the slicing procedure — the steps below add only what the Harness owns, and never -restate, summarise or improve a Method ([ADR-0030](docs/adr/0030-harness-hosts-methods.md)). +restate, summarise or improve a Method. ## Step 2 — Slug + re-entry @@ -116,8 +112,9 @@ Three things the Harness adds or overrides on top of it: - **Granularity litmus (the DLC's "thin enough" test):** one slice = **one demoable behaviour** — thin enough that a single failing test can capture it and a minimal implementation can satisfy it, so - strict red/green (contract B) is safe. If a slice needs more than one failing test to express its - behaviour, or bundles two independently-demoable behaviours, split it. If a slice can't be + strict red/green is safe. In strict red/green, separate fresh sessions write the failing test and + the implementation. If a slice needs more than one failing test to express its behaviour, or + bundles two independently-demoable behaviours, split it. If a slice can't be demonstrated without another, wire the dependency instead of merging. The litmus does **not** apply to the Method's **wide-refactor** exception: an expand–contract sequence is not a tracer bullet by design, and green is promised where the Method says it is. @@ -129,8 +126,7 @@ Three things the Harness adds or overrides on top of it: tracker items (Step 9). Its closing "work the frontier one ticket at a time with `/implement`" maps to `/unic-archon-dlc:build`. And its "run `/setup-matt-pocock-skills` if not" fallback never applies — Step 1 read the vocabulary from `docs/agents/triage-labels.md`, which is the file that - skill would overwrite, with a five-role `wontfix` vocabulary that drops every mapping - ([ADR-0024](docs/adr/0024-triage-intake-on-ramp.md)). + skill would overwrite, with a five-role `wontfix` vocabulary that drops every mapping. Draft each slice with these fields (Step 8 checks them): @@ -189,7 +185,7 @@ fails, propose fixes and re-present; iterate until the user approves (or explici ## Step 7 — Definitive estimation (config-gated) -If `ESTIMATIONS` is `definitive` or `both`, **compose** an estimator (never build one — ADR-0021) to +If `ESTIMATIONS` is `definitive` or `both`, **compose** an estimator (never build one) to attach a **definitive** per-slice estimate, refining any provisional estimate from `/specs`. If `ESTIMATIONS` is `off` or `provisional`, skip this step. @@ -231,7 +227,7 @@ each item can reference the real tracker ids of its blockers. For each slice, build the body from `ISSUE_TEMPLATE` (use `BUG_TEMPLATE` for `type: bug`; fall back to the `to-tickets` Method's issue template if the config template is null). The body MUST carry -the slice's **acceptance criteria** (contract C — intent lives on the tracker item) and its +the slice's **acceptance criteria** (intent lives on the tracker item) and its **Blocked by** references (real tracker ids, or "None — can start immediately"). Write the `ready-for-agent` state role unless the user says otherwise. Do NOT close or modify any parent item. diff --git a/apps/claude-code/unic-archon-dlc/commands/triage.md b/apps/claude-code/unic-archon-dlc/commands/triage.md index 5ee87261..720bdf7c 100644 --- a/apps/claude-code/unic-archon-dlc/commands/triage.md +++ b/apps/claude-code/unic-archon-dlc/commands/triage.md @@ -5,14 +5,12 @@ description: "Intake on-ramp: turn a raw bug/request/QA-finding/external-PR into # unic-archon-dlc:triage -> Design rationale: [ADR-0024 — `/triage` is the intake on-ramp](docs/adr/0024-triage-intake-on-ramp.md) (container per [ADR-0017](docs/adr/0017-container-follows-structural-need.md); compose-don't-reimplement per [ADR-0016](docs/adr/0016-dlc-thin-process-layer.md); generic-core + config per [ADR-0018](docs/adr/0018-generic-core-config-compose.md); tracker is the single source of truth per [ADR-0013](docs/adr/0013-tracker-single-source-of-truth.md); earns-its-place per [ADR-0021](docs/adr/0021-earns-its-place-compose-verbatim.md)). - **Arguments:** "$ARGUMENTS" `/triage` is an **intake on-ramp**: it turns RAW incoming work (bug reports, feature requests, QA findings, external PRs) into **agent-ready issues on the team's tracker**, feeding the `/tickets` convergence point. It is an **in-session command/skill** (triage is a live conversation, inherently -HITL — [ADR-0017](docs/adr/0017-container-follows-structural-need.md)). +HITL). It is a **thin binding wrapper**: it **owns the _what_** — the DLC config binding and the on-ramp contract — and **delegates the procedure** to the `triage` Method verbatim, with `grilling` and @@ -26,8 +24,7 @@ and a file, and never an organisation, a field or a provider. `/unic-archon-dlc:setup` owns both files. `setup-matt-pocock-skills` is **not** a dependency of this plugin and must not be run over them: it writes another host's template over the first and reverts the -second to a five-role `wontfix` vocabulary. See -[ADR-0024](docs/adr/0024-triage-intake-on-ramp.md). +second to a five-role `wontfix` vocabulary. `/triage` writes **only** to the tracker (labels + comments) and, on a rejected enhancement, to the out-of-scope knowledge base. It produces **no** `issues.json` / PRD — a triaged `ready-for-agent` @@ -40,8 +37,7 @@ Follow these steps in order. Do not skip any step. `/triage` reads (never writes) `.archon/unic-dlc.config.yaml`. Read it with your own tools. Do not shell out to Node, do not import a Plugin module, and do not read `$CLAUDE_PLUGIN_ROOT`: an installed Plugin -ships no `node_modules`, and that variable is not set inside the Bash tool -([ADR-0023](docs/adr/0023-build-generic-red-green-refactor-loop.md) §5). The four Archon Boxes read +ships no `node_modules`, and that variable is not set inside the Bash tool. The four Archon Boxes read their config this way already; this is the same shape. If the file is absent or unreadable, print @@ -69,7 +65,7 @@ three is absent, print that exact path followed by `Run /unic-archon-dlc:setup.` cannot run a procedure it cannot read. When all three are present, print nothing and continue. That text **is** the procedure — this wrapper adds only the config binding, and never restates, -summarises or improves a Method ([ADR-0030](docs/adr/0030-harness-hosts-methods.md)). The `triage` +summarises or improves a Method. The `triage` Method's `AGENT-BRIEF.md` and `OUT-OF-SCOPE.md` sit beside its `SKILL.md`, in the same directory. ## Step 2 — Read the tracker contract and build the injected context @@ -81,8 +77,7 @@ do not guess a role value and do not run `setup-matt-pocock-skills`. - **Access** — `issue-tracker.md` § Access names the MCP server or skill that serves this tracker. Read that server's own current tool list and build every call from it. Name no provider and write no - command, subcommand or flag: a flag table written down here is stale the moment the tool changes - ([ADR-0016](docs/adr/0016-dlc-thin-process-layer.md)). + command, subcommand or flag: a flag table written down here is stale the moment the tool changes. - **Addressing** — its § Addressing names the repository to act on. Name it explicitly in every call, and derive nothing from a remote URL. - **Work-item scope** — its § Work-item scope names the one filter every search applies. A search that @@ -121,8 +116,7 @@ calls for grilling, follow the `grilling` and `domain-modeling` Methods. Bind that procedure to the DLC with the Step 2 context, and enforce these overrides: -- **Roles** resolve through `docs/agents/triage-labels.md`, each row naming the axis that carries it - ([ADR-0024](docs/adr/0024-triage-intake-on-ramp.md)). Write the value and the axis that file +- **Roles** resolve through `docs/agents/triage-labels.md`, each row naming the axis that carries it. Write the value and the axis that file gives; invent neither. - **`AGENT-BRIEF.md` is written for GitHub** and names `ready-for-agent` and `wontfix` as literal labels. Read those as canonical roles too, resolve them through `triage-labels.md`, and apply the @@ -147,7 +141,7 @@ Bind that procedure to the DLC with the Step 2 context, and enforce these overri Apply the agreed outcome (a human is present — write directly, no PR gate): - **`ready-for-agent`** — post the agent brief comment and write the `ready-for-agent` state role. - The brief is the durable intent baton (contract C — intent lives on the tracker item). + The brief is the durable intent baton (intent lives on the tracker item). - **`ready-for-human`** — agent-brief structure, plus a note on why it can't be delegated. - **`needs-info`** — post the Triage Notes (established / still-needed), write `needs-info`. - **`needs-specs`** — write `needs-specs`; the item needs a PRD before slicing. Point the user to diff --git a/apps/claude-code/unic-archon-dlc/package.json b/apps/claude-code/unic-archon-dlc/package.json index 33ffd387..aa7a5401 100644 --- a/apps/claude-code/unic-archon-dlc/package.json +++ b/apps/claude-code/unic-archon-dlc/package.json @@ -1,6 +1,6 @@ { "name": "unic-archon-dlc", - "version": "0.36.0", + "version": "0.36.1", "private": true, "license": "LGPL-3.0-or-later", "type": "module", diff --git a/apps/claude-code/unic-archon-dlc/vendor/mattpocock-skills/README.md b/apps/claude-code/unic-archon-dlc/vendor/mattpocock-skills/README.md index de869521..cbdba21a 100644 --- a/apps/claude-code/unic-archon-dlc/vendor/mattpocock-skills/README.md +++ b/apps/claude-code/unic-archon-dlc/vendor/mattpocock-skills/README.md @@ -15,9 +15,7 @@ the one path every Box and every command reads a Method from. | Commit | `d574778f94cf620fcc8ce741584093bc650a61d3` | | Licence | MIT — see [`LICENSE`](LICENSE) | -**This table is the provenance.** It used to mirror a `METHODS_BUNDLE` constant in -`lib/methods-manifest.mjs`, with a test holding the two together; #381 deleted the plugin's code, so -the mirror and the test are gone and these four values live here alone. Update them in the same commit +**This table is the provenance.** These four values live here alone. Update them in the same commit that replaces the vendored files — nothing else records the tag, and nothing checks that this file still describes what sits beside it. @@ -25,30 +23,28 @@ still describes what sits beside it. `skills/` mirrors the upstream directory layout (`skills/<category>/<name>/`). Mirroring rather than flattening is what makes a re-vendoring diffable against upstream by eye — which is now the only check -there is. The closure test that caught an upstream relocation went with the manifest (#381), so +there is. The closure test that caught an upstream relocation went with the manifest, so **upgrading this bundle means diffing this tree against the new upstream tag by hand**, in the commit -that moves the pin above. The root `AGENTS.md` § "The quality bar for a prose Box" names that as the -moment the check happens. +that moves the pin above. That diff is the only moment the check happens. Eleven Methods and their sub-files are vendored. `handoff` and `prototype` are deliberately absent: the Boxes name them in prose for a human to run and never read their files. Which Box reads which Method is recorded once, in the table under [`../../README.md` § Dependencies](../../README.md#dependencies). -`skills/**` is listed in the repository's root `.prettierignore` so the pinned text stays -byte-identical to upstream. This file is not, so it is Prettier-formatted like the rest of the repo. +Keep `skills/**` out of every formatter, so the pinned text stays byte-identical to upstream. This +file is not pinned text, so a formatter may touch it. ## Licence -Upstream is MIT. [`LICENSE`](LICENSE) is the upstream licence file, verbatim; `/setup` verifies its -SHA-256 against `METHODS_BUNDLE.licenceSha256` before installing anything. MIT requires only that +Upstream is MIT. [`LICENSE`](LICENSE) is the upstream licence file, verbatim; `/setup` checks that +it is present before installing anything. MIT requires only that the copyright notice and the permission notice accompany copies, and that file carries both, so no `NOTICE` file is needed. The `LICENSE` file is maintainer-owned: never create, copy, or delete it. ## Re-vendoring Fetch with `git clone --depth 1 --branch <tag> https://github.com/mattpocock/skills` into a temp -directory and copy each manifest entry's directory across. Never use `npx skills` — its +directory and copy each vendored Method's directory across. Never use `npx skills` — its `owner/repo@tag` form silently resolves `main`. -Then update `METHODS_BUNDLE` (tag, commit, and `licenceSha256` if upstream's `LICENSE` changed) and -this file's provenance table, and re-run `pnpm --filter unic-archon-dlc test`. +Then update this file's provenance table.