Skip to content

Record an Architecture Decision

Use this guide when a choice will shape later implementation: a storage model, trust boundary, public contract, dependency policy, or other decision future work must respect. The result is a numbered record under .codearbiter/decisions/, attributed to the person who made the call and linked to the paths it governs.

Trace the ADR workflow from entry to its actual endpoint

Follow the work, not a catalog

Record a decision and bind its acceptance

This path follows an explicitly attributed decision through user-authorized acceptance. Remaining Proposed is valid. A status query and optional challenge are separate operations, not automatic authoring steps.

Rows identify roles. Gold commands enter or define a procedure; blue skills coordinate work; green agents perform bounded roles. Arrows cross rows in execution order. A dashed arrow reuses a procedure rather than calling its entry again. Dashed nodes are conditional roles selected for the work.

Chapter 1 / 2

Record the user’s choice

What did the human decide, and what is actually being recorded?

Link to this chapter
  1. command
    /ca:adr: attributed decision

    Name the decision and the person making it. A routine finding or an unresolved CONFIRM item cannot be converted into an invented architectural choice.

    Result: A named decision to record, not model-owned authority.

    authoring owner → The command routes to decision-lifecycle for numbering, attribution and writing.

    Source for step 1
  2. skill
    decision-lifecycle: index and author

    Use the next unused number and full filename stem, gather rationale and governed paths, and write the current template with status proposed.

    Result: A dated, attributed Proposed record.

    record the choice → The log entry accompanies the newly written ADR.

    Source for step 2
  3. skill
    decision-lifecycle: decision log

    Append the matching user-attributed decision-log entry. A replacement names the full predecessor stem; it does not rewrite the earlier decision.

    Result: The decision and its append-only log entry.

    only on instruction → Stop at Proposed unless the user explicitly authorizes acceptance.

    Source for step 3
  4. skill
    decision-lifecycle: accept on instruction

    Only explicit user acceptance advances status. Derive stable obligations and independently review the completeness of the sealed set before recording the binding.

    Result: Accepted/Planned content and reviewed obligations.

    Source for step 4

Before continuing: A numbered Proposed ADR and corresponding log entry. Acceptance waits for an explicit user instruction.

Continuations, returns and repeat paths
  • accepted content. The user-directed acceptance path commits its content before binding that commit. Next: commit-gate: accepted record. Owning contract

Chapter 2 / 2

Bind a commit that exists

Why are acceptance content and its binding not one invented commit?

Link to this chapter
  1. skill
    commit-gate: accepted record

    Commit the accepted ADR and decision-log append through the normal gate. The acceptance binding is deliberately not added to this commit.

    Result: An existing source commit whose bytes can now be hashed.

    hash exact source → The source commit must exist before the binding can truthfully identify it.

    Source for step 5
  2. skill
    decision-lifecycle: append acceptance

    From the exact source commit, bind the blob, immutable record and sealed obligations in the append-only lifecycle ledger. A second binding for the same stem is invalid.

    Result: An acceptance event with a real source identity.

    append then persist → Persist the event without rewriting earlier history.

    Source for step 6
  3. skill
    decision-lifecycle: subsequent commit

    Persist the binding in a subsequent commit. Later PR delivery must preserve the required source ancestry; an unqualified squash cannot stand in for it.

    Result: The retained record and acceptance binding, not implementation evidence.

    Source for step 7

Before continuing: A committed acceptance event points to the real prior source commit. Later implementation and verification require their own current evidence.

