@arbiterforge/ca-pi 0.15.1 → 0.15.3

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.
Files changed (60) hide show
  1. package/README.md +2 -2
  2. package/package.json +1 -1
  3. package/plugins/ca-pi/CHANGELOG.md +71 -0
  4. package/plugins/ca-pi/COMMANDS.md +3 -9
  5. package/plugins/ca-pi/SKILLS.md +16 -22
  6. package/plugins/ca-pi/agents/coverage-auditor.md +16 -2
  7. package/plugins/ca-pi/generated/command-catalog.json +13 -22
  8. package/plugins/ca-pi/helpers/artifacts/ca-artifact-darwin-amd64 +0 -0
  9. package/plugins/ca-pi/helpers/artifacts/ca-artifact-darwin-arm64 +0 -0
  10. package/plugins/ca-pi/helpers/artifacts/ca-artifact-linux-amd64 +0 -0
  11. package/plugins/ca-pi/helpers/artifacts/ca-artifact-linux-arm64 +0 -0
  12. package/plugins/ca-pi/helpers/artifacts/ca-artifact-windows-amd64.exe +0 -0
  13. package/plugins/ca-pi/helpers/artifacts/ca-artifact-windows-arm64.exe +0 -0
  14. package/plugins/ca-pi/helpers/artifacts/release.json +6 -6
  15. package/plugins/ca-pi/hooks/_artifactauthoritylib.py +618 -58
  16. package/plugins/ca-pi/hooks/_artifactlib.py +3 -1
  17. package/plugins/ca-pi/hooks/_host.py +1 -1
  18. package/plugins/ca-pi/hooks/artifact-authority-hook.py +4 -21
  19. package/plugins/ca-pi/hooks/artifact-authority.py +11 -0
  20. package/plugins/ca-pi/hooks/hostapi.py +1 -1
  21. package/plugins/ca-pi/includes/artifacts.md +20 -1
  22. package/plugins/ca-pi/includes/command-compatibility.md +31 -0
  23. package/plugins/ca-pi/includes/farm.md +187 -36
  24. package/plugins/ca-pi/includes/maturity-coverage.md +57 -17
  25. package/plugins/ca-pi/includes/routing-table.md +10 -11
  26. package/plugins/ca-pi/includes/safety-core.md +2 -2
  27. package/plugins/ca-pi/package.json +1 -1
  28. package/plugins/ca-pi/routines/INDEX.md +12 -11
  29. package/plugins/ca-pi/routines/context-check/SKILL.md +17 -1
  30. package/plugins/ca-pi/routines/context-creation/SKILL.md +8 -1
  31. package/plugins/ca-pi/routines/debug/SKILL.md +18 -2
  32. package/plugins/ca-pi/routines/decision-lifecycle/SKILL.md +72 -118
  33. package/plugins/ca-pi/routines/decision-lifecycle/references/authoring.md +152 -0
  34. package/plugins/ca-pi/routines/decision-variance/SKILL.md +107 -133
  35. package/plugins/ca-pi/routines/decision-variance/references/analysis.md +136 -0
  36. package/plugins/ca-pi/routines/decompose/SKILL.md +8 -1
  37. package/plugins/ca-pi/routines/finishing-a-development-branch/SKILL.md +85 -7
  38. package/plugins/ca-pi/routines/post-merge-cleanup/SKILL.md +19 -2
  39. package/plugins/ca-pi/routines/refactor/SKILL.md +27 -8
  40. package/plugins/ca-pi/routines/release/SKILL.md +2 -1
  41. package/plugins/ca-pi/routines/security-architecture/SKILL.md +14 -3
  42. package/plugins/ca-pi/routines/tdd/SKILL.md +9 -5
  43. package/plugins/ca-pi/routines/tribunal/SKILL.md +28 -14
  44. package/plugins/ca-pi/skills/ca-adr/SKILL.md +103 -18
  45. package/plugins/ca-pi/skills/ca-adr-status/SKILL.md +6 -24
  46. package/plugins/ca-pi/skills/ca-cleanup/SKILL.md +241 -52
  47. package/plugins/ca-pi/skills/ca-context-check/SKILL.md +87 -24
  48. package/plugins/ca-pi/skills/ca-create-context/SKILL.md +159 -19
  49. package/plugins/ca-pi/skills/ca-debug/SKILL.md +100 -27
  50. package/plugins/ca-pi/skills/ca-decompose/SKILL.md +156 -17
  51. package/plugins/ca-pi/skills/ca-pr/SKILL.md +161 -26
  52. package/plugins/ca-pi/skills/ca-reconcile/SKILL.md +108 -30
  53. package/plugins/ca-pi/skills/ca-refactor/SKILL.md +96 -30
  54. package/plugins/ca-pi/skills/ca-release/SKILL.md +614 -39
  55. package/plugins/ca-pi/skills/ca-status/SKILL.md +1 -1
  56. package/plugins/ca-pi/skills/ca-threat-model/SKILL.md +56 -27
  57. package/plugins/ca-pi/skills/ca-tribunal/SKILL.md +105 -26
  58. package/plugins/ca-pi/routines/skill-author/SKILL.md +0 -129
  59. package/plugins/ca-pi/routines/skill-author/references/skill-template.md +0 -58
  60. package/plugins/ca-pi/skills/ca-new-skill/SKILL.md +0 -129
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  name: ca-create-context
3
- description: Brownfield back-fill — scout an existing codebase and populate .codearbiter/, then lock it initialized.
3
+ description: Build project context from an existing codebase through isolated scouts, resolve gaps, and preserve initialization gates.
4
4
  argument-hint: (none)
5
5
  ---
6
6
 
7
- # /ca-create-context — brownfield populate
7
+ # context-creation
8
8
 
9
9
  <!-- catalog-compatibility-notice:start -->
10
10
  > Compatibility route. Prefer `/ca-init --brownfield` for new usage. This installed route remains
