@arbiterforge/ca-pi 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +558 -0
- package/package.json +35 -0
- package/plugins/ca-pi/CHANGELOG.md +1030 -0
- package/plugins/ca-pi/COMMANDS.md +90 -0
- package/plugins/ca-pi/ORCHESTRATOR.md +159 -0
- package/plugins/ca-pi/SKILLS.md +47 -0
- package/plugins/ca-pi/SPRINT.md +142 -0
- package/plugins/ca-pi/agents/INDEX.md +31 -0
- package/plugins/ca-pi/agents/architecture-drift-reviewer.md +86 -0
- package/plugins/ca-pi/agents/auth-crypto-reviewer.md +60 -0
- package/plugins/ca-pi/agents/backend-author.md +60 -0
- package/plugins/ca-pi/agents/checkpoint-aggregator.md +111 -0
- package/plugins/ca-pi/agents/coverage-auditor.md +71 -0
- package/plugins/ca-pi/agents/decision-challenger.md +116 -0
- package/plugins/ca-pi/agents/dependency-reviewer.md +79 -0
- package/plugins/ca-pi/agents/design-quality-reviewer.md +80 -0
- package/plugins/ca-pi/agents/finding-triage.md +86 -0
- package/plugins/ca-pi/agents/frontend-author.md +64 -0
- package/plugins/ca-pi/agents/grader.md +173 -0
- package/plugins/ca-pi/agents/infra-author.md +64 -0
- package/plugins/ca-pi/agents/map-deps.md +35 -0
- package/plugins/ca-pi/agents/map-structure.md +37 -0
- package/plugins/ca-pi/agents/migration-reviewer.md +65 -0
- package/plugins/ca-pi/agents/scout.md +127 -0
- package/plugins/ca-pi/agents/security-reviewer.md +72 -0
- package/plugins/ca-pi/agents/tribunal-lens-reviewer.md +65 -0
- package/plugins/ca-pi/extensions/codearbiter-child.js +1885 -0
- package/plugins/ca-pi/extensions/codearbiter.js +9802 -0
- package/plugins/ca-pi/generated/command-catalog.json +197 -0
- package/plugins/ca-pi/generated/roles.json +213 -0
- package/plugins/ca-pi/helpers/windows-supervisor.js +205 -0
- package/plugins/ca-pi/hooks/_activationlib.py +196 -0
- package/plugins/ca-pi/hooks/_arbiterstatelib.py +208 -0
- package/plugins/ca-pi/hooks/_babysitlib.py +76 -0
- package/plugins/ca-pi/hooks/_bashguardlib.py +1667 -0
- package/plugins/ca-pi/hooks/_boxlib.py +131 -0
- package/plugins/ca-pi/hooks/_colorlib.py +304 -0
- package/plugins/ca-pi/hooks/_durabilitylib.py +186 -0
- package/plugins/ca-pi/hooks/_entrylib.py +41 -0
- package/plugins/ca-pi/hooks/_fmtlib.py +161 -0
- package/plugins/ca-pi/hooks/_gitexec.py +45 -0
- package/plugins/ca-pi/hooks/_githooks.py +920 -0
- package/plugins/ca-pi/hooks/_gitlib.py +110 -0
- package/plugins/ca-pi/hooks/_hooklib.py +595 -0
- package/plugins/ca-pi/hooks/_host.py +115 -0
- package/plugins/ca-pi/hooks/_intentlib.py +242 -0
- package/plugins/ca-pi/hooks/_ledgerlib.py +1035 -0
- package/plugins/ca-pi/hooks/_metricslib.py +709 -0
- package/plugins/ca-pi/hooks/_pathnorm.py +74 -0
- package/plugins/ca-pi/hooks/_planfilelib.py +664 -0
- package/plugins/ca-pi/hooks/_previewlib.py +193 -0
- package/plugins/ca-pi/hooks/_protectedlib.py +312 -0
- package/plugins/ca-pi/hooks/_protectedstatelib.py +411 -0
- package/plugins/ca-pi/hooks/_provenancelib.py +971 -0
- package/plugins/ca-pi/hooks/_prunelib.py +1398 -0
- package/plugins/ca-pi/hooks/_prunepolicy.py +235 -0
- package/plugins/ca-pi/hooks/_readinjectlib.py +1080 -0
- package/plugins/ca-pi/hooks/_releaselib.py +2657 -0
- package/plugins/ca-pi/hooks/_scopelib.py +262 -0
- package/plugins/ca-pi/hooks/_segmentslib.py +278 -0
- package/plugins/ca-pi/hooks/_sensitivelib.py +270 -0
- package/plugins/ca-pi/hooks/_sessionlib.py +78 -0
- package/plugins/ca-pi/hooks/_sloplib.py +244 -0
- package/plugins/ca-pi/hooks/_standuplib.py +214 -0
- package/plugins/ca-pi/hooks/_subagentslib.py +219 -0
- package/plugins/ca-pi/hooks/_taskboardlib.py +1088 -0
- package/plugins/ca-pi/hooks/_updatelib.py +278 -0
- package/plugins/ca-pi/hooks/babysit.py +47 -0
- package/plugins/ca-pi/hooks/boardsync.py +129 -0
- package/plugins/ca-pi/hooks/doctor.py +420 -0
- package/plugins/ca-pi/hooks/git-enforce.py +325 -0
- package/plugins/ca-pi/hooks/hostapi.py +460 -0
- package/plugins/ca-pi/hooks/init-codearbiter.py +225 -0
- package/plugins/ca-pi/hooks/metrics.py +62 -0
- package/plugins/ca-pi/hooks/migration-pass.py +129 -0
- package/plugins/ca-pi/hooks/pi-bridge.py +543 -0
- package/plugins/ca-pi/hooks/post-write-edit.py +231 -0
- package/plugins/ca-pi/hooks/pre-bash.py +90 -0
- package/plugins/ca-pi/hooks/pre-edit.py +284 -0
- package/plugins/ca-pi/hooks/pre-read.py +81 -0
- package/plugins/ca-pi/hooks/pre-write.py +217 -0
- package/plugins/ca-pi/hooks/preview.py +69 -0
- package/plugins/ca-pi/hooks/prune-transcript.py +232 -0
- package/plugins/ca-pi/hooks/releasehash.py +216 -0
- package/plugins/ca-pi/hooks/security-pass.py +139 -0
- package/plugins/ca-pi/hooks/session-start.py +1218 -0
- package/plugins/ca-pi/hooks/statusline.py +736 -0
- package/plugins/ca-pi/hooks/taskwrite.py +351 -0
- package/plugins/ca-pi/hooks/update-refresh.py +51 -0
- package/plugins/ca-pi/hooks/wire-statusline.py +435 -0
- package/plugins/ca-pi/includes/anti-slop-design/INDEX.md +55 -0
- package/plugins/ca-pi/includes/anti-slop-design/color.md +43 -0
- package/plugins/ca-pi/includes/anti-slop-design/core.md +244 -0
- package/plugins/ca-pi/includes/anti-slop-design/images.md +32 -0
- package/plugins/ca-pi/includes/anti-slop-design/layout.md +45 -0
- package/plugins/ca-pi/includes/anti-slop-design/medium-cli.md +39 -0
- package/plugins/ca-pi/includes/anti-slop-design/medium-dataviz.md +43 -0
- package/plugins/ca-pi/includes/anti-slop-design/medium-diagram.md +35 -0
- package/plugins/ca-pi/includes/anti-slop-design/medium-documents.md +70 -0
- package/plugins/ca-pi/includes/anti-slop-design/medium-slides.md +30 -0
- package/plugins/ca-pi/includes/anti-slop-design/medium-web.md +39 -0
- package/plugins/ca-pi/includes/anti-slop-design/typography.md +51 -0
- package/plugins/ca-pi/includes/author-tdd-workflow.md +14 -0
- package/plugins/ca-pi/includes/compaction-charter.md +16 -0
- package/plugins/ca-pi/includes/cut-docs.md +16 -0
- package/plugins/ca-pi/includes/dev-mode.md +30 -0
- package/plugins/ca-pi/includes/farm.md +237 -0
- package/plugins/ca-pi/includes/fresh-verification.md +14 -0
- package/plugins/ca-pi/includes/harvest.md +69 -0
- package/plugins/ca-pi/includes/maturity-coverage.md +102 -0
- package/plugins/ca-pi/includes/pi-host-notes.md +69 -0
- package/plugins/ca-pi/includes/redirect.md +69 -0
- package/plugins/ca-pi/includes/reference-map.md +22 -0
- package/plugins/ca-pi/includes/review-matrix.md +14 -0
- package/plugins/ca-pi/includes/reviewer-contract.md +53 -0
- package/plugins/ca-pi/includes/routing-table.md +47 -0
- package/plugins/ca-pi/includes/security-gate-record.md +22 -0
- package/plugins/ca-pi/includes/smarts/core.md +90 -0
- package/plugins/ca-pi/includes/smarts/decision-log-format.md +56 -0
- package/plugins/ca-pi/routines/INDEX.md +32 -0
- package/plugins/ca-pi/routines/brainstorming/SKILL.md +122 -0
- package/plugins/ca-pi/routines/commit-gate/SKILL.md +151 -0
- package/plugins/ca-pi/routines/context-check/SKILL.md +85 -0
- package/plugins/ca-pi/routines/context-creation/SKILL.md +171 -0
- package/plugins/ca-pi/routines/crypto-compliance/SKILL.md +41 -0
- package/plugins/ca-pi/routines/debug/SKILL.md +99 -0
- package/plugins/ca-pi/routines/decision-lifecycle/SKILL.md +104 -0
- package/plugins/ca-pi/routines/decision-lifecycle/references/adr-template.md +74 -0
- package/plugins/ca-pi/routines/decision-variance/SKILL.md +147 -0
- package/plugins/ca-pi/routines/decompose/SKILL.md +168 -0
- package/plugins/ca-pi/routines/dispatching-parallel-agents/SKILL.md +76 -0
- package/plugins/ca-pi/routines/executing-plans/SKILL.md +83 -0
- package/plugins/ca-pi/routines/finishing-a-development-branch/SKILL.md +91 -0
- package/plugins/ca-pi/routines/post-merge-cleanup/SKILL.md +233 -0
- package/plugins/ca-pi/routines/refactor/SKILL.md +91 -0
- package/plugins/ca-pi/routines/release/SKILL.md +315 -0
- package/plugins/ca-pi/routines/secret-handling/SKILL.md +67 -0
- package/plugins/ca-pi/routines/security-architecture/SKILL.md +63 -0
- package/plugins/ca-pi/routines/skill-author/SKILL.md +108 -0
- package/plugins/ca-pi/routines/skill-author/references/skill-template.md +58 -0
- package/plugins/ca-pi/routines/subagent-driven-development/SKILL.md +149 -0
- package/plugins/ca-pi/routines/subagent-driven-development/references/farm-dispatch.md +145 -0
- package/plugins/ca-pi/routines/tdd/SKILL.md +139 -0
- package/plugins/ca-pi/routines/tribunal/SKILL.md +109 -0
- package/plugins/ca-pi/routines/tribunal/references/ai-markers.md +29 -0
- package/plugins/ca-pi/routines/tribunal/references/cost-and-models.md +64 -0
- package/plugins/ca-pi/routines/tribunal/references/finding-record.md +27 -0
- package/plugins/ca-pi/routines/tribunal/references/issue-filing.md +47 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/appsec.md +22 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/architecture.md +23 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/coverage.md +20 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/infra.md +24 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/migration.md +22 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/observability.md +21 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/performance.md +22 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/reliability.md +23 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/secrets-supply.md +22 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/test-fidelity.md +24 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/typesafety.md +21 -0
- package/plugins/ca-pi/routines/tribunal/references/report.md +19 -0
- package/plugins/ca-pi/routines/tribunal/references/schemas.md +58 -0
- package/plugins/ca-pi/routines/tribunal/references/telemetry.md +28 -0
- package/plugins/ca-pi/routines/tribunal/references/triage.md +53 -0
- package/plugins/ca-pi/routines/using-git-worktrees/SKILL.md +85 -0
- package/plugins/ca-pi/routines/writing-plans/SKILL.md +129 -0
- package/plugins/ca-pi/routines/writing-plans/references/farm-plan.md +50 -0
- package/plugins/ca-pi/skills/ca-add-dep/SKILL.md +88 -0
- package/plugins/ca-pi/skills/ca-adr/SKILL.md +30 -0
- package/plugins/ca-pi/skills/ca-adr-status/SKILL.md +30 -0
- package/plugins/ca-pi/skills/ca-arbiter/SKILL.md +36 -0
- package/plugins/ca-pi/skills/ca-audit/SKILL.md +51 -0
- package/plugins/ca-pi/skills/ca-btw/SKILL.md +23 -0
- package/plugins/ca-pi/skills/ca-checkpoint/SKILL.md +50 -0
- package/plugins/ca-pi/skills/ca-chore/SKILL.md +58 -0
- package/plugins/ca-pi/skills/ca-cleanup/SKILL.md +55 -0
- package/plugins/ca-pi/skills/ca-commands/SKILL.md +21 -0
- package/plugins/ca-pi/skills/ca-commit/SKILL.md +27 -0
- package/plugins/ca-pi/skills/ca-conflict/SKILL.md +61 -0
- package/plugins/ca-pi/skills/ca-context-check/SKILL.md +32 -0
- package/plugins/ca-pi/skills/ca-create-context/SKILL.md +32 -0
- package/plugins/ca-pi/skills/ca-debug/SKILL.md +42 -0
- package/plugins/ca-pi/skills/ca-decompose/SKILL.md +30 -0
- package/plugins/ca-pi/skills/ca-dev/SKILL.md +42 -0
- package/plugins/ca-pi/skills/ca-doctor/SKILL.md +44 -0
- package/plugins/ca-pi/skills/ca-feature/SKILL.md +105 -0
- package/plugins/ca-pi/skills/ca-fix/SKILL.md +42 -0
- package/plugins/ca-pi/skills/ca-init/SKILL.md +56 -0
- package/plugins/ca-pi/skills/ca-metrics/SKILL.md +80 -0
- package/plugins/ca-pi/skills/ca-new-skill/SKILL.md +34 -0
- package/plugins/ca-pi/skills/ca-override/SKILL.md +72 -0
- package/plugins/ca-pi/skills/ca-pr/SKILL.md +61 -0
- package/plugins/ca-pi/skills/ca-preview/SKILL.md +86 -0
- package/plugins/ca-pi/skills/ca-prune/SKILL.md +100 -0
- package/plugins/ca-pi/skills/ca-reconcile/SKILL.md +43 -0
- package/plugins/ca-pi/skills/ca-refactor/SKILL.md +43 -0
- package/plugins/ca-pi/skills/ca-release/SKILL.md +57 -0
- package/plugins/ca-pi/skills/ca-review/SKILL.md +63 -0
- package/plugins/ca-pi/skills/ca-spike/SKILL.md +41 -0
- package/plugins/ca-pi/skills/ca-sprint/SKILL.md +44 -0
- package/plugins/ca-pi/skills/ca-standup/SKILL.md +112 -0
- package/plugins/ca-pi/skills/ca-status/SKILL.md +56 -0
- package/plugins/ca-pi/skills/ca-task/SKILL.md +61 -0
- package/plugins/ca-pi/skills/ca-threat-model/SKILL.md +45 -0
- package/plugins/ca-pi/skills/ca-tribunal/SKILL.md +44 -0
- package/plugins/ca-pi/skills/ca-watch/SKILL.md +78 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: decision-lifecycle
|
|
3
|
+
description: 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.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# decision-lifecycle
|
|
7
|
+
|
|
8
|
+
Author and track ADRs. Routed to when the user invokes `/adr "<title>"` (author a new ADR) or `/adr-status [--adr N]` (list ADR health, read-only). Every ADR is user-attributed — this skill never records a decision the user did not explicitly make.
|
|
9
|
+
|
|
10
|
+
The append-only decision-log format (entry fields, supersession protocol) lives in `<plugin-root>/includes/smarts/decision-log-format.md`. Read it before writing a log line; do not restate it here.
|
|
11
|
+
|
|
12
|
+
**Boundary with `decision-variance`.** This skill owns ADR *authoring* and *status* (`/adr`, `/adr-status`) — recording a decision the user has already made, and reporting ADR health. `decision-variance` owns *arbitration* — detecting variances between artifacts and the scaffold, scoring options via SMARTS, and the decision log itself. The two share the canonical SMARTS reference under `<plugin-root>/includes/smarts/` (`core.md` for scoring, `decision-log-format.md` for the log) and one ADR template (`references/adr-template.md`); they are one domain split by responsibility, not duplicated. When a decision needs *making* (competing options), route to `decision-variance`; when it needs *recording* (already decided), stay here.
|
|
13
|
+
|
|
14
|
+
## Pre-flight
|
|
15
|
+
|
|
16
|
+
Read these, or STOP and surface the gap — never guess a path:
|
|
17
|
+
|
|
18
|
+
- `<project-root>/.codearbiter/decisions/` — the ADR directory and existing records. Create it on first `/adr` if absent.
|
|
19
|
+
- For `/adr`: 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.
|
|
20
|
+
|
|
21
|
+
## Phase 1 — Index · gate: BLOCK
|
|
22
|
+
|
|
23
|
+
Scan `<project-root>/.codearbiter/decisions/` for existing `NNNN-*.md` ADR files. Record each by **filename stem** (`0014-githook-shim-dropin-fail-closed`), title, and status. Determine the next sequential number (no gaps) for `/adr`; for `/adr-status` this is the working set.
|
|
24
|
+
|
|
25
|
+
**The stem is the identifier; the number is only a sort key.** 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 `NNNN` resolves to one file until you have checked.
|
|
26
|
+
|
|
27
|
+
Gate: the existing ADRs are indexed by stem and, for `/adr`, the next number is fixed and **unused** — a number already taken by an existing stem is not available, even for an unrelated decision.
|
|
28
|
+
|
|
29
|
+
## Phase 2 — Author (/adr) · gate: STOP
|
|
30
|
+
|
|
31
|
+
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 `[CONFIRM-NN]` placeholder; do not resolve it by guessing.
|
|
32
|
+
|
|
33
|
+
**Drop the authoring marker first.** The `pre-write`/`pre-edit` hooks block any write to `.codearbiter/decisions/NNNN-*.md` unless a fresh authoring marker is present — that block is the mechanism enforcing "ADRs only via `/adr`" (ORCHESTRATOR §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):
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
mkdir -p "$(git rev-parse --show-toplevel)/.codearbiter/.markers"
|
|
37
|
+
touch "$(git rev-parse --show-toplevel)/.codearbiter/.markers/adr-authoring-active"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The marker is honored for 30 minutes. Then write `<project-root>/.codearbiter/decisions/NNNN-<slug>.md` using the canonical ADR template — `<plugin-root>/routines/decision-lifecycle/references/adr-template.md` (the single source of truth for the ADR shape, shared with `decompose`). Author it with `status: proposed`. If this decision supersedes an existing one, set `supersedes:` to that ADR's **full filename stem** — `supersedes: 0014-githook-shim-dropin-fail-closed`, never `supersedes: 0014` — and leave the prior ADR's file untouched (forward-only chain — do not edit it to add a back-reference).
|
|
41
|
+
|
|
42
|
+
If the new ADR supersedes only *part* of the prior decision, say which part in the body. `supersedes:` 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.
|
|
43
|
+
|
|
44
|
+
After writing the ADR, append a corresponding entry to the decision log per the format in `<plugin-root>/includes/smarts/decision-log-format.md` — `Decided by:` names the user. Status transitions (`proposed → accepted → superseded | rejected`) require explicit user instruction; never advance status on this skill's own judgment.
|
|
45
|
+
|
|
46
|
+
**`governs:` makes the decision live.** When an ADR names path globs in `governs:`, the post-write
|
|
47
|
+
hook surfaces a one-line notice on any Write/Edit touching a matching file — "this file is governed
|
|
48
|
+
by ADR-NNNN" — so a recorded decision pushes back at edit time instead of waiting for a checkpoint
|
|
49
|
+
sweep. Offer the field whenever a decision constrains identifiable files; omit it for decisions
|
|
50
|
+
without a file footprint. Globs are fnmatch-style against repo-relative forward-slash paths.
|
|
51
|
+
|
|
52
|
+
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:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
rm -f "$(git rev-parse --show-toplevel)/.codearbiter/.markers/adr-authoring-active"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Gate: the ADR file is written with a real `decided-by` 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.
|
|
59
|
+
|
|
60
|
+
## Phase 3 — Status (/adr-status) · gate: BLOCK
|
|
61
|
+
|
|
62
|
+
Read-only. For each ADR (or the `--adr N` target), report: stem, title, status, date, and supersession state — found by scanning forward for any later ADR whose `supersedes:` **resolves to** it.
|
|
63
|
+
|
|
64
|
+
Resolve a `supersedes:` value like this, and never guess:
|
|
65
|
+
|
|
66
|
+
- The value is a **stem** → it names that ADR. Done.
|
|
67
|
+
- The value is a **bare number** → collect every stem with that number. Exactly one → it names that ADR. More than one → **ambiguous: report it as an error and resolve nothing.** Zero → a dangling reference; report that too.
|
|
68
|
+
- `none` (or empty) → no predecessor.
|
|
69
|
+
|
|
70
|
+
`.github/scripts/check_adr_identity.py` enforces this same rule mechanically in CI; if it disagrees with this report, the report is wrong.
|
|
71
|
+
|
|
72
|
+
If a supersession candidate contradicts an `accepted` ADR with no clear direction, do not pick one — flag it for `/conflict`.
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
## ADR Status — YYYY-MM-DD
|
|
76
|
+
|
|
77
|
+
### Active
|
|
78
|
+
- ADR-NNNN-<slug> — <title> — <status> (<date>)
|
|
79
|
+
|
|
80
|
+
### Superseded
|
|
81
|
+
- ADR-NNNN-<slug> — <title> — superseded by ADR-MMMM-<slug>
|
|
82
|
+
|
|
83
|
+
### Ambiguous supersession
|
|
84
|
+
- ADR-NNNN-<slug> — supersedes: <value> names <N> ADRs (<stems>) — unresolved
|
|
85
|
+
|
|
86
|
+
### Unresolved CONFIRM-NN
|
|
87
|
+
- ADR-NNNN-<slug> — [CONFIRM-NN]: <text>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
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 `decision-challenger` (`<plugin-root>/agents/decision-challenger.md`) to stress-test an ADR; optional, never forced.
|
|
91
|
+
|
|
92
|
+
Gate: every indexed ADR appears with its current status and supersession state; no `[CONFIRM-NN]` resolved; no file modified.
|
|
93
|
+
|
|
94
|
+
## Hard rules
|
|
95
|
+
|
|
96
|
+
- MUST author an ADR only via `/adr` with explicit user attribution. MUST NOT author an ADR as the disposition of a routine finding — an out-of-scope finding gets an inline `[NEEDS-TRIAGE]` marker instead.
|
|
97
|
+
- MUST NOT record a decision the user did not explicitly make. "Use your best judgment," "I trust you" are declined.
|
|
98
|
+
- MUST NOT resolve a `[CONFIRM-NN]` placeholder by guessing. Surface it and stop.
|
|
99
|
+
- MUST NOT advance an ADR's status without explicit user instruction.
|
|
100
|
+
- 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 `supersedes:` names the prior one.
|
|
101
|
+
- **The never-edit rule protects decision CONTENT, not identifiers.** Rewriting what was decided corrupts the record; disambiguating *which document a pointer names* repairs it. Maintainer ruling, 2026-07-25: *"the never edit rule is meant to prevent this situation, not prevent this situation from being fixed."* So a correction that is provably identifier-only — a `supersedes:` 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 `adr-authoring-active` marker. MUST NOT touch Context, Decision, Alternatives, Consequences, Risks, `status:`, `date:`, `decided-by:`, or `title:` under this allowance.
|
|
102
|
+
- 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.
|
|
103
|
+
- MUST NOT modify any file under `/adr-status` — it is read-only.
|
|
104
|
+
- MUST NOT force the `decision-challenger` agent — its dispatch is MAY only.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Canonical ADR template
|
|
2
|
+
|
|
3
|
+
The single source of truth for the shape of an Architecture Decision Record under
|
|
4
|
+
`<project-root>/.codearbiter/decisions/`. Both `decision-lifecycle` (via `/adr`) and
|
|
5
|
+
`decompose` (Layer 4 DRAFT ADRs) author to this exact format, so `/adr-status` and the
|
|
6
|
+
`governs:` post-write hook parse every ADR the same way regardless of who wrote it.
|
|
7
|
+
|
|
8
|
+
## Filename
|
|
9
|
+
|
|
10
|
+
`NNNN-<slug>.md` — a zero-padded 4-digit sequential number with no gaps (`0001-…`, `0002-…`),
|
|
11
|
+
numbered across the existing `decisions/` directory.
|
|
12
|
+
|
|
13
|
+
**The filename stem is the ADR's identifier** — `0014-githook-shim-dropin-fail-closed`, not
|
|
14
|
+
`0014`. The number alone is a sort key, not a name: this repository already holds two ADRs
|
|
15
|
+
numbered 0014, so `supersedes: 0014` named two documents at once until it was disambiguated.
|
|
16
|
+
Reference an ADR by its full stem everywhere a machine reads it.
|
|
17
|
+
|
|
18
|
+
## File format
|
|
19
|
+
|
|
20
|
+
```markdown
|
|
21
|
+
---
|
|
22
|
+
status: proposed
|
|
23
|
+
date: YYYY-MM-DD
|
|
24
|
+
title: <title>
|
|
25
|
+
decided-by: <user identifier>
|
|
26
|
+
supersedes: NNNN-<slug> | none
|
|
27
|
+
governs: <optional, comma-separated path globs this decision constrains — e.g. src/auth/*, config/tls/*>
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
# ADR-NNNN — <title>
|
|
31
|
+
|
|
32
|
+
## Status
|
|
33
|
+
<Proposed | Accepted | Superseded | Rejected | Draft>
|
|
34
|
+
|
|
35
|
+
## Context
|
|
36
|
+
<What situation, constraint, or requirement prompted this decision?>
|
|
37
|
+
|
|
38
|
+
## Decision
|
|
39
|
+
<What was decided. One clear statement.>
|
|
40
|
+
|
|
41
|
+
## Alternatives considered
|
|
42
|
+
- **<Option A>** — <why not chosen>
|
|
43
|
+
- **<Option B>** — <why not chosen>
|
|
44
|
+
|
|
45
|
+
## Consequences
|
|
46
|
+
<What becomes easier or harder as a result.>
|
|
47
|
+
|
|
48
|
+
## Risks
|
|
49
|
+
<What could go wrong; what would prove this decision wrong.>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Field & status semantics
|
|
53
|
+
|
|
54
|
+
- **`status:` (frontmatter) is authoritative** — `/adr-status` reads it. The `## Status` body line
|
|
55
|
+
mirrors it for human readers. Keep the two in agreement.
|
|
56
|
+
- **Status lifecycle:** `proposed → accepted → superseded | rejected`. `decompose` authors Layer 4
|
|
57
|
+
ADRs as **`status: draft`** during the interview and promotes each to `status: accepted` at its
|
|
58
|
+
Phase 5 (a frontmatter `status:` edit only — never a body rewrite). Status transitions otherwise
|
|
59
|
+
require explicit user instruction; never advance status on the skill's own judgment.
|
|
60
|
+
- **`decided-by:`** names the user who made the decision — real attribution, never inferred.
|
|
61
|
+
- **`supersedes:`** names the prior ADR's full filename stem — `supersedes:
|
|
62
|
+
0014-githook-shim-dropin-fail-closed`, not `supersedes: 0014` — or `none`. A bare number is
|
|
63
|
+
still accepted for the legacy records that carry one, but ONLY while it names exactly one
|
|
64
|
+
ADR; once a number is shared it is an error, not a guess, and
|
|
65
|
+
this repository's own CI fails the build (the identity check is CI-only and is
|
|
66
|
+
not shipped, so a consumer enforces this rule by review rather than by script). Supersession is a forward-only
|
|
67
|
+
chain: set it on the new ADR; never edit the prior ADR to add a back-reference.
|
|
68
|
+
- **`supersedes:` cannot say WHICH CLAUSE it supersedes.** A partial supersession — the new ADR
|
|
69
|
+
replaces some clauses of the prior one and leaves the rest in force — must say so in prose, and
|
|
70
|
+
a chain may legitimately fork when two ADRs supersede different clauses of one predecessor.
|
|
71
|
+
The frontmatter records only *which document*; the body records *how much of it*.
|
|
72
|
+
- **`governs:`** (optional) lists fnmatch-style, repo-relative forward-slash path globs. When present,
|
|
73
|
+
the post-write hook surfaces a "governed by ADR-NNNN" notice on any Write/Edit touching a matching
|
|
74
|
+
file. Omit it for decisions without a file footprint.
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: decision-variance
|
|
3
|
+
description: Reconcile the project's architectural artifacts against the scaffold and prior decisions, then present each variance as a SMARTS analysis for the user to decide. Routed to when the user asks to arbitrate, reconcile, or consolidate architectural context, requests a variance report, mentions ADR conflicts, or asks which downstream artifacts the current state supports. Never decides alone — every arbitration is user-attributed and logged.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# decision-variance
|
|
7
|
+
|
|
8
|
+
Reconcile the architectural artifacts against the scaffold; present variances; the user decides. This skill never arbitrates on its own — every recorded decision carries user attribution.
|
|
9
|
+
|
|
10
|
+
The SMARTS lenses, cell rules, and strength labels are in
|
|
11
|
+
`<plugin-root>/includes/smarts/core.md` — read it before Phase 3. The append-only decision-log
|
|
12
|
+
entry format is in `<plugin-root>/includes/smarts/decision-log-format.md` — read it before
|
|
13
|
+
writing a log line.
|
|
14
|
+
|
|
15
|
+
## Pre-flight
|
|
16
|
+
|
|
17
|
+
Read these, or STOP and surface the gap — never guess a path or a position:
|
|
18
|
+
|
|
19
|
+
- `<project-root>/.codearbiter/CONTEXT.md` — project context and the `stage:` maturity value.
|
|
20
|
+
- `<project-root>/.codearbiter/security-controls.md` — only when a variance touches a security boundary (auth, crypto, secrets). Feeds the Securable lens.
|
|
21
|
+
|
|
22
|
+
Locate the three architectural artifacts by **exact** filename — `01-architecture-breakdown.md`,
|
|
23
|
+
`02-phased-build-plan.md`, `03-task-backlog.md` — first under
|
|
24
|
+
`<project-root>/.codearbiter/plans/`, then the project root, then `docs/`. MUST NOT
|
|
25
|
+
pattern-match similar names (`architecture-draft.md`, `task-list.md`); loose matching arbitrates
|
|
26
|
+
against the wrong document. If any of the three cannot be located, ask the user for the path. Do not
|
|
27
|
+
infer.
|
|
28
|
+
|
|
29
|
+
## Phase 1 — Locate inputs and detect stale decisions · gate: STOP
|
|
30
|
+
|
|
31
|
+
Index, in addition to the three artifacts:
|
|
32
|
+
|
|
33
|
+
- **Existing ADRs** — `<project-root>/.codearbiter/decisions/`. Record each by number, title, status, summary.
|
|
34
|
+
- **The decision log** — `<project-root>/.codearbiter/decisions/decision-log.md`. The persistent, append-only arbitration record. Read it before generating new variances.
|
|
35
|
+
- **The scaffold** — manifests, dependency files, source dirs, config, CI.
|
|
36
|
+
|
|
37
|
+
If the decision log exists, run the stale check: extract each prior entry's recorded
|
|
38
|
+
artifact-section hash, recompute the current SHA-256 of the cited section (heading inclusive, HTML
|
|
39
|
+
comments stripped), and flag every decision whose hash changed. Surface the flagged set: "These
|
|
40
|
+
prior decisions reference artifact sections that have changed. Re-evaluate, keep as-is, or mark
|
|
41
|
+
superseded?" Per the user's choice — re-evaluate (treat as a new variance), keep (update the
|
|
42
|
+
recorded hash to current), or supersede (prompt for a new decision, append per the supersession
|
|
43
|
+
protocol in `<plugin-root>/includes/smarts/decision-log-format.md`).
|
|
44
|
+
|
|
45
|
+
Gate: the three artifacts are located, ADRs and the decision log are indexed, and any stale prior
|
|
46
|
+
decisions are surfaced and dispositioned by the user. A first session with no decision log skips the
|
|
47
|
+
stale check and clears.
|
|
48
|
+
|
|
49
|
+
## Phase 2 — Build the evidence index · gate: BLOCK
|
|
50
|
+
|
|
51
|
+
For each architectural decision in the three artifacts, record: a decision ID, the artifact source
|
|
52
|
+
(document, section anchor), the stated position, the scaffold evidence (file paths), and exactly one
|
|
53
|
+
variance status:
|
|
54
|
+
|
|
55
|
+
- `concur` — both have evidence and agree
|
|
56
|
+
- `divergent` — both have evidence and disagree
|
|
57
|
+
- `scaffold-silent` — artifact states a position, scaffold shows nothing
|
|
58
|
+
- `artifact-silent` — scaffold implements it, artifact is silent
|
|
59
|
+
- `both-silent` — neither has evidence (informational only)
|
|
60
|
+
|
|
61
|
+
A decision that fits none of the project's established categories is recorded `category: UNKNOWN`
|
|
62
|
+
with a note on why it does not fit, then surfaced to the user to map or name. MUST NOT invent a
|
|
63
|
+
category.
|
|
64
|
+
|
|
65
|
+
Gate: every artifact decision classified to exactly one status, each `divergent` /
|
|
66
|
+
`scaffold-silent` / `artifact-silent` case backed by a concrete citation on both sides where
|
|
67
|
+
evidence exists.
|
|
68
|
+
|
|
69
|
+
## Phase 3 — Generate the variance report · gate: BLOCK
|
|
70
|
+
|
|
71
|
+
For every `divergent`, `scaffold-silent`, or `artifact-silent` case, write one entry: the artifact
|
|
72
|
+
position (cited with anchor), the scaffold position (cited with file paths), why it matters (1–3
|
|
73
|
+
sentences), the resolution options (adopt artifact / adopt scaffold / hybrid only if a real synthesis
|
|
74
|
+
exists / defer with reason), a SMARTS analysis of each option, and a recommendation with a strength
|
|
75
|
+
label. `concur` and `both-silent` cases produce no entry — they live in the evidence index only.
|
|
76
|
+
|
|
77
|
+
The SMARTS table follows `<plugin-root>/includes/smarts/core.md` exactly: six lenses, verdict-first cells (Strong /
|
|
78
|
+
Adequate / Weak / Indifferent), the length cap, no hedging adverbs, evidence specificity. The
|
|
79
|
+
recommendation carries one strength label — strong / moderate / tied.
|
|
80
|
+
|
|
81
|
+
**Precedent row.** Before writing the tables, scan the existing decision log once: tally which
|
|
82
|
+
lenses prior resolutions turned on (which lens was decisive, which way ties broke) and note
|
|
83
|
+
decisions whose subject overlaps this variance. Under each SMARTS table, append one `Precedent:`
|
|
84
|
+
line citing the 1–3 most similar prior decisions by ID and the observed pattern — e.g.
|
|
85
|
+
`Precedent: D-014 (bundled over external, Available decisive), D-009; this log has broken 3 of 4
|
|
86
|
+
ties toward Maintainable.` No prior decisions, or none relevant → `Precedent: none on record` —
|
|
87
|
+
never invent a pattern from thin history (fewer than 3 relevant entries is "none yet established").
|
|
88
|
+
Precedent informs the recommendation; it never outranks the Phase 4 authority order, and it is
|
|
89
|
+
input to the user's choice, not a substitute for it.
|
|
90
|
+
|
|
91
|
+
For more than ~10 open variances, group by area and present area-by-area. For a large pass (more
|
|
92
|
+
than ~20 decision categories or ~50 scaffold files), MAY dispatch `scout`
|
|
93
|
+
(`<plugin-root>/agents/scout.md`) to gather evidence and `grader`
|
|
94
|
+
(`<plugin-root>/agents/grader.md`) to produce SMARTS analyses. Inline execution is fine for
|
|
95
|
+
smaller passes.
|
|
96
|
+
|
|
97
|
+
Gate: every qualifying variance has a conformant SMARTS table and a strength-labeled
|
|
98
|
+
recommendation. No `concur`/`both-silent` noise in the report.
|
|
99
|
+
|
|
100
|
+
## Phase 4 — Present variances and capture decisions · gate: STOP
|
|
101
|
+
|
|
102
|
+
Present grouped by area, dependency-ordered within each area, one area at a time. For each variance:
|
|
103
|
+
lead with the variance, present the recommendation (recommend, do not push), wait for the user's
|
|
104
|
+
choice, confirm it back in one sentence, then append the decision to the log per `<plugin-root>/includes/smarts/decision-log-format.md`
|
|
105
|
+
— immediately, never batched in memory.
|
|
106
|
+
|
|
107
|
+
When two sources at the same authority level conflict (e.g., two `accepted` ADRs that contradict),
|
|
108
|
+
record both `same-level-conflict`, surface both with their sources, treat both as silent until the
|
|
109
|
+
user resolves, and record the resolution naming both sources. MUST NOT pick one on this skill's
|
|
110
|
+
judgment.
|
|
111
|
+
|
|
112
|
+
The user may pause at any time. Confirm the pause ("N resolved, M remaining; decisions are saved"),
|
|
113
|
+
summarize the unresolved IDs, and exit. Resume reads the log, finds which variances already have
|
|
114
|
+
recorded decisions, and presents only the rest.
|
|
115
|
+
|
|
116
|
+
The authority order when evidence conflicts: (1) an explicit user decision this session, (2) a
|
|
117
|
+
recorded log decision not yet superseded, (3) an `accepted` ADR, (4) the three artifacts
|
|
118
|
+
(authoritative-by-default, not infallible), (5) scaffold implementation, (6) inferred intent (last
|
|
119
|
+
resort, flagged as inference). Same-level conflicts escalate to the user.
|
|
120
|
+
|
|
121
|
+
After a session resolves ADR-touching variances, MAY dispatch `decision-challenger`
|
|
122
|
+
(`<plugin-root>/agents/decision-challenger.md`) to stress-test an ADR. Optional, not forced.
|
|
123
|
+
|
|
124
|
+
Gate: every presented variance is either resolved with a user-attributed log entry or explicitly
|
|
125
|
+
deferred. No variance is recorded against this skill's own judgment.
|
|
126
|
+
|
|
127
|
+
## Phase 5 — Recommend downstream artifacts · gate: BLOCK
|
|
128
|
+
|
|
129
|
+
Evaluate which downstream artifacts the current decision state supports. For each candidate report
|
|
130
|
+
readiness (`ready` / `partial` / `blocked`), the reason with specific decision-ID references, the
|
|
131
|
+
missing decision IDs if partial, and a recommendation (produce now / produce after named variances
|
|
132
|
+
resolve / not yet). Present as a menu.
|
|
133
|
+
|
|
134
|
+
Gate: this skill recommends only — it MUST NOT produce a downstream artifact without explicit user
|
|
135
|
+
direction. An out-of-scope finding gets an inline `[NEEDS-TRIAGE]` marker, not an arbitration entry.
|
|
136
|
+
|
|
137
|
+
## Hard rules
|
|
138
|
+
|
|
139
|
+
- MUST NOT record an arbitration decision the user did not explicitly make. "Pick one," "use your best judgment," "I trust you," "we're short on time" are declined — the log requires user attribution to stay auditable. Decline, do not capitulate after repeated requests.
|
|
140
|
+
- MAY treat the user explicitly accepting this skill's recommendation ("accept your recommendation," "record the recommended option") as an explicit decision; the log entry then notes the acceptance in `Decided by:`. Never volunteer this fast-path.
|
|
141
|
+
- MUST match the three artifacts by exact filename; never pattern-match a similar name.
|
|
142
|
+
- MUST run the stale-artifact check when a decision log exists, before generating new variances.
|
|
143
|
+
- MUST NOT invent a decision category — surface an `UNKNOWN` for the user to map or name.
|
|
144
|
+
- MUST NOT edit or rebuild a prior log entry — the log is append-only; supersede by appending a new entry whose `Supersedes:` references the prior one.
|
|
145
|
+
- MUST NOT modify the three artifacts, scaffold, or codebase to "fix" a variance — this skill records and recommends; the user implements.
|
|
146
|
+
- MUST NOT generate a variance entry for a `concur` or `both-silent` case.
|
|
147
|
+
- MUST NOT produce a downstream artifact without explicit user direction.
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: decompose
|
|
3
|
+
description: The greenfield decomposition interview. Routed to at startup when .codearbiter/CONTEXT.md lacks the <!--INITIALIZED--> body marker and no source code exists, or when the user invokes /decompose. A senior-architect persona drives a six-layer interview, persists every layer to disk so a context reset loses nothing, then populates .codearbiter/ and locks it initialized. No project-state doc is written before the layers are solid; orchestration does not resume until the lock is set.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# decompose
|
|
7
|
+
|
|
8
|
+
Spec the project before a line of code exists. Routed to at greenfield startup, or by `/decompose`.
|
|
9
|
+
|
|
10
|
+
## Pre-flight
|
|
11
|
+
|
|
12
|
+
Run these ordered checks. Each passes silently or hard-stops with a routing action — never guess:
|
|
13
|
+
|
|
14
|
+
1. Read `<project-root>/.codearbiter/CONTEXT.md`. If it already carries the `<!--INITIALIZED-->` body marker on its own line, STOP — context exists. Route to normal operation.
|
|
15
|
+
2. Scan for meaningful source code: any file outside `.git/`, `.codearbiter/`, `.claude/`, `ORCHESTRATOR.md`, `AGENTS.md`, `CLAUDE.md`, `README.md`, `LICENSE`, `.gitignore`, `.gitmodules`, and standard tooling dotfiles. If any exist, STOP and route to `/create-context`.
|
|
16
|
+
3. Confirm `<project-root>/.codearbiter/` exists and is writable. If not, surface the gap and STOP.
|
|
17
|
+
|
|
18
|
+
All three pass → proceed to Phase 1. Later phases consume this pass-status; they do not re-run it.
|
|
19
|
+
|
|
20
|
+
## Phase 1 — Persona adoption · gate: BLOCK
|
|
21
|
+
|
|
22
|
+
Announce the role switch to the user, verbatim:
|
|
23
|
+
|
|
24
|
+
> "Switching to decomposition mode. For this session I operate as a senior software architect and technical lead, decomposing your project vision into a complete, unambiguous specification before any code is written. Vague language will be challenged, hidden complexity surfaced, and trade-offs forced. This is a thorough interview — typically 60–110 questions across six layers; every layer persists to disk, so you can stop at any point and resume in a later session. Orchestrator mode resumes when this decomposition is locked."
|
|
25
|
+
|
|
26
|
+
State the Rules of Engagement, verbatim:
|
|
27
|
+
|
|
28
|
+
> **Rules of Engagement**
|
|
29
|
+
>
|
|
30
|
+
> - **Pacing:** ONE LAYER AT A TIME. One focused question at a time within a layer (cluster only when tightly coupled). Never advance until the current layer is solid — no hand-wavy answers, no deferred decisions, no unchallenged vague language.
|
|
31
|
+
> - **Three lenses on every answer:**
|
|
32
|
+
> 1. **Vague requirements** — Challenge hand-wavy language. Force concrete nouns, numbers, and verbs. "Manage" is not a verb. "We'll figure that out later" is not acceptable; every "later" becomes a `[CONFIRM-NN]` placeholder.
|
|
33
|
+
> 2. **Hidden complexity** — After each layer, name what the user assumes is easy but is hard: state management, real-time sync, edge cases, data migration, multi-tenancy, role matrices, offline behavior, failure modes — anything that grows non-linearly with scale.
|
|
34
|
+
> 3. **Trade-off forcing** — When a real architectural or product decision exists, frame it: "X gives you A but costs B; Y gives you C but costs D — choose." Record every forced choice as a DRAFT ADR.
|
|
35
|
+
> - **Suggestions calibrated to confidence:** HIGH → recommend one option, one-line justification. MEDIUM → present 2–3 options with trade-offs, ask the deciding question. LOW → flag the gap, explain why it matters, ask the unlocking question. Never skip a gap silently; never suggest an integration without stating why.
|
|
36
|
+
|
|
37
|
+
No interview question is asked yet — the Layer 1 question is asked at the end of Phase 2, after draft persistence exists, so the first answer lands on disk.
|
|
38
|
+
|
|
39
|
+
Gate: persona and Rules of Engagement stated. Advance to Phase 2, never directly to Phase 3.
|
|
40
|
+
|
|
41
|
+
## Phase 2 — Draft persistence (or resume) · gate: BLOCK
|
|
42
|
+
|
|
43
|
+
The Phase 3 interview accumulates 60–110 Q/A turns across six layers. Without per-layer disk persistence, an auto-compaction event silently destroys earlier reasoning and any DRAFT ADRs. This phase plus the per-layer write rule in Phase 3 plus the disk re-read in Phase 4/5 make the skill compaction-resilient: every layer is durable the moment its gate clears.
|
|
44
|
+
|
|
45
|
+
Check for an existing draft directory at `<project-root>/.codearbiter/.decompose-draft/`.
|
|
46
|
+
|
|
47
|
+
**If it exists with `_session.md` and one or more `layer-N-*.md` files — Resume mode:**
|
|
48
|
+
|
|
49
|
+
- Read `_session.md` and every `layer-*.md` present. Read every `<project-root>/.codearbiter/decisions/*.md` with `status: draft` (prior-session draft ADRs to carry forward).
|
|
50
|
+
- Present a numbered summary: prior-session timestamp, captured layers by name, count of DRAFT ADRs.
|
|
51
|
+
- Ask the user to choose: **(a) Resume** — continue from the next unfinished layer, treating captured layers as solid; **(b) Restart** — delete the draft directory and every `status: draft` ADR, begin fresh; **(c) Abort** — exit the skill, leave draft directory and DRAFT ADRs intact.
|
|
52
|
+
- On Resume: re-establish each captured layer as solid, then enter Phase 3 at the next unfinished layer. On Restart: delete `.decompose-draft/` and every DRAFT ADR, then fresh-init below. On Abort: exit cleanly; never silently delete.
|
|
53
|
+
|
|
54
|
+
**If no draft directory exists (or after Restart) — fresh init:**
|
|
55
|
+
|
|
56
|
+
- Create `<project-root>/.codearbiter/.decompose-draft/`.
|
|
57
|
+
- Write `_session.md` recording the ISO-8601 start timestamp, the invoking identity (`git config user.email`), `Status: in-progress`, and a note that this directory is session state, auto-deleted on Phase 6 completion, and that re-invoking `/decompose` after interruption enters Resume mode.
|
|
58
|
+
- Ensure `.codearbiter/.decompose-draft/` is gitignored — append the entry to `<project-root>/.gitignore` if absent.
|
|
59
|
+
|
|
60
|
+
Then ask the first Layer 1 question to open the interview:
|
|
61
|
+
|
|
62
|
+
> "Describe your solution vision in your own words. What problem does it solve, and for whom?"
|
|
63
|
+
|
|
64
|
+
Gate: Phase 3 does not begin until either (a) the draft directory exists with `_session.md` and is otherwise empty (fresh start), or (b) prior layers are replayed and the user explicitly chose Resume.
|
|
65
|
+
|
|
66
|
+
## Phase 3 — Layered interview · gate: BLOCK
|
|
67
|
+
|
|
68
|
+
Run the six layers in strict sequence. Never skip a layer. Never advance until the current layer is solid — no open "later" items unless recorded as `[CONFIRM-NN]`, no unchallenged vague language, no forced trade-off left unresolved.
|
|
69
|
+
|
|
70
|
+
**Per-layer disk write (compaction contract):** when a layer's "advance when" checklist is satisfied, BEFORE the first question of the next layer, write the completed layer's full Q/A record to disk:
|
|
71
|
+
|
|
72
|
+
| Layer | Draft file |
|
|
73
|
+
|---|---|
|
|
74
|
+
| 1 — Vision & Problem | `.decompose-draft/layer-1-vision.md` |
|
|
75
|
+
| 2 — Users & Flows | `.decompose-draft/layer-2-flows.md` |
|
|
76
|
+
| 3 — Functional Scope | `.decompose-draft/layer-3-functional-scope.md` |
|
|
77
|
+
| 4 — Technical Shape | `.decompose-draft/layer-4-tech-shape.md` |
|
|
78
|
+
| 5 — Integrations & Infrastructure | `.decompose-draft/layer-5-integrations.md` |
|
|
79
|
+
| 6 — Risks & Unknowns | `.decompose-draft/layer-6-risks.md` |
|
|
80
|
+
|
|
81
|
+
(All under `<project-root>/.codearbiter/`.) Each file holds every question asked, the user's verbatim answer (or a faithful paraphrase), every challenge made under the three lenses, every `[CONFIRM-NN]` raised, and every DRAFT-ADR title generated. These files are the authoritative record — Phases 4 and 5 read from them, not from conversation context. The next layer does not begin until the prior layer's file exists on disk and is non-empty; if a write fails, surface the error and do not advance.
|
|
82
|
+
|
|
83
|
+
**Layer 4 immediate ADR drafts:** each forced architectural choice in Layer 4 is written at the moment it is made as `<project-root>/.codearbiter/decisions/NNNN-<slug>.md`, numbered sequentially across the existing `decisions/` directory. Do not batch the writes. Author each using the canonical ADR template — `<plugin-root>/routines/decision-lifecycle/references/adr-template.md` (the single source of truth, shared with `decision-lifecycle`) — with frontmatter `status: draft` and `decided-by:` set to the user (or "user" if anonymous). Fill `## Context`, `## Decision`, and `## Consequences` from the forced choice; leave `## Alternatives considered` and `## Risks` populated where the interview surfaced them, or as `<none recorded>`. Phase 5 promotes each to `status: accepted`.
|
|
84
|
+
|
|
85
|
+
**Layer 1 — Vision & Problem.** Unlock: the specific problem and the evidence it is real (not assumed); the primary user and any conflicting user types (name and resolve the conflict, or flag it); the demo-to-a-skeptic definition of "working"; what this project explicitly is NOT building. Advance when: problem concrete, primary user named, "working" demonstrable, NOT-building list explicit.
|
|
86
|
+
|
|
87
|
+
**Layer 2 — Users & Flows.** Unlock: the core user journey from first touch to value delivered, in specific steps; every non-human actor at MVP (scheduled jobs, webhooks, callbacks, external triggers); failure-mode UX (concrete, not "we'll show an error"); admin/ops/internal privilege model. Advance when: end-to-end journey specific, non-human actors named, failure UX defined, privilege model sketched.
|
|
88
|
+
|
|
89
|
+
**Layer 3 — Functional Scope.** Unlock: every capability, challenged individually — what it does (concrete verbs), who initiates it, inputs and outputs; each capability classified MVP / v1 / later; the hardest user-facing problem (the one that invalidates the product if wrong); every "later" forced to closure or recorded as `[CONFIRM-NN]`. Advance when: capability list complete and every item classified; no unresolved "later" except as `[CONFIRM-NN]`.
|
|
90
|
+
|
|
91
|
+
**Layer 4 — Technical Shape.** Unlock: components and ownership (what each owns, where the boundaries are); core data entities, relationships, cardinality; where state lives and how it changes (write paths); the hardest technical problem; hard constraints (stack, runtime, cloud, compliance, budget, team size and skill); the copyright holder for new-file headers (record in `coding-standards.md`; if undecided, record as `[CONFIRM-NN]`); a forced trade-off for every major architectural decision (e.g. monolith vs. services, sync vs. async); **release intent** — the tag prefix the user wants (e.g. `v`), and whether a `CHANGELOG.md` is kept at all. Each forced choice is written immediately as a `status: draft` ADR per the rule above. Advance when: all components named, all entities sketched, all hard constraints recorded, every major trade-off resolved or deferred as `[CONFIRM-NN]`, release intent captured, AND `layer-4-tech-shape.md` is on disk with one DRAFT ADR per forced choice.
|
|
92
|
+
|
|
93
|
+
**Release intent is elicited here, but no `.codearbiter/release-targets.md` row is ever written by this skill.** This lane runs before any manifest or tag exists — greenfield has no `package.json` version field, no `Cargo.toml`, no committed tag to anchor a `prefix` against — so there is nothing yet to substantiate a full row (`manifest`, `payload`, an actual declared file `load_targets` could parse). Record the two answers (tag prefix preference; changelog kept y/n) in `layer-4-tech-shape.md` alongside the rest of the layer's Q/A, for `context-creation`'s back-fill (once source exists) or `/release`'s own back-fill lane (once a manifest and tag exist) to substantiate later. Writing a guessed row now, ahead of anything to check it against, is exactly the invented-shape failure both of those later lanes exist to refuse.
|
|
94
|
+
|
|
95
|
+
**Layer 5 — Integrations & Infrastructure.** Unlock: every external dependency (APIs, services, data sources, auth providers, payment processors, notification services), each named; commodity vs. differentiator for each; actual API contracts, data formats, and auth mechanisms for any system being integrated with; integration risks per dependency (rate limits, reliability and fallback, data ownership and portability, cost at scale). Advance when: all dependencies named, commodity/differentiator classified, integration risks surfaced for each.
|
|
96
|
+
|
|
97
|
+
**Layer 6 — Risks & Unknowns.** Unlock: the top three build-killing risks, each with probability, impact, mitigation; the lowest-confidence areas; spike candidates (what question each answers, cost of being wrong, time-box); the signals and decision points that would force a major architecture change mid-build. Advance when: top three risks named with mitigations, spike candidates identified, architecture-change triggers named.
|
|
98
|
+
|
|
99
|
+
Gate: all six layers complete (no open "later" except as `[CONFIRM-NN]`); all six `layer-*-*.md` files on disk and non-empty; at least one `status: draft` ADR present if any Layer 4 trade-off was forced — a Layer 4 with zero forced trade-offs is suspicious and is re-examined before advancing.
|
|
100
|
+
|
|
101
|
+
## Phase 4 — Synthesis · gate: BLOCK
|
|
102
|
+
|
|
103
|
+
Begin by re-reading every `layer-*-*.md` and every `status: draft` ADR from disk. Do NOT rely on conversation context — by now an auto-compaction may have erased the original Q/A. The on-disk drafts are authoritative; this re-read makes the phase idempotent across compaction. If any expected layer file is missing, BLOCK and surface the gap rather than synthesizing from incomplete context.
|
|
104
|
+
|
|
105
|
+
Produce three artifacts and write each to disk under `<project-root>/.codearbiter/plans/` BEFORE asking for review (the user reviews from disk, which survives a session restart):
|
|
106
|
+
|
|
107
|
+
1. `01-architecture-breakdown.md` — every component with responsibility and connections; a text/ASCII system diagram; every integration with its type (sync/async), protocol, and owner; every open architectural decision flagged with a `[CONFIRM-NN]` marker (numbered sequentially with `open-questions.md`).
|
|
108
|
+
2. `02-phased-build-plan.md` — MVP → v1 → v2 phases; per phase a one-sentence goal, what is included, what is deferred and why (explicit rationale), key risks, and a measurable definition of done.
|
|
109
|
+
3. `03-task-backlog.md` — a flat prioritized task list; each task estimable (1–5 days), assignable to one role (frontend/backend/infra/etc.), phase-grouped (MVP first), with dependencies flagged and spikes time-boxed.
|
|
110
|
+
|
|
111
|
+
Present all three. Request explicit review:
|
|
112
|
+
|
|
113
|
+
> "These three artifacts are written to `.codearbiter/plans/`. Open and review each one. Tell me what is wrong, incomplete, or misrepresents your intent. They are on disk now and survive a session restart, but Phase 5 will not run until you confirm they are correct."
|
|
114
|
+
|
|
115
|
+
Iterate on the on-disk files in place until the user explicitly approves.
|
|
116
|
+
|
|
117
|
+
Gate: all three artifact files on disk AND the user explicitly approves all three, with no unresolved objections.
|
|
118
|
+
|
|
119
|
+
## Phase 5 — project-state population · gate: BLOCK
|
|
120
|
+
|
|
121
|
+
Re-read every input from disk — the three approved artifacts, all six `layer-*-*.md` files, and every `status: draft` ADR. This makes population idempotent across compaction: a user may approve Phase 4, suffer a compaction, re-invoke `/decompose` (Phase 2 enters Resume, Phase 4 sees its artifacts already approved on disk), and Phase 5 proceeds from disk.
|
|
122
|
+
|
|
123
|
+
Promote each `status: draft` ADR to `status: accepted` — an in-place edit of the frontmatter `status:` line (and its `## Status` body mirror) only; do not duplicate or rewrite the ADR body.
|
|
124
|
+
|
|
125
|
+
Then write the surviving project-state docs. Every file holds actual content derived from the interview — no template boilerplate left unfilled:
|
|
126
|
+
|
|
127
|
+
| Source | Destination |
|
|
128
|
+
|---|---|
|
|
129
|
+
| Layer 1 problem + users + NOT-building, with `arbiter: enabled` and `stage:` frontmatter | `CONTEXT.md` |
|
|
130
|
+
| Layer 4 stack + hard constraints + tracker command (e.g. `gh issue create`) | `tech-stack.md` |
|
|
131
|
+
| Layer 4 lint, format, naming + copyright holder | `coding-standards.md` |
|
|
132
|
+
| Layer 4 compliance + crypto + trust-boundary notes (thin — banned-primitive posture only) | `security-controls.md` |
|
|
133
|
+
| Layer 6 unknowns + spike candidates | `open-questions.md` (`[CONFIRM-NN]` format) |
|
|
134
|
+
| Task backlog | `open-tasks.md` |
|
|
135
|
+
| Carried from the `/ca-init` scaffold — confirm present, create empty if absent | `overrides.log` (append-only audit sink, with its audit header), `last-checkpoint` (`0`) |
|
|
136
|
+
| Each Layer 4 forced choice | `decisions/000N-<slug>.md` — already written in Layer 4; Phase 5 only promotes Status to Accepted |
|
|
137
|
+
| The three Phase 4 artifacts | `plans/01-…`, `plans/02-…`, `plans/03-…` — already written and approved; Phase 5 only verifies they exist |
|
|
138
|
+
|
|
139
|
+
(All under `<project-root>/.codearbiter/`.) Set the `stage:` frontmatter value in `CONTEXT.md` to the maturity number for the MVP phase of the build plan (a single number — there is no promotion ladder).
|
|
140
|
+
|
|
141
|
+
**Provenance stubs and code-map stub:** once the project-state docs above are on disk, write a provenance stub per derived doc to `.codearbiter/.provenance/<doc>.json` via `_provenancelib.write_stub` (`interview_derived: true`, empty `entries`) — one stub for each scout/source-derived doc (`CONTEXT`, `tech-stack`, `coding-standards`, `security-controls`). Also write a `.codearbiter/code-map.md` stub — a placeholder empty coarse map. WHY: greenfield has no source code yet, so real provenance entries and code-map contents populate on the first commit-gate auto-heal (or `/ca-context-check`) once code exists.
|
|
142
|
+
|
|
143
|
+
Gate: every project-state doc written with real content; no `status: draft` ADRs remain in `decisions/`; `[CONFIRM-NN]` items are acceptable in `open-questions.md` for genuinely unresolved items; provenance stubs and code-map stub written.
|
|
144
|
+
|
|
145
|
+
## Phase 6 — Initialization lock & cleanup · gate: BLOCK
|
|
146
|
+
|
|
147
|
+
1. Write the `<!--INITIALIZED-->` body marker on its own line in `<project-root>/.codearbiter/CONTEXT.md`. A marker embedded in a template instruction comment does not satisfy the gate.
|
|
148
|
+
2. List `<project-root>/.codearbiter/` and show the populated tree to the user.
|
|
149
|
+
3. Confirm each required file is present and non-empty: `CONTEXT.md` (with `arbiter: enabled` + `stage:` frontmatter and `<!--INITIALIZED-->` body), `tech-stack.md`, `coding-standards.md`, `security-controls.md`, `open-questions.md`, `open-tasks.md`, `overrides.log` (append-only audit sink — create with its audit header if the scaffold left it absent), `last-checkpoint`, `decisions/` (at least one ADR, all `status: accepted`, none `status: draft`), and `plans/01-…`, `plans/02-…`, `plans/03-…`.
|
|
150
|
+
4. Delete `<project-root>/.codearbiter/.decompose-draft/` and all its contents. This is mandatory — a leftover draft directory signals a still-in-progress decomposition to Phase 2 of any future `/decompose`.
|
|
151
|
+
5. Announce return to normal operation:
|
|
152
|
+
|
|
153
|
+
> "Decomposition complete. Project state is initialized and locked, draft directory removed. Returning to codeArbiter orchestrator mode. Use `/ca-feature` to begin implementation, or any other command. Open questions are recorded in `.codearbiter/open-questions.md`."
|
|
154
|
+
|
|
155
|
+
Gate: `<!--INITIALIZED-->` present on its own line in `CONTEXT.md`; all required files present and non-empty; no `status: draft` ADRs in `decisions/`; `.decompose-draft/` no longer exists on disk.
|
|
156
|
+
|
|
157
|
+
## Hard rules
|
|
158
|
+
|
|
159
|
+
- MUST NOT write any project-state file before all six layers are solid and on disk.
|
|
160
|
+
- MUST NOT scaffold any cut doc — see `<plugin-root>/includes/cut-docs.md` for the canonical never-scaffold list. Maturity is the single `stage:` value in `CONTEXT.md` frontmatter.
|
|
161
|
+
- MUST NOT advance a layer until its draft file exists on disk and is non-empty.
|
|
162
|
+
- MUST NOT advance past a layer holding an unresolved "later" item unless it is recorded as `[CONFIRM-NN]`.
|
|
163
|
+
- MUST NOT resolve a `[CONFIRM-NN]` by guessing — surface the question and record it in `open-questions.md`.
|
|
164
|
+
- MUST NOT synthesize artifacts (Phase 4) or populate context (Phase 5) from conversation context — re-read the on-disk drafts first.
|
|
165
|
+
- MUST NOT proceed past Phase 4 without explicit user approval of all three artifacts.
|
|
166
|
+
- MUST NOT leave any `status: draft` ADR in `decisions/` after Phase 5.
|
|
167
|
+
- MUST NOT close the skill while `.decompose-draft/` still exists, or while `CONTEXT.md` lacks the `<!--INITIALIZED-->` body marker on its own line.
|
|
168
|
+
- MUST NOT silently delete a draft directory on Resume — the user chooses Resume, Restart, or Abort.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dispatching-parallel-agents
|
|
3
|
+
description: "The parallel fan-out primitive. Routed to by any skill or command that splits work across independent units and dispatches an agent per unit — subagent-driven-development, /sprint, parallel /review. It owns the dispatch/collect/funnel discipline: bound concurrency, isolate units, collect every result, dedupe overlap, and funnel through finding-triage then checkpoint-aggregator. Raw agent output is never consumed before the funnel runs; an agent that errors drops its unit without corrupting the batch."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# dispatching-parallel-agents
|
|
8
|
+
|
|
9
|
+
Fan out, collect everything, funnel before consuming. Plumbing other skills dispatch through — it owns the parallel discipline, not domain logic.
|
|
10
|
+
|
|
11
|
+
## Pre-flight
|
|
12
|
+
|
|
13
|
+
The caller supplies the work. Confirm it, or STOP and surface the gap — never invent units or pick an agent on a hunch:
|
|
14
|
+
|
|
15
|
+
- **The unit list** — N discrete, independently-completable units of work, each with its scope and target paths.
|
|
16
|
+
- **The agent kind** — which agent kind to dispatch per unit (e.g. `backend-author`, `frontend-author`, `scout`, `security-reviewer` at `<plugin-root>/agents/<name>.md`). One kind per batch.
|
|
17
|
+
- **The completion contract** — what each agent must return: a structured result, its unit ID, and a pass/fail/error status. Self-reports are claims, not evidence (see Phase 4).
|
|
18
|
+
|
|
19
|
+
## Phase 1 — Partition · gate: BLOCK
|
|
20
|
+
|
|
21
|
+
Split the work into units that do not collide. A unit owns a distinct file or path set; two units in one batch MUST NOT mutate the same path.
|
|
22
|
+
|
|
23
|
+
- **Independent paths** — units touch disjoint files. Dispatch directly. This is the common, fast case.
|
|
24
|
+
- **Shared paths unavoidable** — units must mutate the same file or tree. Do NOT dispatch into the conflict. Route to `using-git-worktrees` (`<plugin-root>/routines/using-git-worktrees/SKILL.md`) to give each unit an isolated working tree, or serialize the colliding units into one sequential unit. A shared-path collision in a parallel batch is a corruption, not a merge.
|
|
25
|
+
|
|
26
|
+
Tag each unit with its ID, scope, target paths, and the agent kind. Read-only batches (review, scout) skip the collision check — they mutate nothing.
|
|
27
|
+
|
|
28
|
+
Gate: every unit has a disjoint path set, or its overlap is resolved by worktree isolation or serialization. An unresolved collision does not pass.
|
|
29
|
+
|
|
30
|
+
## Phase 2 — Dispatch · gate: BLOCK
|
|
31
|
+
|
|
32
|
+
Dispatch one agent per unit, bounded.
|
|
33
|
+
|
|
34
|
+
- **Concurrency bound** — dispatch in waves of at most a fixed width (default 4 concurrent agents; the caller MAY override). Do not fan out unbounded; a hundred agents at once starves the batch and corrupts nothing useful.
|
|
35
|
+
- **Fresh and isolated** — each agent gets only its own unit's scope and the completion contract. No agent sees another's working state. No shared mutable context between units in flight.
|
|
36
|
+
- **Hard-stop propagation** — a `tdd` BLOCK, a `commit-gate` failure, a security CRITICAL, or a `[CONFIRM-NN]` inside any unit halts that unit and surfaces immediately; it does not get silently swallowed by the batch.
|
|
37
|
+
|
|
38
|
+
Gate: every unit is dispatched or explicitly deferred. No unit is dropped silently at dispatch.
|
|
39
|
+
|
|
40
|
+
## Phase 3 — Collect · gate: BLOCK
|
|
41
|
+
|
|
42
|
+
Wait for the full wave, then the next, until every unit has terminated. Record each unit's terminal state: `DONE` (returned a result), `ERRORED` (the agent failed), or `DEFERRED` (a hard-stop surfaced).
|
|
43
|
+
|
|
44
|
+
An `ERRORED` unit drops its own work — its partial output is discarded, never half-applied — and is logged against its unit ID. **One errored unit MUST NOT corrupt or discard the batch.** The remaining units' results stand. Record the error for the funnel; do not retry blindly inside this phase.
|
|
45
|
+
|
|
46
|
+
Gate: every unit has a terminal state and `DONE` results are captured intact. A still-running or unaccounted unit blocks Phase 4 — partial collection does not pass.
|
|
47
|
+
|
|
48
|
+
## Phase 4 — Dedupe · gate: BLOCK
|
|
49
|
+
|
|
50
|
+
Parallel agents over adjacent units produce overlapping findings — the same issue reported by two units, the same fix proposed twice. Collapse them before anything downstream sees the batch.
|
|
51
|
+
|
|
52
|
+
- Merge findings that name the same defect at the same location into one, keeping the highest severity reported.
|
|
53
|
+
- Reconcile contradictory results across units (two units that disagree on the same fact) into a single surfaced conflict, not a silent pick.
|
|
54
|
+
- Verify any "done" claim that gates real work: re-run the proving command fresh and read its output and exit code. A subagent's self-report is a claim — never trust it as evidence of completion.
|
|
55
|
+
|
|
56
|
+
Gate: the result set is deduped, contradictions surfaced, and completion claims verified by fresh evidence. Raw, un-deduped agent output MUST NOT reach Phase 5.
|
|
57
|
+
|
|
58
|
+
## Phase 5 — Funnel · gate: STOP
|
|
59
|
+
|
|
60
|
+
The batch is consumed only here, through the fixed funnel — never directly by the caller.
|
|
61
|
+
|
|
62
|
+
1. Dispatch `finding-triage` (`<plugin-root>/agents/finding-triage.md`) over the deduped result set: it classifies severity, marks out-of-scope items with an inline `[NEEDS-TRIAGE]` marker, and discards noise.
|
|
63
|
+
2. Hand the triaged set to `checkpoint-aggregator` (`<plugin-root>/agents/checkpoint-aggregator.md`): it aggregates into the single batch verdict the caller consumes — pass, or a blocking finding list.
|
|
64
|
+
|
|
65
|
+
The errored and deferred units from Phase 3 ride through the funnel as findings — an `ERRORED` unit is a finding the caller must see, not a silent gap.
|
|
66
|
+
|
|
67
|
+
Gate: the caller receives only the aggregated verdict. Bypassing the funnel — consuming raw or merely-deduped agent output — is a gate violation. STOP and return the verdict.
|
|
68
|
+
|
|
69
|
+
## Hard rules
|
|
70
|
+
|
|
71
|
+
- MUST NOT dispatch two units that mutate the same path in one batch; isolate via `using-git-worktrees` or serialize.
|
|
72
|
+
- MUST NOT fan out unbounded; dispatch within the concurrency bound.
|
|
73
|
+
- MUST NOT let one `ERRORED` unit discard or corrupt the rest of the batch.
|
|
74
|
+
- MUST NOT consume agent output before the `finding-triage` → `checkpoint-aggregator` funnel runs.
|
|
75
|
+
- MUST NOT trust a subagent's self-reported completion; verify with a fresh proving command.
|
|
76
|
+
- MUST NOT silently drop a unit — every unit terminates with a recorded state that rides through the funnel.
|