Continuations, returns and repeat paths

    The decision, decision-log append and exact acceptance binding are retained. Accepted/Planned does not prove implementation, verification or a merged PR.

    Actual endpoint: The decision, decision-log append and exact acceptance binding are retained. Accepted/Planned does not prove implementation, verification or a merged PR.

    Command labels use Claude Code spelling for the illustrated route. Codex and Pi use their own entries; shared names do not establish equal execution or authority support. Check the installed-host boundary.

    Source identity and diagram limits

    Reviewed source: 929229354e3a15ae3002c82116b66c837ab43729. The numbered stages explain one ordinary success path. The return notes retain the caller’s conditions and alternate paths. A conditional role participates only when its owning contract selects it. This route has its own endpoint. Row membership does not imply every role participates, and a source-traced relationship is not an installed-host verification.

    Open the complete three-row diagram. The reading view and image are generated from the same editorial map. They neither run tools nor record approvals.

    Open the full three-row diagram.

    Host syntax: Claude Code uses /ca:adr; Codex uses $ca-adr; Pi uses /ca-adr. Examples below use Claude Code syntax.

    • Set git config user.email. The record and decision ledger use that identity.
    • Be ready to decide the material trade-off. codeArbiter can structure and challenge the options, but it cannot attribute its own preference to you.
    • If the question is still exploratory, ask a read-only question or use a spike first. An ADR records a decision; it is not a scratchpad.

    Invoke the command with a short title:

    /ca:adr "Store durable workflow state in the repository"

    The decision-lifecycle skill gathers context, the options considered, the decision, consequences, and the paths the decision governs. Any fact only you can supply becomes a numbered [CONFIRM-NN]; it is not guessed.

    Review the proposed record. On approval, codeArbiter writes:

    .codearbiter/decisions/0017-store-durable-workflow-state.md

    The number is the next unused value in the indexed records, and the slug is derived from the title. The companion .codearbiter/decisions/decision-log.md receives the corresponding ledger entry.

    Acceptance binds a real committed definition

    Section titled “Acceptance binds a real committed definition”

    Remaining Proposed is a valid outcome. An explicit acceptance instruction moves the decision to Accepted/Planned; it is not implementation or verification. The owning lane derives stable normative obligations and independently reviews their completeness before sealing the accepted set.

    The accepted ADR and its decision-log entry are committed through the normal commit gate first. Only then can the lane hash those committed bytes and append an acceptance event to .codearbiter/adr-lifecycle.jsonl with the real source commit. That binding is persisted in a subsequent commit. It cannot truthfully point to a commit that did not yet exist, and a repeated binding for the same full stem is not a harmless rewrite.

    Inspect both records and the existing source identity. For later PR delivery, preserve the ancestry required by the installed lifecycle verifier rather than choosing an unqualified squash that discards it. Derived Implemented and Verified states need their own current obligation and evidence records. A legacy-unsealed decision keeps its narrower inspection limits; do not invent missing obligations or receipts to improve its display.

    Open the new ADR and confirm:

    • the status is accepted only if you explicitly accepted it;
    • decided-by matches your Git identity;
    • governs lists the intended path globs, not the whole repository by accident;
    • the options and consequences reflect the choice you made; and
    • any [CONFIRM-NN] still present also appears in .codearbiter/open-questions.md.

    Run /ca:adr-status --adr 17 (Codex: $ca-adr-status --adr 17) to read the decision’s current health and any challenge result.

    This is an illustrative record, not a newly accepted decision or a receipt from your repository. The owning ADR lane supplies the exact current template and lifecycle records.

    ---
    status: proposed
    decided-by: learner@example.invalid
    governs:
    - src/export/**
    ---
    # 0017: Keep CSV formatting separate from saved-search storage
    ## Context
    The export action needs stored names and queries, but should not own persistence.
    ## Decision
    The export module receives validated records and returns CSV or no payload for an empty set.
    Storage and authorization remain with their existing owners.
    ## Consequences
    Formatting can be tested without a database. The caller must supply validated records.
    ## Alternatives considered
    Let the exporter query storage directly. Rejected here because it couples formatting tests to storage.
    ## Risks
    A caller might pass unvalidated data. Test and review that boundary before claiming completion.

    Review the rationale, intended paths, omitted paths, alternatives and consequences. A glob such as ** would govern far more than this example needs. Send a separate explicit acceptance decision only after review. That acceptance is not proof the module or tests exist. Inspect implementation and current verification separately; attribution by Git email is not identity authentication.

    If the decision later changes, create its replacement through the lane rather than editing the old file to erase the previous choice.

    Do not edit history to make an old ADR look current. Create a new ADR and tell the command which accepted decision it replaces:

    /ca:adr "Move durable workflow state to a signed event store"

    The new record receives supersedes: 0017-store-durable-workflow-state, using the prior ADR’s full filename stem rather than an ambiguous bare number. The earlier file is left byte-for-byte unchanged. Supersession is a forward-only chain: the newest record names what it replaces, and the decision ledger records the transition.

    Verify the chain with:

    /ca:adr-status --adr 17
    /ca:adr-status --adr 24

    The first report should identify the newer governing decision; the second should name 0017 as its predecessor.

    StopWhy it happensWhat to do
    Git identity is missing
    Decisions require real attribution
    Set git config user.email, then invoke the command again
    A [CONFIRM-NN] is unresolved
    Only you can supply the missing fact
    Answer it, or leave the ADR proposed until you can
    The number or file already exists
    Another decision won the next sequence number
    Re-run through /ca:adr; never hand-renumber files
    A direct edit is blocked
    ADR files have a protected authoring lane
    Use /ca:adr to create a replacement or superseding record