@@ -12,27 +12,167 @@ argument-hint: (none)
12
12
  > continue with the unchanged brownfield workflow below.
13
13
  <!-- catalog-compatibility-notice:end -->
14
14
 
15
- Wraps an existing codebase in project state without guessing. Dispatches parallel scouts to read the repository, synthesizes their findings into the surviving `.codearbiter/` doc set, resolves gaps via a targeted interview, and locks the project initialized. No arguments — the skill reads the repo and asks only what it cannot determine.
15
+ Wrap an existing codebase in project state, without guessing. Routed to by `/create-context`, and by startup when `.codearbiter/CONTEXT.md` exists but carries no `<!--INITIALIZED-->` body marker and meaningful source code is present. When no meaningful source exists, this is the wrong skill — route to `decompose` instead.
16
16
 
17
- The only permitted path to populate `.codearbiter/` when meaningful source code already exists. For a greenfield project with no source, use `/ca-decompose`.
17
+ This back-fills from existing source. It complements `/ca-init`, which scaffolds an empty `.codearbiter/` for a fresh project; here the docs are derived from what is already on disk.
18
18
 
19
- ## Routes to
19
+ ## Pre-flight
20
20
 
21
- The `context-creation` skill (`<plugin-root>/routines/context-creation/SKILL.md`) — six gated
22
- phases: pre-flight, scout dispatch, synthesis, gap interview, write, lock. Scouts return paths, line
23
- numbers, and named values only — never raw source or secret values. The skill is canonical for the
24
- phases and their gates.
21
+ Read these, or STOP and surface the gap — never guess project identity or a command:
25
22
 
26
- ## When NOT to use
23
+ - `<project-root>/.codearbiter/CONTEXT.md` — if it already carries `<!--INITIALIZED-->`, context exists. Stop and route to normal operation.
24
+ - The repository root listing (one level deep) — the source surface this skill extracts from.
27
25
 
28
- - Project already initialized (`<!--INITIALIZED-->` in `CONTEXT.md`) → `/ca-status`.
29
- - Greenfield project, no source → `/ca-decompose`.
30
- - `.codearbiter/` not yet scaffolded → `/ca-init` first.
31
- - Update one doc → edit `<project-root>/.codearbiter/` directly or use `/ca-feature`.
26
+ The excluded set (not "meaningful source"): `.git/`, `.codearbiter/`, `.claude/`, `AGENTS.md`, `CLAUDE.md`, `README.md`, `LICENSE`, `.gitignore`, `.gitmodules`, and standard tooling dotfiles (`.editorconfig`, `.prettierrc`, etc.). Meaningful source MUST exist beyond it.
32
27
 
33
- ## Hard gate
28
+ ## Phase 1 — Pre-flight confirmation · gate: BLOCK
34
29
 
