{"slug":"decision-lifecycle-3","title":"decision-lifecycle","summary":"Author and track Architecture Decision Records. Routed to when the user invokes /adr to record a new decision or /adr-status to list ADR health. Authors numbered, dated, user-attributed ADRs under .codearbiter/decisions/, maintains supersede chains, and reports status read-only. ","platform":"Claude","tags":[],"authorName":"LLM Mart","authorSlug":"llm-mart","score":0,"source":"github","price":null,"verified":false,"createdAt":"2026-08-24T16:57:05.276139Z","repo":{"url":"https://github.com/arbiterForge/codeArbiter","stars":145,"forks":7,"license":"AGPL-3.0","updatedAt":"2026-09-27T13:54:01Z"},"bodyHtml":"<hr>\n<h2>name: decision-lifecycle\ndescription: Author and track Architecture Decision Records. Routed to when the user invokes /adr to record a new decision or /adr-status to list ADR health. Authors numbered, dated, user-attributed ADRs under .codearbiter/decisions/, maintains supersede chains, and reports status read-only. Never authors an ADR as its own judgment — every ADR carries explicit user attribution.</h2>\n<h1>decision-lifecycle</h1>\n<p>Author and track ADRs. Routed to when the user invokes <code>/adr \"&lt;title&gt;\"</code> (author a new ADR) or <code>/adr-status [--adr N]</code> (list ADR health, read-only). Every ADR is user-attributed — this skill never records a decision the user did not explicitly make.</p>\n<p>The append-only decision-log format (entry fields, supersession protocol) lives in <code>${CLAUDE_PLUGIN_ROOT}/includes/smarts/decision-log-format.md</code>. Read it before writing a log line; do not restate it here.</p>\n<p><strong>Boundary with <code>decision-variance</code>.</strong> This skill owns ADR <em>authoring</em> and <em>status</em> (<code>/adr</code>, <code>/adr-status</code>) — recording a decision the user has already made, and reporting ADR health. <code>decision-variance</code> owns <em>arbitration</em> — detecting variances between artifacts and the scaffold, scoring options via SMARTS, and the decision log itself. The two share the canonical SMARTS reference under <code>${CLAUDE_PLUGIN_ROOT}/includes/smarts/</code> (<code>core.md</code> for scoring, <code>decision-log-format.md</code> for the log) and one ADR template (<code>references/adr-template.md</code>); they are one domain split by responsibility, not duplicated. When a decision needs <em>making</em> (competing options), route to <code>decision-variance</code>; when it needs <em>recording</em> (already decided), stay here.</p>\n<h2>Pre-flight</h2>\n<p>Read these, or STOP and surface the gap — never guess a path:</p>\n<ul>\n<li><code>&lt;project-root&gt;/.codearbiter/decisions/</code> — the ADR directory and existing records. Create it on first <code>/adr</code> if absent.</li>\n<li>For <code>/adr</code>: confirm the user explicitly authorized this decision and supplied (or confirmed) its content. An ADR is never authored as the disposition of a routine finding.</li>\n</ul>\n<h2>Phase 1 — Index · gate: BLOCK</h2>\n<p>Scan <code>&lt;project-root&gt;/.codearbiter/decisions/</code> for existing <code>NNNN-*.md</code> ADR files. Record each by <strong>filename stem</strong> (<code>0014-githook-shim-dropin-fail-closed</code>), title, and status. Determine the next sequential number (no gaps) for <code>/adr</code>; for <code>/adr-status</code> this is the working set.</p>\n<p><strong>The stem is the identifier; the number is only a sort key.</strong> Two ADRs may already share a number — this repository holds two numbered 0014 — so a bare number can name more than one document. Index by stem, and never assume <code>NNNN</code> resolves to one file until you have checked.</p>\n<p>Gate: the existing ADRs are indexed by stem and, for <code>/adr</code>, the next number is fixed and <strong>unused</strong> — a number already taken by an existing stem is not available, even for an unrelated decision.</p>\n<h2>Phase 2 — Author (/adr) · gate: STOP</h2>\n<p>Confirm the decision content with the user — context, the decision itself, alternatives, consequences. MUST NOT fill these from inference. Surface any unknown as an inline <code>[CONFIRM-NN]</code> placeholder; do not resolve it by guessing.</p>\n<p><strong>Drop the authoring marker first.</strong> The <code>pre-write</code>/<code>pre-edit</code> hooks block any write to <code>.codearbiter/decisions/NNNN-*.md</code> unless a fresh authoring marker is present — that block is the mechanism enforcing \"ADRs only via <code>/adr</code>\" (arbiter.md §3), so the sanctioned path must arm it itself. Immediately before writing, create the marker at the path the hooks check (project root = git top level):</p>\n<pre><code>mkdir -p \"$(git rev-parse --show-toplevel)/.codearbiter/.markers\"\ntouch \"$(git rev-parse --show-toplevel)/.codearbiter/.markers/adr-authoring-active\"\n</code></pre>\n<p>The marker is honored for 30 minutes. Then write <code>&lt;project-root&gt;/.codearbiter/decisions/NNNN-&lt;slug&gt;.md</code> using the canonical ADR template — <code>${CLAUDE_PLUGIN_ROOT}/routines/decision-lifecycle/references/adr-template.md</code> (the single source of truth for the ADR shape, shared with <code>decompose</code>). Author it with <code>status: proposed</code>. If this decision supersedes an existing one, set <code>supersedes:</code> to that ADR's <strong>full filename stem</strong> — <code>supersedes: 0014-githook-shim-dropin-fail-closed</code>, never <code>supersedes: 0014</code> — and leave the prior ADR's file untouched (forward-only chain — do not edit it to add a back-reference).</p>\n<p>If the new ADR supersedes only <em>part</em> of the prior decision, say which part in the body. <code>supersedes:</code> names a document, not a clause, so a chain may legitimately fork — two ADRs can each supersede different clauses of one predecessor. That fork is correct and must not be \"repaired\"; only the prose can carry the scope.</p>\n<p>After writing the ADR, append a corresponding entry to the decision log per the format in <code>${CLAUDE_PLUGIN_ROOT}/includes/smarts/decision-log-format.md</code> — <code>Decided by:</code> names the user. Status transitions (<code>proposed → accepted → superseded | rejected</code>) require explicit user instruction; never advance status on this skill's own judgment.</p>\n<p><strong><code>governs:</code> makes the decision live.</strong> When an ADR names path globs in <code>governs:</code>, the post-write\nhook surfaces a one-line notice on any Write/Edit touching a matching file — \"this file is governed\nby ADR-NNNN\" — so a recorded decision pushes back at edit time instead of waiting for a checkpoint\nsweep. Offer the field whenever a decision constrains identifiable files; omit it for decisions\nwithout a file footprint. Globs are fnmatch-style against repo-relative forward-slash paths.</p>\n<p>Once the ADR file and its log entry are written (and any user-instructed status edit is applied), remove the marker — it exists only for one authoring pass:</p>\n<pre><code>rm -f \"$(git rev-parse --show-toplevel)/.codearbiter/.markers/adr-authoring-active\"\n</code></pre>\n<p>Gate: the ADR file is written with a real <code>decided-by</code> user attribution, numbered without a gap, and its log entry is appended. An ADR with no user attribution, or authored as the disposition of a finding, does not pass — STOP.</p>\n<h2>Phase 3 — Status (/adr-status) · gate: BLOCK</h2>\n<p>Read-only. For each ADR (or the <code>--adr N</code> target), report: stem, title, status, date, and supersession state — found by scanning forward for any later ADR whose <code>supersedes:</code> <strong>resolves to</strong> it.</p>\n<p>Resolve a <code>supersedes:</code> value like this, and never guess:</p>\n<ul>\n<li>The value is a <strong>stem</strong> → it names that ADR. Done.</li>\n<li>The value is a <strong>bare number</strong> → collect every stem with that number. Exactly one → it names that ADR. More than one → <strong>ambiguous: report it as an error and resolve nothing.</strong> Zero → a dangling reference; report that too.</li>\n<li><code>none</code> (or empty) → no predecessor.</li>\n</ul>\n<p><code>.github/scripts/check_adr_identity.py</code> enforces this same rule mechanically in CI; if it disagrees with this report, the report is wrong.</p>\n<p>If a supersession candidate contradicts an <code>accepted</code> ADR with no clear direction, do not pick one — flag it for <code>/conflict</code>.</p>\n<pre><code>## ADR Status — YYYY-MM-DD\n\n### Active\n- ADR-NNNN-&lt;slug&gt; — &lt;title&gt; — &lt;status&gt; (&lt;date&gt;)\n\n### Superseded\n- ADR-NNNN-&lt;slug&gt; — &lt;title&gt; — superseded by ADR-MMMM-&lt;slug&gt;\n\n### Ambiguous supersession\n- ADR-NNNN-&lt;slug&gt; — supersedes: &lt;value&gt; names &lt;N&gt; ADRs (&lt;stems&gt;) — unresolved\n\n### Unresolved CONFIRM-NN\n- ADR-NNNN-&lt;slug&gt; — [CONFIRM-NN]: &lt;text&gt;\n</code></pre>\n<p>Every ADR is named by its stem, so a shared number never collapses two rows into one. An empty section is marked \"None\" — not omitted. MAY dispatch <code>decision-challenger</code> (<code>${CLAUDE_PLUGIN_ROOT}/agents/decision-challenger.md</code>) to stress-test an ADR; optional, never forced.</p>\n<p>Gate: every indexed ADR appears with its current status and supersession state; no <code>[CONFIRM-NN]</code> resolved; no file modified.</p>\n<h2>Hard rules</h2>\n<ul>\n<li>MUST author an ADR only via <code>/adr</code> with explicit user attribution. MUST NOT author an ADR as the disposition of a routine finding — an out-of-scope finding gets an inline <code>[NEEDS-TRIAGE]</code> marker instead.</li>\n<li>MUST NOT record a decision the user did not explicitly make. \"Use your best judgment,\" \"I trust you\" are declined.</li>\n<li>MUST NOT resolve a <code>[CONFIRM-NN]</code> placeholder by guessing. Surface it and stop.</li>\n<li>MUST NOT advance an ADR's status without explicit user instruction.</li>\n<li>MUST NOT edit a prior ADR or a prior decision-log entry to add a back-reference — supersession is a forward-only chain; append a new record whose <code>supersedes:</code> names the prior one.</li>\n<li><strong>The never-edit rule protects decision CONTENT, not identifiers.</strong> Rewriting what was decided corrupts the record; disambiguating <em>which document a pointer names</em> repairs it. Maintainer ruling, 2026-07-25: <em>\"the never edit rule is meant to prevent this situation, not prevent this situation from being fixed.\"</em> So a correction that is provably identifier-only — a <code>supersedes:</code> value changed from a number to the stem it already meant — is permissible, and nothing else about the file is. Any such correction MUST be a single-line diff that alters not one word of any decision, MUST be visible in its own commit, and still requires the maintainer-armed <code>adr-authoring-active</code> marker. MUST NOT touch Context, Decision, Alternatives, Consequences, Risks, <code>status:</code>, <code>date:</code>, <code>decided-by:</code>, or <code>title:</code> under this allowance.</li>\n<li>MUST NOT number an ADR with a gap, and MUST NOT reuse a number an existing stem already holds — a shared number makes every bare reference to it ambiguous.</li>\n<li>MUST NOT modify any file under <code>/adr-status</code> — it is read-only.</li>\n<li>MUST NOT force the <code>decision-challenger</code> agent — its dispatch is MAY only.</li>\n</ul>\n","files":[{"path":"references/adr-template.md","sizeBytes":4288,"isText":true},{"path":"references/authoring.md","sizeBytes":13224,"isText":true},{"path":"SKILL.md","sizeBytes":6724,"isText":true}],"reviewScore":null,"reviewSummary":null,"trust":{"provenance":"trusted-source-unreviewed","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow.","bodySource":null},"bodyLocked":false,"purchaseUrl":null,"sourceUrl":null,"report":{"provenance":"trusted-source-unreviewed","screen":{"ran":true,"outcome":"clean","suspicious":0,"notes":0,"hiddenCharacters":false},"virusScan":{"engine":"clamav","status":"clean","scannedAt":"2026-09-27T19:35:07.782068Z","sha256":"DD1A03E6F2CB27DD9740D11D3AC07D510DE1A0D11739A7BDB3B492446C8158AF","sizeBytes":10707},"review":null,"source":{"repositoryUrl":"https://github.com/arbiterForge/codeArbiter","path":"plugins/ca-codex/routines/decision-lifecycle","license":"AGPL-3.0","commit":"8e88bce938ebf7dc8cfd934307b8d6859092d86e","subtreeSha":"0DA989C006B9EA8C3B6A7AB4DBAC74F6B74DAE402D7AFCF44FF43A151657C726","lastSyncedAt":"2026-09-27T19:33:31.953812Z"},"reviewedAt":"2026-09-27T19:37:50.705297Z","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow."},"install":[{"target":"skills-cli","command":"npx skills add https://github.com/arbiterForge/codeArbiter/tree/main/plugins/ca-codex/routines/decision-lifecycle"},{"target":"claude-code","command":"claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install arbiterforge-codearbiter@llmmart"},{"target":"git","command":"git clone https://github.com/arbiterForge/codeArbiter.git"}]}