35
- BLOCK if `<!--INITIALIZED-->` is already present in `CONTEXT.md`. BLOCK if no meaningful source exists
36
- (route to `/ca-decompose`). BLOCK if any scout fails to return before synthesis. BLOCK if any
37
- `[CONFIRM-NN]` exits the gap interview unresolved and undeferred. MUST NOT write `<!--INITIALIZED-->`
38
- until every gap is resolved or deferred to `open-questions.md`.
30
+ Confirm the repository is a brownfield codebase safe for scout-based extraction:
31
+
32
+ 1. Confirm `<!--INITIALIZED-->` is absent from `CONTEXT.md`.
33
+ 2. Confirm meaningful source code is present beyond the excluded set.
34
+ 3. Identify the primary source directories (`src/`, `backend/`, `frontend/`, `lib/`, `app/`, or equivalent).
35
+
36
+ State the finding to the user: existing source detected, beginning scout-based extraction.
37
+
38
+ Gate: `<!--INITIALIZED-->` absent AND meaningful source present. If the marker is present, stop and route to normal operation. If no meaningful source exists, stop and route to `decompose`. Neither condition met → do not proceed.
39
+
40
+ ## Phase 2 — Scout dispatch · gate: BLOCK
41
+
42
+ A **scout** is a restricted, read-only role, not an unconstrained
43
+ `general-purpose` agent. A scout reads one targeted slice of the codebase and
44
+ returns a structured findings report — file paths, line numbers, and named
45
+ values only, never raw code excerpts. Scouts are internal to this skill; they
46
+ are never invoked from a command.
47
+
48
+ Dispatch six isolated `scout` subagents simultaneously. If the active host
49
+ cannot provide isolated subagents, BLOCK context creation and report the host
50
+ capability gap. The general inline-role fallback does not apply here: this
51
+ skill's report-only synthesis contract depends on the orchestrator never
52
+ loading the scouts' raw source into its own context.
53
+ Each reads only its assigned slice:
54
+
55
+ - **Scout A — Tech stack.** Read `package.json`, lockfiles, `pyproject.toml`, `requirements.txt`, `go.mod`, `Cargo.toml`, `*.gemspec`, `Gemfile`. Report languages, runtime versions, frameworks, key dependencies, the dependency manager, license fields. Additionally report, at the repository root only: which of `package.json` / `pyproject.toml` / `Cargo.toml` / `composer.json` carry a version field (candidate release manifests), which of `CHANGELOG.md` / `CHANGES.md` / `HISTORY.md` are present (candidate changelogs), and any existing tag naming convention visible in the repo (e.g. a `v*` tag) — the inputs Phase 3/5 use to draft `.codearbiter/release-targets.md`.
56
+ - **Scout B — Infrastructure.** Read CI/CD config (`.github/workflows/`, `.gitlab-ci.yml`, `Jenkinsfile`, `.circleci/config.yml`), `Dockerfile*`, `docker-compose*.yml`, `Makefile`, `*.tf`, IaC. Report CI/CD platform, build/test/lint commands, deployment targets, environment names, containerization, IaC tool.
57
+ - **Scout C — Architecture.** Read the source tree (names and structure only), entry points (`main.ts`, `index.ts`, `app.py`, `server.go`), and imports in entry points only. Report component list, entry points, module boundaries, architectural pattern, public interfaces.
58
+ - **Scout D — Security posture.** Read auth files (`auth*`, `middleware*`, `guard*`, `jwt*`, `session*`, `oauth*`), crypto import lines, secret-loading sites (`process.env`, `os.environ`, vault/KMS call sites — paths and line numbers only, never values), `.env.example` (never `.env`). Report auth mechanism, crypto libraries, secret-loading patterns (paths + lines, no values), vault/KMS integration, hardcoded-secret risk files (paths only).
59
+ - **Scout E — Testing.** Read test files and test config (`vitest.config.*`, `jest.config.*`, `pytest.ini`, Makefile test flags), coverage config. Report test framework, runner command, coverage tool, coverage thresholds in config, naming convention, approximate test count by type, fixtures.
60
+ - **Scout F — Data model.** Read migration files (`migrations/`, `drizzle/`, `alembic/`, `db/migrate/`), schema definitions (`schema.ts`, `*.prisma`, `*.sql`, `models/`), ORM config, DB connection config (keys only, never credentials). Report database type, ORM/query builder, entity names, migration tool, approximate entity count, multi-tenancy patterns.
61
+
62
+ The orchestrator reads only the scout reports in later phases — never the raw source — to preserve working context. A scout that finds nothing returns an explicit "not found" report, never silence.
63
+
64
+ **Content hashes:** Scouts additionally emit a `git hash-object <path>` content oid per cited file in the hash field of their evidence entry. The scout already Read those files — no additional pass is needed, and no raw content is forwarded to the orchestrator.
65
+
66
+ Gate: all six scout reports returned. A missing report is a blocking gap — do not proceed with an incomplete picture. Re-dispatch a failing scout before Phase 3.
67
+
68
+ ## Phase 3 — Synthesis · gate: BLOCK
69
+
70
+ Draft every surviving project-state doc from the six reports, working only from the reports. Map source to destination:
71
+
72
+ | Scout source | Destination |
73
+ |---|---|
74
+ | A (tech stack), B (build/test/lint commands), E (test runner) | `tech-stack.md` |
75
+ | C (architecture), E (structure) | `coding-standards.md` |
76
+ | D (security) | `security-controls.md` (thin) |
77
+ | A (candidate manifest, candidate changelog, tag convention) | `.codearbiter/release-targets.md` |
78
+ | All scouts | `CONTEXT.md` (project identity, purpose, scope, NOT-building) |
79
+
80
+ Classify every finding by confidence:
81
+
82
+ - **HIGH** — directly and unambiguously in a report (e.g., `"jest"` in `package.json`). Write it as fact.
83
+ - **MEDIUM** — inferred from an indirect signal (directory layout implies layered architecture, no explicit config). Write it with a note: inferred from [signal], verify before relying on it.
84
+ - **LOW** — no signal, or conflicting signals. Write a `[CONFIRM-NN]` placeholder.
85
+
86
+ Every `[CONFIRM-NN]` carries: a sequential ID, one sentence on what is unknown, why it matters, and what would resolve it. IDs are sequential with `open-questions.md`.
87
+
88
+ **`.codearbiter/release-targets.md` is HIGH-confidence only when Scout A found exactly one candidate manifest and exactly one candidate changelog at the repository root.** Draft the row then, in the grammar `<plugin-root>/hooks/_releaselib.py`'s module docstring declares — a single-target project needs only `prefix`, `manifest`, `changelog`, `payload`:
89
+
90
+ ```text
91
+ <!-- release-targets -->
92
+ [app]
93
+ prefix: v
94
+ manifest: package.json
95
+ changelog: CHANGELOG.md
96
+ payload: .
97
+ latest-eligible: true
98
+ <!-- /release-targets -->
99
+ ```
100
+
101
+ (`prefix` defaults to `v` unless Scout A found a different existing tag convention; `payload` is `.` for a single-package repository.) Zero, or more than one, candidate manifest or changelog is LOW confidence — the same "no signal, or conflicting signals" rule above — and gets a `[CONFIRM-NN]` instead of a guessed row; this doc is never scaffolded from an ambiguous scan, and the file is simply not written until the gap is resolved in Phase 4.
102
+
103
+ **`latest-eligible: true` is not cosmetic.** `/release`'s own back-fill detector (`detect_candidate_target`) emits it for this exact single-target shape, so a project drafted here and one back-filled through `/release` must agree — omitting it here would default the row's Phase-3 publish to `--latest=false`, and the same project would get different release behavior depending on which lane happened to declare it first.
104
+
105
+ Gate: every surviving doc drafted; every low-confidence inference carries a `[CONFIRM-NN]`. No silent omission. A domain with no scout signal gets a doc with a `[CONFIRM-NN]` for the whole section — never an empty file.
106
+
107
+ ## Phase 4 — Gap interview · gate: BLOCK
108
+
109
+ Resolve `[CONFIRM-NN]` items with the user. Ask only what the scouts could not answer with HIGH confidence.
110
+
111
+ 1. Present the `[CONFIRM-NN]` list grouped by category — gaps the scan could not resolve.
112
+ 2. Ask ONE targeted question per item. No compound questions. Do not re-ask anything scouts answered with HIGH confidence.
113
+ 3. Per answer: if it resolves the gap, replace the placeholder with content; if the user explicitly defers, keep the placeholder, mark it deferred with the date, and record it in `open-questions.md`; if the answer is vague, challenge it and demand a concrete answer before recording anything.
114
+
115
+ Gate: every `[CONFIRM-NN]` has exactly one outcome — resolved (replaced with content) or explicitly deferred (marked and recorded in `open-questions.md`). No item is silently dropped. Do not proceed with unacknowledged gaps.
116
+
117
+ ## Phase 5 — Project-state write · gate: BLOCK
118
+
119
+ Write the surviving docs to `<project-root>/.codearbiter/`. Every doc carries actual content — no unresolved placeholder may remain where a value was determined:
120
+
121
+ | File | Content |
122
+ |---|---|
123
+ | `CONTEXT.md` | Project identity, purpose, scope, primary users, NOT-building. Frontmatter MUST include `arbiter: enabled` (the activation flag the SessionStart hook keys on) and `stage:` set to a single maturity number (default `1`; the user may raise it if the project is further along). |
124
+ | `tech-stack.md` | Languages, frameworks, test runner, lint command, build command, coverage command, issue-tracker command (e.g. `gh issue create`). |
125
+ | `coding-standards.md` | Structural patterns, naming conventions, style rules. |
126
+ | `security-controls.md` | Thin: auth mechanism, banned crypto primitives, secret-loading stance. Only what a security boundary actually requires. |
127
+ | `open-questions.md` | Every deferred `[CONFIRM-NN]` in `CONFIRM-NN: <description>` form. |
128
+ | `open-tasks.md` | Create the file with its heading only. **Every task goes in through the board helper, one call per item — `python3 "<plugin-root>/hooks/taskwrite.py" add "<task>"` — never by writing entries into the file directly** (B-18). The helper owns the board schema the SessionStart hook and the statusline parse, so a backlog seeded this way cannot drift from it; and once `open-tasks.md` is enrolled in the protected-state registry, a direct write is refused outright, which would leave a Write-tool instruction here unfollowable. If scouts found no backlog, the heading-only file stands as the stub. |
129
+ | `overrides.log` | Empty append-only audit log, created so `/override` has a sink. |
130
+ | `release-targets.md` | Conditional, unlike every other row above: written ONLY when Phase 3 drafted it at HIGH confidence (exactly one candidate manifest, exactly one candidate changelog) or Phase 4 resolved its `[CONFIRM-NN]` to a concrete row. Left unwritten otherwise — `/release`'s own back-fill lane (or a later `context-creation` run, once the ambiguity resolves) is the sanctioned way to create it, never a guess made here. **This file is marker-gated protected state; it needs the authoring marker below, unlike every other row in this table.** |
131
+
132
+ **Authoring marker — required for `release-targets.md` only.** That path is enrolled in the protected-state registry as `marker-gated` (hook `H-22`), so a Write against it is refused unless a fresh authoring marker exists. This lane is a sanctioned author of it, so it mints one immediately before the write and removes it immediately after — the same one-pass shape `/release`'s back-fill lane uses:
133
+
134
+ ```bash
135
+ mkdir -p "$(git rev-parse --show-toplevel)/.codearbiter/.markers"
136
+ touch "$(git rev-parse --show-toplevel)/.codearbiter/.markers/release-targets-authoring"
137
+ ```
138
+
139
+ Write the file, then:
140
+
141
+ ```bash
142
+ rm -f "$(git rev-parse --show-toplevel)/.codearbiter/.markers/release-targets-authoring"
143
+ ```
144
+
145
+ Skip both commands entirely when this run is not writing `release-targets.md` — a marker minted for a write that never happens is a 30-minute window nothing needed. No other file in the table above is enrolled, so none of them take a marker.
146
+
147
+ If scouts found existing decision records (`docs/decisions/`, `adr/`), summarize them as entries under `.codearbiter/decisions/` in the standard ADR format. If a record cannot be fully parsed, summarize what is known, flag the uncertainty, and note the source path for review.
148
+
149
+ **Provenance and code-map (small addition, not a Phase 5 rebuild):**
150
+
151
+ - Write ONE provenance file per derived doc to `.codearbiter/.provenance/<doc>.json` via `_provenancelib.write_provenance` and `new_record`. Each entry carries: `path` (repo-relative), `hash` (the scout's `git hash-object` oid), `drift_trigger` (from `_provenancelib.classify_source(path)`), and the `claims` array with `lines`, `claim`, and `confidence` drawn from the scout evidence.
152
+ - Synthesize `.codearbiter/code-map.md` (concern → path → ≤1-line role) from Scout C (architecture) evidence. Use concern headings (`## <concern>`) and column-0 bullets (`- \`path\` — role`). Keep it coarse — module/concern granularity only, no full file listing.
153
+
154
+ Do NOT scaffold any cut doc — see `<plugin-root>/includes/cut-docs.md` for the canonical never-scaffold list. Maturity lives in the `stage:` frontmatter of `CONTEXT.md`, not a separate file.
155
+
156
+ Gate: every surviving doc written; `CONTEXT.md` frontmatter carries `arbiter: enabled` and `stage:`; no resolved value left as a placeholder. Deferred `[CONFIRM-NN]` items are acceptable only in `open-questions.md`.
157
+
158
+ ## Phase 6 — Initialization lock · gate: BLOCK
159
+
160
+ Lock the project state as initialized and return to normal orchestration:
161
+
162
+ 1. Write the `<!--INITIALIZED-->` marker into the body of `CONTEXT.md`.
163
+ 2. List `.codearbiter/` and display the populated tree.
164
+ 3. Confirm each required file is present and non-empty: `CONTEXT.md` (with `arbiter: enabled` frontmatter and the `<!--INITIALIZED-->` body marker), `tech-stack.md`, `coding-standards.md`, `security-controls.md`, `open-questions.md`, `open-tasks.md`, `overrides.log`.
165
+ 4. State the return to normal operation: extraction complete, project state initialized and locked, `/ca-feature` available to begin work. Deferred questions live in `open-questions.md`.
166
+
167
+ Gate: `arbiter: enabled` set and `<!--INITIALIZED-->` present in `CONTEXT.md`; every required file present and non-empty. Do not close this skill without confirming both markers are written.
168
+
169
+ ## Hard rules
170
+
171
+ - MUST NOT write `<!--INITIALIZED-->` while any `[CONFIRM-NN]` is unaddressed — every gap must be resolved or explicitly deferred to `open-questions.md` first.
172
+ - MUST NOT resolve a `[CONFIRM-NN]` by guessing — surface the question to the user or defer it.
173
+ - MUST NOT proceed past Phase 2 with fewer than six scout reports.
174
+ - MUST NOT run Phase 2 inline — isolated scout subagents are required for the report-only synthesis boundary.
175
+ - MUST NOT load raw source into the orchestrator context after Phase 1 — synthesize from scout reports only.
176
+ - MUST NOT record a scout finding that exposes a secret value — paths and line numbers only.
177
+ - MUST NOT scaffold a cut doc — see `<plugin-root>/includes/cut-docs.md` for the canonical never-scaffold list. Maturity is the `stage:` frontmatter number in `CONTEXT.md`.
178
+ - MUST NOT run when `CONTEXT.md` already carries `<!--INITIALIZED-->` — stop and route to normal operation.
@@ -1,42 +1,115 @@
1
1
  ---
2
2
  name: ca-debug
3
- description: Investigate-then-decide root-cause analysis for a defect whose cause is unknown. No code changes — exits to /ca-fix, /ca-adr, or a no-action close.
3
+ description: "Investigate an unexplained defect or unexpected behavior without changing application code. Use for root-cause diagnosis and an evidence-backed handoff. A no-action close records a board note. Not for implementing a known fix, new features, or explanation-only questions."
4
4
  argument-hint: "<observed symptom>"
5
5
  ---
6
6
 
7
- # /ca-debug — root-cause investigation
7
+ # debug
8
8
 
9
- Investigates a defect, anomaly, or unexpected behavior whose cause is not yet known. Separates investigation from implementation: no code is modified while debugging. Describe the symptom with enough fidelity that another operator could reproduce it — observed behavior, reproduction steps (or intermittent-trigger profile), and environment. Vague descriptions ("it's flaky") are rejected; the orchestrator asks for clarification before routing.
9
+ Select this owning procedure for a root-cause investigation, whether requested in
10
+ plain language or through `/debug`. The command spelling is not a prerequisite.
11
+ Investigation and implementation remain separate: this procedure never changes code.
12
+ It closes the reproduce, evidence, and regression-test handoff loop through `/fix`.
10
13
 
11
- If the cause is already known and a regression test is already named, invoke `/ca-fix` directly.
14
+ ## Entry boundaries
12
15
 
13
- ## Routes to
16
+ - A known bug with a named regression test belongs to `/fix` directly.
17
+ - A design discussion without failing behavior belongs to `/adr`; attribution is
18
+ still required before authoring an ADR. New behavior belongs to `/feature`.
19
+ - An explanation-only question stays in the non-mutating question-answer path;
20
+ it does not require a debug invocation or a command spelled by the user.
21
+ - Do not re-enter from an active `/fix` or `/adr` invocation. Complete that
22
+ invocation before a separate investigation; do not create a routing cycle.
23
+ - The phase gates below own symptom precision, evidence, and the one named exit.
24
+ A no-action close uses the board helper in Phase 5, never a direct file append.
14
25
 
15
- The `debug` skill (`<plugin-root>/routines/debug/SKILL.md`) — five gated phases: symptom
16
- capture, hypothesis generation, evidence gathering, root-cause decision, handoff. Phase 4 forces one
17
- named exit:
26
+ ## Pre-flight
18
27
 
19
- - **(a) Confirmed bug → `/ca-fix`**, carrying the confirmed bug statement, cited evidence, and a named
20
- regression test obligation tied to the minimal repro.
21
- - **(b) Behavior/design ambiguity → `/ca-adr`**, with the ambiguity statement and evidence ledger,
22
- authored only with explicit user attribution.
23
- - **(c) No-action close** — symptom and rationale appended to
24
- `<project-root>/.codearbiter/open-tasks.md`.
28
+ Read these, or STOP and surface the gap — never guess a log path, trace tool, or test runner:
25
29
 
26
- A real finding that is out of scope for those exits is marked inline `[NEEDS-TRIAGE]` and the
27
- investigation continues.
30
+ - `<project-root>/.codearbiter/tech-stack.md` — log paths, trace tooling, test runner conventions. The evidence sources.
31
+ - `<project-root>/.codearbiter/CONTEXT.md` — domain vocabulary, system structure, and the `stage:` frontmatter (the maturity value; higher demands more rigorous evidence before exit).
32
+ - `<project-root>/.codearbiter/security-controls.md` — only when the symptom touches a security boundary (auth, crypto, secrets). Optional; absent on most defects.
28
33
 
29
- ## When NOT to use
34
+ The user MUST supply at least a one-sentence symptom. If absent, ask for one — do not guess the symptom.
30
35
 
31
- - Known bug with a named regression test → `/ca-fix` directly.
32
- - Design discussion with no failing behavior → `/ca-adr`.
33
- - New feature → `/ca-feature`.
34
- - A general "why does it behave this way" question with no defect → `/ca-btw`.
35
- - Re-entry from inside `/ca-fix` or `/ca-adr` → exit that command first (routing-cycle prevention).
36
+ ## Phase 1 — Symptom capture · gate: BLOCK
36
37
 
37
- ## Hard gate
38
+ Record the symptom with enough fidelity that another operator reproduces it without further questions:
38
39
 
39
- MUST NOT modify any code during Phases 1–5 — code changes belong to `/ca-fix`. MUST exit Phase 4 with
40
- exactly one of (a)/(b)/(c). Exit (a) MUST carry a regression test obligation. Exit (b) MUST obtain
41
- user attribution before any `/ca-adr`. MUST NOT promote INCONCLUSIVE evidence to CONFIRMED without a
42
- cited source.
40
+ - **Observed** — one sentence: what the system did. Not the suspected cause; causes belong to Phase 2.
41
+ - **Expected** — one sentence. If the user cannot state expected behavior, that itself may be a design/behavior ambiguity — flag it for Phase 4.
42
+ - **Minimal repro** — exact command/request/action, required input and state, environment (local/staging/prod/test) and maturity value, frequency (every time / intermittent / one-time).
43
+ - **Evidence in hand** — error messages, stack traces, log excerpts; cite the source of each (log path + timestamp, request ID).
44
+
45
+ If no minimal repro exists, derive one with the user before continuing. An intermittent issue still has a trigger condition (an input pattern, a load condition, a timing window) — capture that.
46
+
47
+ Gate: a minimal repro, or a documented intermittent-trigger profile. A symptom without one cannot be debugged, only speculated about. Every piece of evidence MUST cite its source.
48
+
49
+ ## Phase 2 — Hypothesis generation · gate: BLOCK
50
+
51
+ Produce at least three distinct candidate causes, ranked by likelihood, before gathering any evidence against them. Distinct means different subsystems, mechanisms, or failure modes — not three rewordings of one suspicion.
52
+
53
+ For each candidate write: a one-sentence hypothesis, the subsystem/boundary involved, and the mechanism by which it produces the observed symptom. Number them H1, H2, H3… for Phase 3.
54
+
55
+ Rank by recency of relevant changes (recent commits to the suspect subsystem raise rank), symptom specificity (a symptom pointing narrowly at one mechanism raises it), and historical pattern.
56
+
57
+ Include at least one **boring** hypothesis — environmental drift, dependency version change, config mismatch, stale cache, operator error. List it even if ranked last. Confirmation bias toward exotic causes is the recurring debug failure mode.
58
+
59
+ Gate: three or more distinct hypotheses, one of them boring. Single-hypothesis lock-in is the single most common cause of misdiagnosis — the gate forces breadth before depth.
60
+
61
+ ## Phase 3 — Evidence gathering · gate: BLOCK
62
+
63
+ For each hypothesis, identify what would confirm or refute it, then gather that evidence by reading existing artifacts only. No code is modified in this phase.
64
+
65
+ For each H1…HN write the CONFIRM signal, the REFUTE signal, and the source where each lives (log file, trace tool, commit range, metric dashboard). Then read:
66
+
67
+ - Application logs and traces at the paths/tools in `tech-stack.md`.
68
+ - Recent commits (`git log`, `git diff`) on suspect paths.
69
+ - Configuration, environment variables, feature flags (read-only).
70
+
71
+ Annotate each hypothesis CONFIRMED, REFUTED, or INCONCLUSIVE, with a cited source. Do not collapse INCONCLUSIVE to CONFIRMED or REFUTED by inference — state what additional evidence is needed and where it lives. New hypotheses that emerge are added and gathered against; Phase 2 is a floor, not a ceiling.
72
+
73
+ Gate: no code change of any kind — no edit, no refactor, no "try a fix." A hypothesis testable only by changing code becomes a Phase 4 finding (exit (a), with a regression test obligation), not a change here. No INCONCLUSIVE evidence promoted to CONFIRMED without a cited source.
74
+
75
+ ## Phase 4 — Root-cause decision · gate: BLOCK
76
+
77
+ Walk the evidence ledger and pick exactly one exit. "We'll figure it out later" is not an exit.
78
+
79
+ - **(a) Confirmed bug → `/fix`.** One hypothesis is CONFIRMED by cited evidence and the disposition is a code change. Carry: the hypothesis ID and statement, the cited confirming evidence, and a named **regression test obligation** — a one-sentence description of the test `/fix` MUST write (and watch fail) before any fix code. It MUST encode the Phase 1 minimal repro, so the exact condition that reproduced the defect becomes the test that proves it fixed — this is what closes the reproduce→fix→verify loop. `/fix` refuses to proceed without it.
80
+ - **(b) Behavior/design ambiguity → `/adr`.** The system behaves as currently specified, but the specification itself is in question. Carry: the hypothesis ID and statement, a one-sentence statement of the ambiguity, and the symptom record plus evidence ledger as context. An ADR is authored only via `/adr` with explicit user attribution — surface the question to the user and obtain attribution; never author the ADR autonomously as the disposition of a debug session.
81
+ - **(c) No-action close.** The symptom is non-reproducible, was a one-time environmental event, or was already resolved by an unrelated commit. Carry: a one-sentence rationale, the cited evidence supporting "no action," and a note appended to the symptom record.
82
+
83
+ If a finding is real but out of scope for any of the three exits, mark it inline with `[NEEDS-TRIAGE]` and continue — do not stall on it.
84
+
85
+ If no exit can be chosen — all hypotheses INCONCLUSIVE — loop back to Phase 3 for more evidence, or take exit (b) and surface the open question. "No decision" is not a valid exit.
86
+
87
+ Gate: exactly one of (a) / (b) / (c) is named. Exit (a) carries a regression test obligation. Exit (b) carries the ambiguity statement and user attribution before any `/adr`. No exit closes on "more investigation needed" without either looping to Phase 3 or selecting (b).
88
+
89
+ ## Phase 5 — Handoff · gate: BLOCK
90
+
91
+ Emit a summary downstream skills can consume without re-reading the session, then route:
92
+
93
+ - **Summary block:** symptom (one sentence), reproduction profile, hypotheses considered (count + one-line list), evidence ledger summary (CONFIRMED / REFUTED / INCONCLUSIVE per hypothesis), the Phase 4 exit and rationale, and the handoff target.
94
+ - **Exit (a):** route to `/fix` with the confirmed bug statement, cited evidence, and named regression test obligation. The orchestrator routes `/fix` to the `tdd` skill in bug-fix variant, where that test becomes the Phase 1 obligation that must fail before fix code. `debug` does not pre-write the test.
95
+ - **Exit (b):** surface the chosen `/adr` with the ambiguity statement, symptom record, and evidence ledger attached as context, with user attribution.
96
+ - **Exit (c):** record a queued entry **through the board helper, never by appending to the file** — `python3 "<plugin-root>/hooks/taskwrite.py" add "<symptom>" --desc "<no-action rationale>"` (add `--id debug.note` to mint a dotted ID; optional for a debug note). The helper owns the schema the SessionStart hook parses, so a note recorded this way cannot drift from it, and it is the only writer that `.codearbiter/open-tasks.md`'s protected-state class admits. This keeps the note in the in-flight count as an open item to revisit rather than a bare bullet. No further handoff.
97
+
98
+ Surface the summary and the handoff to the user before the skill exits.
99
+
100
+ Gate: the handoff is routed. Exit (a) carries an explicit regression test obligation. Exit (c) is recorded before close.
101
+
102
+ ## Hard rules
103
+
104
+ - MUST NOT modify, refactor, or "try a fix" on any code during Phases 1–5. Code changes belong to `/fix`.
105
+ - MUST NOT proceed past Phase 1 without a minimal repro or a documented intermittent-trigger profile.
106
+ - MUST NOT proceed past Phase 2 with fewer than three distinct hypotheses, or with three rewordings of one suspicion.
107
+ - MUST include at least one boring environmental / configuration / dependency hypothesis in Phase 2.
108
+ - MUST NOT promote INCONCLUSIVE evidence to CONFIRMED or REFUTED without a cited source.
109
+ - MUST cite the source of every piece of evidence — log path + timestamp, commit SHA, trace ID.
110
+ - MUST exit Phase 4 with exactly one of (a) confirmed bug → `/fix`, (b) ambiguity → `/adr`, or (c) no-action close.
111
+ - MUST NOT route to `/fix` for a bug not yet confirmed by cited evidence — `/fix` is for known bugs.
112
+ - MUST NOT exit (a) without a named regression test obligation for `/fix` to carry into its TDD Phase 1.
113
+ - MUST tie the exit-(a) regression test obligation to the Phase 1 minimal repro — the repro is the test that closes the loop.
114
+ - MUST NOT author an ADR autonomously as the disposition of a debug session — exit (b) obtains user attribution and routes through `/adr`.
115
+ - MUST NOT guess a log path, trace tool, or test command — read `tech-stack.md` or STOP.
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  name: ca-decompose
3
- description: Greenfield decomposition interview — a layered interview that populates .codearbiter/ and locks it initialized.
3
+ description: Develop greenfield project context through a layered interview, preserve decisions, and initialize only after the required gates.
4
4
  argument-hint: (none)
5
5
  ---
6
6
 
7
- # /ca-decompose — greenfield populate
7
+ # decompose
8
8
 
9
9
  <!-- catalog-compatibility-notice:start -->
10
10
  > Compatibility route. Prefer `/ca-init --greenfield` for new usage. This installed route remains
@@ -12,25 +12,164 @@ argument-hint: (none)
12
12
  > continue with the unchanged greenfield workflow below.
13
13
  <!-- catalog-compatibility-notice:end -->
14
14
 
15
- Stands up project state for a greenfield project — one with no meaningful source code yet. A senior-architect persona drives a six-layer interview eliciting purpose, scope, primary users, domain vocabulary, and architectural constraints, persisting each layer to disk so a context reset loses nothing, then writes the surviving `.codearbiter/` doc set and locks the project initialized. No arguments — the skill interviews the user (a handoff summary may be supplied freely during the interview).
15
+ Spec the project before a line of code exists. Routed to at greenfield startup, or by `/decompose`.
16
16
 
17
- The only permitted path to populate `.codearbiter/` when no meaningful source exists. For an existing codebase, use `/ca-create-context`.
17
+ ## Pre-flight
18
18
 
19
- ## Routes to
19
+ Run these ordered checks. Each passes silently or hard-stops with a routing action — never guess:
20
20
 
21
- The `decompose` skill (`<plugin-root>/routines/decompose/SKILL.md`) — six gated phases:
22
- pre-flight, persona adoption, layered interview, synthesis, population, lock. The skill is canonical
23
- for the layers and their gates.
21
+ 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.
22
+ 2. Scan for meaningful source code: any file outside `.git/`, `.codearbiter/`, `.claude/`, `arbiter.md`, `AGENTS.md`, `CLAUDE.md`, `README.md`, `LICENSE`, `.gitignore`, `.gitmodules`, and standard tooling dotfiles. If any exist, STOP and route to `/create-context`.
23
+ 3. Confirm `<project-root>/.codearbiter/` exists and is writable. If not, surface the gap and STOP.
24
24
 
25
- ## When NOT to use
25
+ All three pass → proceed to Phase 1. Later phases consume this pass-status; they do not re-run it.
26
26
 
27
- - Project already initialized (`<!--INITIALIZED-->` in `CONTEXT.md`) → `/ca-status`.
28
- - Existing codebase with source present → `/ca-create-context`.
29
- - `.codearbiter/` not yet scaffolded → `/ca-init` first.
30
- - Update one doc → edit `<project-root>/.codearbiter/` directly or use `/ca-feature`.
27
+ ## Phase 1 — Persona adoption · gate: BLOCK
31
28
 
32
- ## Hard gate
29
+ Announce the role switch to the user, verbatim:
33
30
 
34
- BLOCK if `<!--INITIALIZED-->` is already present in `CONTEXT.md`. BLOCK if meaningful source is
35
- detected (route to `/ca-create-context`). BLOCK if any `[CONFIRM-NN]` exits synthesis unresolved and
36
- undeferred. MUST NOT write `<!--INITIALIZED-->` until every required doc is present and non-empty.
31
+ > "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."
32
+
33
+ State the Rules of Engagement, verbatim:
34
+
35
+ > **Rules of Engagement**
36
+ >
37
+ > - **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.
38
+ > - **Three lenses on every answer:**
39
+ > 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.
40
+ > 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.
41
+ > 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.
42
+ > - **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.
43
+
44
+ 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.
45
+
46
+ Gate: persona and Rules of Engagement stated. Advance to Phase 2, never directly to Phase 3.
47
+
48
+ ## Phase 2 — Draft persistence (or resume) · gate: BLOCK
49
+
50
+ 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.
51
+
52
+ Check for an existing draft directory at `<project-root>/.codearbiter/.decompose-draft/`.
53
+
54
+ **If it exists with `_session.md` and one or more `layer-N-*.md` files — Resume mode:**
55
+
56
+ - 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).
57
+ - Present a numbered summary: prior-session timestamp, captured layers by name, count of DRAFT ADRs.
58
+ - 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.
59
+ - 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.
60
+
61
+ **If no draft directory exists (or after Restart) — fresh init:**
62
+
63
+ - Create `<project-root>/.codearbiter/.decompose-draft/`.
64
+ - 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.
65
+ - Ensure `.codearbiter/.decompose-draft/` is gitignored — append the entry to `<project-root>/.gitignore` if absent.
66
+
67
+ Then ask the first Layer 1 question to open the interview:
68
+
69
+ > "Describe your solution vision in your own words. What problem does it solve, and for whom?"
70
+
71
+ 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.
72
+
73
+ ## Phase 3 — Layered interview · gate: BLOCK
74
+
75
+ 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.
76
+
77
+ **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:
78
+
79
+ | Layer | Draft file |
80
+ |---|---|
81
+ | 1 — Vision & Problem | `.decompose-draft/layer-1-vision.md` |
82
+ | 2 — Users & Flows | `.decompose-draft/layer-2-flows.md` |
83
+ | 3 — Functional Scope | `.decompose-draft/layer-3-functional-scope.md` |
84
+ | 4 — Technical Shape | `.decompose-draft/layer-4-tech-shape.md` |
85
+ | 5 — Integrations & Infrastructure | `.decompose-draft/layer-5-integrations.md` |
86
+ | 6 — Risks & Unknowns | `.decompose-draft/layer-6-risks.md` |
87
+
88
+ (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.
89
+
90
+ **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`.
91
+
92
+ **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.
93
+
94
+ **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.
95
+
96
+ **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]`.
97
+
98
+ **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.
99
+
100
+ **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.
101
+
102
+ **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.
103
+
104
+ **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.
105
+
106
+ 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.
107
+
108
+ ## Phase 4 — Synthesis · gate: BLOCK
109
+
110
+ 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.
111
+
112
+ 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):
113
+
114
+ 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`).
115
+ 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.
116
+ 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.
117
+
118
+ Present all three. Request explicit review:
119
+
120
+ > "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."
121
+
122
+ Iterate on the on-disk files in place until the user explicitly approves.
123
+
124
+ Gate: all three artifact files on disk AND the user explicitly approves all three, with no unresolved objections.
125
+
126
+ ## Phase 5 — project-state population · gate: BLOCK
127
+
128
+ 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.
129
+
130
+ 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.
131
+
132
+ Then write the surviving project-state docs. Every file holds actual content derived from the interview — no template boilerplate left unfilled:
133
+
134
+ | Source | Destination |
135
+ |---|---|
136
+ | Layer 1 problem + users + NOT-building, with `arbiter: enabled` and `stage:` frontmatter | `CONTEXT.md` |
137
+ | Layer 4 stack + hard constraints + tracker command (e.g. `gh issue create`) | `tech-stack.md` |
138
+ | Layer 4 lint, format, naming + copyright holder | `coding-standards.md` |
139
+ | Layer 4 compliance + crypto + trust-boundary notes (thin — banned-primitive posture only) | `security-controls.md` |
140
+ | Layer 6 unknowns + spike candidates | `open-questions.md` (`[CONFIRM-NN]` format) |
141
+ | Task backlog | `open-tasks.md` |
142
+ | 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`) |
143
+ | Each Layer 4 forced choice | `decisions/000N-<slug>.md` — already written in Layer 4; Phase 5 only promotes Status to Accepted |
144
+ | The three Phase 4 artifacts | `plans/01-…`, `plans/02-…`, `plans/03-…` — already written and approved; Phase 5 only verifies they exist |
145
+
146
+ (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).
147
+
148
+ **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.
149
+
150
+ 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.
151
+
152
+ ## Phase 6 — Initialization lock & cleanup · gate: BLOCK
153
+
154
+ 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.
155
+ 2. List `<project-root>/.codearbiter/` and show the populated tree to the user.
156
+ 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-…`.
157
+ 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`.
158
+ 5. Announce return to normal operation:
159
+
160
+ > "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`."
161
+
162
+ 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.
163
+
164
+ ## Hard rules
165
+
166
+ - MUST NOT write any project-state file before all six layers are solid and on disk.
167
+ - 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.
168
+ - MUST NOT advance a layer until its draft file exists on disk and is non-empty.
169
+ - MUST NOT advance past a layer holding an unresolved "later" item unless it is recorded as `[CONFIRM-NN]`.
170
+ - MUST NOT resolve a `[CONFIRM-NN]` by guessing — surface the question and record it in `open-questions.md`.
171
+ - MUST NOT synthesize artifacts (Phase 4) or populate context (Phase 5) from conversation context — re-read the on-disk drafts first.
172
+ - MUST NOT proceed past Phase 4 without explicit user approval of all three artifacts.
173
+ - MUST NOT leave any `status: draft` ADR in `decisions/` after Phase 5.
174
+ - MUST NOT close the skill while `.decompose-draft/` still exists, or while `CONTEXT.md` lacks the `<!--INITIALIZED-->` body marker on its own line.
175
+ - MUST NOT silently delete a draft directory on Resume — the user chooses Resume, Restart, or Abort.