@arbiterforge/ca-pi 0.15.12 → 0.16.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.
Files changed (64) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/plugins/ca-pi/CHANGELOG.md +26 -0
  4. package/plugins/ca-pi/SKILLS.md +1 -1
  5. package/plugins/ca-pi/agents/infra-author.md +7 -1
  6. package/plugins/ca-pi/agents/scout.md +40 -8
  7. package/plugins/ca-pi/generated/command-catalog.json +1 -1
  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 +104 -6
  15. package/plugins/ca-pi/hooks/_activationlib.py +97 -13
  16. package/plugins/ca-pi/hooks/_arbiterstatelib.py +7 -2
  17. package/plugins/ca-pi/hooks/_artifactauthoritylib.py +206 -2
  18. package/plugins/ca-pi/hooks/_artifactlib.py +166 -2
  19. package/plugins/ca-pi/hooks/_artifactpromptlib.py +106 -2
  20. package/plugins/ca-pi/hooks/_bashguardlib.py +14 -0
  21. package/plugins/ca-pi/hooks/_contextreportlib.py +564 -6
  22. package/plugins/ca-pi/hooks/_contextselectlib.py +464 -0
  23. package/plugins/ca-pi/hooks/_contextsnapshotlib.py +999 -0
  24. package/plugins/ca-pi/hooks/_debughandofflib.py +767 -0
  25. package/plugins/ca-pi/hooks/_hooklib.py +1 -0
  26. package/plugins/ca-pi/hooks/_host.py +1 -1
  27. package/plugins/ca-pi/hooks/_intentlib.py +5 -5
  28. package/plugins/ca-pi/hooks/_protectedlib.py +3 -3
  29. package/plugins/ca-pi/hooks/_protectedstatelib.py +152 -2
  30. package/plugins/ca-pi/hooks/_provenancelib.py +604 -34
  31. package/plugins/ca-pi/hooks/_readinjectlib.py +131 -1
  32. package/plugins/ca-pi/hooks/artifact-authority.py +20 -1
  33. package/plugins/ca-pi/hooks/debug-handoff.py +85 -0
  34. package/plugins/ca-pi/hooks/doctor.py +4 -2
  35. package/plugins/ca-pi/hooks/hostapi.py +1 -1
  36. package/plugins/ca-pi/hooks/init-codearbiter.py +143 -15
  37. package/plugins/ca-pi/hooks/prompt-submit.py +14 -0
  38. package/plugins/ca-pi/hooks/session-start.py +26 -7
  39. package/plugins/ca-pi/includes/author-tdd-workflow.md +16 -4
  40. package/plugins/ca-pi/includes/helper-invocation.md +128 -0
  41. package/plugins/ca-pi/includes/pi-host-notes.md +13 -0
  42. package/plugins/ca-pi/includes/routing-table.md +1 -1
  43. package/plugins/ca-pi/package.json +1 -1
  44. package/plugins/ca-pi/routines/INDEX.md +1 -1
  45. package/plugins/ca-pi/routines/commit-gate/SKILL.md +5 -3
  46. package/plugins/ca-pi/routines/context-check/SKILL.md +103 -17
  47. package/plugins/ca-pi/routines/context-creation/SKILL.md +290 -54
  48. package/plugins/ca-pi/routines/debug/SKILL.md +303 -55
  49. package/plugins/ca-pi/routines/debug/references/debug-handoff.schema.json +879 -0
  50. package/plugins/ca-pi/routines/debug/references/handoff.md +155 -0
  51. package/plugins/ca-pi/routines/decompose/SKILL.md +13 -0
  52. package/plugins/ca-pi/routines/subagent-driven-development/SKILL.md +34 -0
  53. package/plugins/ca-pi/routines/tdd/SKILL.md +91 -17
  54. package/plugins/ca-pi/skills/ca-commit/SKILL.md +5 -3
  55. package/plugins/ca-pi/skills/ca-context-check/SKILL.md +103 -17
  56. package/plugins/ca-pi/skills/ca-create-context/SKILL.md +290 -54
  57. package/plugins/ca-pi/skills/ca-debug/SKILL.md +303 -55
  58. package/plugins/ca-pi/skills/ca-decompose/SKILL.md +13 -0
  59. package/plugins/ca-pi/skills/ca-feature/SKILL.md +1 -1
  60. package/plugins/ca-pi/skills/ca-fix/SKILL.md +36 -3
  61. package/plugins/ca-pi/skills/ca-init/SKILL.md +19 -0
  62. package/plugins/ca-pi/skills/ca-review/SKILL.md +33 -4
  63. package/plugins/ca-pi/skills/ca-status/SKILL.md +5 -0
  64. package/plugins/ca-pi/skills/ca-task/SKILL.md +55 -8
@@ -0,0 +1,155 @@
1
+ # Debug handoff field reference
2
+
3
+ Generated from the finite `_debughandofflib.MODEL` definitions.
4
+ The JSON Schema projects shape and scalar profiles. Cross-record SEM
5
+ rules, strict byte decoding, causal truth, freshness, and authority remain
6
+ separate obligations of the validator and its consumers.
7
+
8
+ Protocol: `codearbiter.debug-handoff/1.0.0`.
9
+
10
+ ## blocker
11
+
12
+ | Field | Profile |
13
+ |---|---|
14
+ | `blocker.kind` | `enum(access, evidence, authority, capability, safety, scope, budget, input)` |
15
+ | `blocker.missing` | `text(1500)` |
16
+ | `blocker.owner` | `nullable(text(300))` |
17
+ | `blocker.resume_condition` | `text(1500)` |
18
+
19
+ ## check
20
+
21
+ | Field | Profile |
22
+ |---|---|
23
+ | `check.authorization_basis` | `nullable(text(1000))` |
24
+ | `check.cwd` | `nullable(text(512))` |
25
+ | `check.evidence_ids` | `refs(evidence_id, 0..32, unique)` |
26
+ | `check.exit_code` | `nullable(integer)` |
27
+ | `check.expectation` | `text(1500)` |
28
+ | `check.id` | `check_id` |
29
+ | `check.observed` | `nullable(text(1500))` |
30
+ | `check.operation` | `text(2000)` |
31
+ | `check.side_effects` | `text(1500)` |
32
+ | `check.status` | `enum(planned, completed, not_run, interrupted)` |
33
+
34
+ ## disposition
35
+
36
+ | Field | Profile |
37
+ |---|---|
38
+ | `disposition.blockers` | `array(object(blocker), 0..8)` |
39
+ | `disposition.cause_ids` | `refs(hypothesis_id, 0..16, unique)` |
40
+ | `disposition.evidence_ids` | `refs(evidence_id, 0..32, unique)` |
41
+ | `disposition.kind` | `enum(confirmed_code_defect, confirmed_noncode_cause, design_question, no_action, unresolved)` |
42
+ | `disposition.rationale` | `text(2000)` |
43
+
44
+ ## evidence
45
+
46
+ | Field | Profile |
47
+ |---|---|
48
+ | `evidence.check_id` | `nullable(check_id)` |
49
+ | `evidence.coverage` | `enum(complete_for_claim, partial, unknown)` |
50
+ | `evidence.id` | `evidence_id` |
51
+ | `evidence.kind` | `enum(source, observation, user_report, command_result, contract)` |
52
+ | `evidence.limitations` | `nullable(text(1500))` |
53
+ | `evidence.locator` | `text(1000)` |
54
+ | `evidence.observation` | `text(2000)` |
55
+ | `evidence.observed_at` | `nullable(timestamp)` |
56
+ | `evidence.snapshot_id` | `nullable(snapshot_id)` |
57
+
58
+ ## hypothesis
59
+
60
+ | Field | Profile |
61
+ |---|---|
62
+ | `hypothesis.discriminator` | `text(1500)` |
63
+ | `hypothesis.id` | `hypothesis_id` |
64
+ | `hypothesis.limitations` | `nullable(text(1500))` |
65
+ | `hypothesis.mechanism` | `text(2000)` |
66
+ | `hypothesis.opposing_evidence_ids` | `refs(evidence_id, 0..32, unique)` |
67
+ | `hypothesis.status` | `enum(supported, refuted, inconclusive)` |
68
+ | `hypothesis.supporting_evidence_ids` | `refs(evidence_id, 0..32, unique)` |
69
+
70
+ ## next_step
71
+
72
+ | Field | Profile |
73
+ |---|---|
74
+ | `next_step.action` | `nullable(text(1500))` |
75
+ | `next_step.completion_evidence` | `nullable(text(1500))` |
76
+ | `next_step.owner` | `nullable(text(300))` |
77
+ | `next_step.target` | `enum(none, fix, adr, existing_owner, evidence)` |
78
+
79
+ ## packet
80
+
81
+ | Field | Profile |
82
+ |---|---|
83
+ | `packet.case_id` | `case_id` |
84
+ | `packet.checks` | `array(object(check), 0..24)` |
85
+ | `packet.disposition` | `object(disposition)` |
86
+ | `packet.evidence` | `array(object(evidence), 1..32)` |
87
+ | `packet.hypotheses` | `array(object(hypothesis), 0..16)` |
88
+ | `packet.next_step` | `object(next_step)` |
89
+ | `packet.protocol` | `const(codearbiter.debug-handoff/1.0.0)` |
90
+ | `packet.regression` | `nullable(object(regression))` |
91
+ | `packet.reproduction` | `object(reproduction)` |
92
+ | `packet.request` | `object(request)` |
93
+ | `packet.snapshots` | `array(object(snapshot), 0..4)` |
94
+ | `packet.symptom` | `object(symptom)` |
95
+
96
+ ## recipe
97
+
98
+ | Field | Profile |
99
+ |---|---|
100
+ | `recipe.cwd` | `text(512)` |
101
+ | `recipe.failure_signature` | `text(1000)` |
102
+ | `recipe.preconditions` | `text(1000)` |
103
+ | `recipe.steps` | `array(text(500), 1..8)` |
104
+
105
+ ## regression
106
+
107
+ | Field | Profile |
108
+ |---|---|
109
+ | `regression.basis` | `enum(reproduction, causal_trace)` |
110
+ | `regression.candidate_test_id` | `nullable(text(500))` |
111
+ | `regression.evidence_ids` | `refs(evidence_id, 0..32, unique)` |
112
+ | `regression.obligation` | `text(2000)` |
113
+ | `regression.oracle` | `text(1500)` |
114
+ | `regression.reuse_existing` | `boolean` |
115
+ | `regression.snapshot_id` | `snapshot_id` |
116
+
117
+ ## reproduction
118
+
119
+ | Field | Profile |
120
+ |---|---|
121
+ | `reproduction.evidence_ids` | `refs(evidence_id, 0..32, unique)` |
122
+ | `reproduction.limitations` | `nullable(text(1500))` |
123
+ | `reproduction.recipe` | `nullable(object(recipe))` |
124
+ | `reproduction.status` | `enum(reproduced, intermittent, not_yet_reproduced, unsafe_to_replay, unavailable)` |
125
+
126
+ ## request
127
+
128
+ | Field | Profile |
129
+ |---|---|
130
+ | `request.intent` | `enum(diagnosis_only, repair_requested)` |
131
+ | `request.request_ref` | `text(512)` |
132
+ | `request.restrictions` | `array(text(500), 0..12)` |
133
+ | `request.scope` | `text(2000)` |
134
+
135
+ ## snapshot
136
+
137
+ | Field | Profile |
138
+ |---|---|
139
+ | `snapshot.commit` | `nullable(git_oid)` |
140
+ | `snapshot.dirty_state` | `enum(clean, dirty, unknown)` |
141
+ | `snapshot.fingerprint` | `nullable(sha256)` |
142
+ | `snapshot.fingerprint_recipe` | `nullable(recipe_name)` |
143
+ | `snapshot.id` | `snapshot_id` |
144
+ | `snapshot.limitations` | `nullable(text(1500))` |
145
+ | `snapshot.repository` | `text(512)` |
146
+ | `snapshot.runtime_identity` | `nullable(text(500))` |
147
+ | `snapshot.worktree` | `text(512)` |
148
+
149
+ ## symptom
150
+
151
+ | Field | Profile |
152
+ |---|---|
153
+ | `symptom.expected` | `nullable(text(1500))` |
154
+ | `symptom.expected_evidence_ids` | `refs(evidence_id, 0..32, unique)` |
155
+ | `symptom.observed` | `text(1500)` |
@@ -147,6 +147,19 @@ Then write the surviving project-state docs. Every file holds actual content der
147
147
 
148
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
149
 
150
+ After initialization, the first real package manifest is acquired through the
151
+ normal `/ca-context-check` route, not another decomposition interview. An
152
+ empty interview-derived `tech-stack` stub is intended context only. At task
153
+ time, use a source/target snapshot with root `manifests` membership and call
154
+ `_provenancelib.assess_context_provenance` for the selected document. Its
155
+ `first_input_pending` state names the newly observed manifest paths and only
156
+ `tech-stack` as a bounded refresh candidate. Inspect those real files through
157
+ the selected refresh, reconcile facts with the intended architecture, and use
158
+ the existing owner preview and receipt before any update. An empty membership
159
+ or an uninspected boundary supplies no package command, dependency, database
160
+ claim, or nested guidance. Preserve the initialized marker and interview
161
+ history; the first input is not authority to rewrite them.
162
+
150
163
  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
164
 
152
165
  ## Phase 6 — Initialization lock & cleanup · gate: BLOCK
@@ -98,6 +98,27 @@ The subagent works test-first by routing through the `tdd` skill (`<plugin-root>
98
98
  `tdd` Phase 1. Brief it with the task's path set, its spec obligation, and its verification command.
99
99
  Nothing else from prior tasks leaks in.
100
100
 
101
+ Before dispatch, obtain current bounded inputs for the selected task paths:
102
+ existing code-map text if available, assessed provenance, scoped command
103
+ records and collector observations, applicable constraint references, and
104
+ host-effective native instructions in precedence order. Call the private
105
+ `_artifactpromptlib.compose_feature_actor_input` with the chosen author name,
106
+ brief, exact approved spec and plan IDs, task ID, task paths, and those inputs.
107
+ Send its returned `input` as the fresh child's actual input. The returned
108
+ packet never grants task start, source-snapshot admission, or permission to
109
+ mutate or execute a discovered command. Resolve an applicable critical
110
+ unresolved constraint before that material action. An unavailable optional
111
+ map permits bounded read-only orientation, not an invented complete map.
112
+ For each author or reviewer dispatch, call `_contextselectlib.prepare_actor_delivery`
113
+ on that actor's freshly selected packet with the actual actor/task, absolute
114
+ worktree, current source identity, and host epoch when observable. Send its
115
+ bounded `delivery_text` to that child on `deliver` and retain the counted
116
+ attempt. Treat `observed` only as caller-reported load/input evidence; do not
117
+ use a shared session or persona/read marker as a receipt. On `blocked`, stop
118
+ the material action and report the delivery gap. Re-select after resume,
119
+ compaction, scope expansion, or worktree switch; missing epochs get at most
120
+ two counted deliveries for the same binding.
121
+
101
122
  Gate: all six `tdd` phases must be green before acceptance. Never redispatch merely to evade a failing gate.
102
123
  Under an approved `/sprint`, an ordinary implementation/test failure routes to **Recovery within the approved sprint** in `<plugin-root>/SPRINT.md`; rerun the original gate after an evidence-led correction.
103
124
  An attended invocation returns the blocked prerequisite to its caller. A real authority or security block
@@ -108,6 +129,12 @@ halts the affected work and is surfaced under the hard rules, in either mode.
108
129
  Did the change satisfy the task's obligation? Measure the result against the spec line the task
109
130
  traces to — not against whether tests merely pass.
110
131
 
132
+ For an independent spec reviewer, freshly compose the same task-scoped input
133
+ with actor `spec-reviewer` and the exact artifact/task IDs, then send the
134
+ returned `input` to that reviewer before its substantive verdict. Do not
135
+ substitute the author's packet or the coordinator's summary for reviewer
136
+ delivery; the reviewer independently checks source identity and constraints.
137
+
111
138
  - Every acceptance claim in the task's obligation is met by the change.
112
139
  - Scope is clean: nothing implemented beyond the task; nothing required by it omitted.
113
140
  - Out-of-scope work the subagent noticed is recorded with an inline `[NEEDS-TRIAGE]` marker — never
@@ -132,6 +159,13 @@ Dispatch the reviewers applicable to what the combined diff touches, then `findi
132
159
  (`<plugin-root>/agents/finding-triage.md`) to classify every finding by severity. Select
133
160
  reviewers by the diff, not blanket — dispatching an irrelevant reviewer wastes a context:
134
161
 
162
+ For each dispatched reviewer, compose and send a fresh actor input with the
163
+ union of paths in the combined scope, the current bounded context inputs,
164
+ exact approved spec/plan IDs, and the scope task binding. Preserve independent
165
+ review judgment and all existing review gates. A packet read only by the
166
+ coordinator is not reviewer delivery; unresolved critical constraints block a
167
+ substantive verdict while bounded source inspection remains possible.
168
+
135
169
  - `security-reviewer` (`<plugin-root>/agents/security-reviewer.md`) — any security-relevant path (authn/authz, deploy, CI, trust boundary).
136
170
  - `auth-crypto-reviewer` (`<plugin-root>/agents/auth-crypto-reviewer.md`) — auth, crypto, key, or secret changes.
137
171
  - `dependency-reviewer` (`<plugin-root>/agents/dependency-reviewer.md`) — `package.json` / lockfile / base-image changes.
@@ -20,6 +20,43 @@ dispatch remains blocked.
20
20
 
21
21
  Test-first, or it does not ship. Routed to by `/feature` (after spec approval), `/fix`, and `/refactor`.
22
22
 
23
+ For a feature author, including a confirmed small-lane feature, the owning
24
+ coordinator selects task paths and obtains the current bounded map, provenance,
25
+ scoped command records and collector observations, applicable constraint
26
+ references, and host-effective instructions in native precedence order. Before
27
+ the author mutates or executes a discovered command, compose the fresh child
28
+ input with `_artifactpromptlib.compose_feature_actor_input` and send its
29
+ returned `input` to that child. Bind the actual approved spec and plan IDs
30
+ for full-lane work. For a confirmed small-lane feature, pass its mini-spec
31
+ text as `confirmed_mini_spec` and leave both artifact IDs absent; do not invent
32
+ a plan or bypass its existing gate. The packet
33
+ is an orientation aid with `requires_actor_check`, not admission. Recheck
34
+ worktree/source identity and resolve applicable critical constraints before a
35
+ material action. Missing optional map detail permits bounded read-only source
36
+ inspection, with full schema or document body read only when needed.
37
+ Apply `_contextselectlib.prepare_actor_delivery` to that selected packet for
38
+ the actual child, task, worktree and current source/host epochs. Send its
39
+ `delivery_text` when requested and count the attempt before the material
40
+ action; an unknown receipt or surviving session marker never proves delivery.
41
+ Re-select on resume, compaction, scope or worktree change, and report a blocked
42
+ delivery gap rather than assuming the child retained prior context.
43
+
44
+ For a fix or targeted test-only change, use the caller that already owns the
45
+ task. Before the author mutates or executes a discovered command, call
46
+ `_contextselectlib.compose_fix_or_test_actor_input` with the current scoped
47
+ sources, exact command cwd and collector evidence, then send its returned
48
+ `input` to that actor. Use `route='fix'`, `caller='fix'`, and the confirmed
49
+ bug-origin evidence and named regression for a fix. Use `route='test_change'`
50
+ with the existing `fix`, `feature`, or `refactor` caller for a test-only change;
51
+ do not create a feature spec pair merely to deliver context. The selected
52
+ caller retains its own approval and TDD gates. Reuse an actual bug-origin RED
53
+ when it already proves the named regression; for a targeted test change,
54
+ validate the test against the real defect or an honest fault fixture. Never
55
+ change production behavior merely to manufacture a failing test. If this
56
+ conflicts with a required TDD gate, surface the conflict to that gate's owner;
57
+ context delivery does not waive it. The packet remains reported evidence, not
58
+ task admission.
59
+
23
60
  ## Pre-flight
24
61
 
25
62
  Read these, or STOP and surface the gap — never guess a command or a threshold:
@@ -28,11 +65,19 @@ Read these, or STOP and surface the gap — never guess a command or a threshold
28
65
  - `<project-root>/.codearbiter/tech-stack.md` — test, coverage, and lint invocations; file layout; mock patterns.
29
66
  - `<plugin-root>/includes/verification-boundary.md` — the required split between focused local proof and exhaustive exact-head hosted CI.
30
67
  - `<project-root>/.codearbiter/coding-standards.md` — style, structure, naming. Required for Phase 3.
31
- - The authoritative approved spec selected by `/feature`. For HTML, read its
32
- typed criterion records through the installed engine and confirm the paired
33
- plan's exact binding; for legacy Markdown, read
34
- `<project-root>/.codearbiter/specs/<slug>.md`. It is the primary obligation
68
+ - For `/feature`, the authoritative approved spec. For HTML, read its typed
69
+ criterion records through the installed engine and confirm the paired plan's
70
+ exact binding; for legacy Markdown, read
71
+ `<project-root>/.codearbiter/specs/<slug>.md`. It is the feature obligation
35
72
  source.
73
+ - For `/fix`, the bug-origin evidence: observed and expected behavior, the
74
+ current expectation and its citations, supported cause, and the regression
75
+ oracle with its cited evidence. If a validated debug handoff supplies these,
76
+ recheck its source binding and freshness in the actual worktree and the
77
+ original caller authority through the fix owner. A packet or its intent field
78
+ does not authorize repair. Do not create a feature artifact to enter TDD.
79
+ - For `/refactor` backfill, the user-approved surface table and pre-existing
80
+ parity evidence owned by `/refactor`. It does not require a feature spec.
36
81
  - `<project-root>/.codearbiter/security-controls.md` — only when the change touches a security boundary (auth, crypto, secrets, a trust boundary). Optional; absent on most changes.
37
82
  - `<project-root>/.codearbiter/code-map.md` — if present, a coarse concern→path→role map to orient before writing tests and code. Absent is fine — it is read-on-demand, populated by context-creation or commit-gate heal.
38
83
 
@@ -44,27 +89,53 @@ test is `MISSING`. "We should test X" is not an obligation.
44
89
 
45
90
  Derive every obligation before any code is written, and record each as `ID · source · OPEN`:
46
91
 
47
- - **Spec** — one obligation per acceptance criterion in the approved spec. For
92
+ - **Spec (`/feature`)** — one obligation per acceptance criterion in the approved spec. For
48
93
  HTML, cite the exact artifact ID and criterion ID returned by the engine;
49
94
  caller-supplied labels cannot manufacture obligations or widen the approved
50
95
  criterion set.
96
+ - **Bug-origin regression (`/fix`)** — one obligation for each scoped wrong
97
+ behavior to repair. Cite the current expectation, observed defect and supported
98
+ cause, regression oracle and evidence, and relevant source binding. A validated
99
+ debug handoff supplies cited facts, not authority; derive these rows in the
100
+ existing ledger. Do not invent a feature artifact such as a spec, plan, or
101
+ mini-spec. The target regression must go red for the right reason before the
102
+ minimum implementation. If the expectation is unresolved or the proposed
103
+ behavior is new, stop and use the feature or decision owner.
104
+ - **Refactor parity (`/refactor` backfill)** — cite the approved surface table
105
+ and the uncovered symbol or seam with its pre-existing behavior and parity
106
+ evidence. Do not turn a refactor into a feature or a bug fix.
51
107
  - **Contract** — API and input-validation invariants, error responses, boundary conditions.
52
108
  - **Security** — only when `security-controls.md` applies: the assertion that the security-relevant boundary holds.
53
109
 
54
- Gate: the obligation list is complete. **Auto-pass** when every obligation maps one-to-one onto the
55
- acceptance criteria of an already-approved spec (full-lane spec or small-lane mini-spec) — the user
56
- approved that list once; do not re-ask. **User review is required** only for obligations derived
57
- BEYOND the spec (Contract and Security rows): surface just those additions, not the whole list.
110
+ Gate: the obligation list is complete. For `/feature`, **auto-pass** when every obligation maps
111
+ one-to-one onto the acceptance criteria of an already-approved spec (full-lane spec or small-lane
112
+ mini-spec) — the user approved that list once; do not re-ask. **User review is required** only for
113
+ obligations derived BEYOND that spec (Contract and Security rows): surface just those additions.
114
+ For `/fix`, the scoped bug-origin regression follows the original caller's repair authority and
115
+ current evidence; the absence of a feature spec is not a block or permission to expand scope.
116
+ Review any proposed obligation beyond that supported correction under its actual owner. An ADR
117
+ remains a user-attributed decision through `/adr`; neither a handoff nor this ledger creates one.
118
+ For `/refactor`, retain its user-approved surface table and parity gates; backfill only the named
119
+ uncovered behavior or seam. The TDD checklist does not amend that table.
58
120
  Under `/sprint`, spec-derived obligations auto-pass the same way and beyond-spec additions are
59
121
  SMARTS-decided and logged like any other auto-decision. A partial list never passes either way.
60
122
 
61
123
  ## Phase 2 — Red · gate: BLOCK
62
124
 
63
- Write one or more failing tests per obligation. Bind each test ID to its obligation ID and move that
64
- obligation `OPEN → MAPPED`. Run the test command from `tech-stack.md`.
125
+ Bind a failing test ID to each obligation and move that obligation `OPEN → MAPPED`.
126
+ Run the test command from `tech-stack.md`. For `/fix`, first assess an existing failing
127
+ test against target red: compare its assertion and regression oracle with the current
128
+ target failure and evidence. Name the existing test ID in the obligation ledger and
129
+ reuse that named existing target-red test when its oracle is adequate and it fails for
130
+ the target reason. Do not duplicate a test solely because of its age or because it
131
+ predates repair. Add tests only for uncovered obligations. Do not make a named target
132
+ failure green before observing and recording its red result.
133
+
134
+ - Every newly written test MUST fail, and fail **for the right reason** — the assertion, not an import error or a typo. A new test that passes with no implementation is wrong; fix it before continuing.
135
+ - Record unrelated existing failures in the baseline and report them; an unrelated failure is not target red. An import or setup error is not target red. Preserve each failure's identity and output. A newly broken pre-existing test is a conflict — stop and surface it.
136
+ - Required commit gates remain blocked while required checks fail. Do not skip tests, suppress failures, or waive gates to proceed.
65
137
 
66
- - Every new test MUST fail, and fail **for the right reason** — the assertion, not an import error or a typo. A new test that passes with no implementation is wrong; fix it before continuing.
67
- - Every pre-existing test MUST stay green. One that breaks here is a conflict — stop and surface it.
138
+ Observe the target regression red on the broken source before repair or implementation. If a material fixture or setup change occurs after that observation, the earlier red no longer qualifies: repeat target red on the broken implementation with the changed fixture or setup before the minimum repair. For an intermittent or timing defect, prefer a faithful deterministic seam. If only repeated trials can exercise the mechanism, predeclare a finite trial bound and failure oracle; record the stochastic sample limit. Do not claim deterministic proof from a passing sample or retry until green. A failing trial must match the target mechanism, not merely fail intermittently.
68
139
 
69
140
  Reject the standard traps: asserting on a mock instead of behavior; a test that can never fail; a
70
141
  snapshot so broad it asserts nothing; coupling to an implementation detail instead of observable
@@ -80,8 +151,11 @@ never the license to waive it:
80
151
  | "The test would just restate the implementation." | Then it is aimed at the wrong seam — assert the observable behavior, not the wiring. A change with no observable behavior to assert is a design finding, not an exemption. |
81
152
  | "The existing suite already covers this." | Then the failing test is impossible to write — try it. If it genuinely cannot go red, the obligation is already COVERED and Phase 4 records exactly that; if it goes red, the claim was wrong and you are holding the proof. |
82
153
 
83
- Gate: the runner confirms new tests red (for the right reason) and existing tests green, with every
84
- obligation `MAPPED` to a failing test. No implementation code is written until this gate clears.
154
+ Gate: the runner confirms each newly written test red for the right reason, or an
155
+ adequate named existing target-red test red for that reason, with every obligation
156
+ `MAPPED` to a failing test. Record unrelated existing failures separately; they
157
+ cannot count as target red or clear later required checks. No implementation code
158
+ is written until this gate clears.
85
159
 
86
160
  ## Phase 3 — Green · gate: BLOCK
87
161
 
@@ -91,8 +165,8 @@ gold-plating — to the conventions in `coding-standards.md`. Run the impact-bou
91
165
  pre-existing test is a regression: fix it. Exhaustive and cross-platform suites run on exact-head
92
166
  hosted CI before merge.
93
167
 
94
- Gate: the applicable local suite is green, reached by satisfying the Phase 2 tests — not by weakening them. A test's
95
- assertions MUST be unchanged between red and green; only fixtures and setup may move. A relaxed
168
+ Gate: rerun the same named target test for fresh green on the repaired source, then rerun fresh affected-contract tests on that source. Record these results with the applicable coverage, lint, and type-check results; an old-head green is not repair proof. The applicable local suite is green, reached by satisfying the Phase 2 tests — not by weakening them. A test's
169
+ assertions MUST be unchanged between red and green; only fixtures and setup may move, and a material change to either requires renewed target red on the broken implementation before this green. A relaxed
96
170
  assertion is a gate violation.
97
171
 
98
172
  ## Phase 4 — Obligation verify · gate: BLOCK
@@ -107,10 +107,12 @@ Gate: the change is proven to do what it claimed by fresh evidence — command o
107
107
 
108
108
  Compute the heal worklist from the staged set via `_provenancelib.heal_worklist(staged_paths, provenance, current_hashes)` — the subset of staged paths that are `drift_trigger:true` provenance entries whose recorded hash has diverged or is absent. **Empty worklist → skip this phase entirely; most commits pay nothing** (cost guarantee: ordinary commits touching no provenance source do zero re-scout work).
109
109
 
110
- Non-empty worklist → run an **incremental re-scout scoped to those paths only** (not the full repo). For each path, re-examine whether the claims in the backing doc still hold:
110
+ Non-empty worklist → call `_provenancelib.compute_drift(provenance, current_hashes)` to retain the document/source mapping. For each stale document in that drift report, get its record as `doc_provenance` and call `_provenancelib.changed_scope(doc_provenance, drift)`. Intersect that document's drifted paths with the worklist; skip a document when the intersection is empty. The hash map can omit unstaged paths, so a missing entry outside the worklist must not broaden this commit's re-scout. Confirm that every selected worklist path maps to at least one stale document after this filtering; if a record is malformed or the mapping is incomplete, STOP and report the gap rather than treating the path as fresh.
111
111
 
112
- - **Claim still holds → silently re-baseline.** Call `_provenancelib.rebaseline` to update the stored hash in `.codearbiter/.provenance/<doc>.json` and stage that file by explicit path so the re-baselined record rides THIS commit (ADR-0008 ride-along pattern — nothing is surfaced to the user). After staging, re-run the secrets scan from `tech-stack.md` over the newly-staged path(s) — any file staged after Phase 4 must still pass the automated secrets scan before the commit proceeds.
113
- - **Claim changed → route to the existing Phase 6 diff-review.** The doc or code-map edit required to reflect the changed claim is proposed in diff review — the user reviews it as part of the normal diff; nothing is silently rewritten.
112
+ Run an **incremental re-scout for each affected document**, scoped to its selected staged paths only (not the full repo). A fresh first document does not discharge a stale second document's claims for the same source. Resolve each selected document/path dependency independently:
113
+
114
+ - **Claim still holds → silently re-baseline only that document's provenance record.** Call `_provenancelib.rebaseline(doc_provenance, selected_current_hashes)` where `selected_current_hashes` contains current hashes only for the selected staged paths whose claims in that document were inspected and still hold. Do not re-baseline a path whose claim changed or was not inspected. Stage only `.codearbiter/.provenance/<doc>.json` by explicit path so the re-baselined record rides THIS commit (ADR-0008 ride-along pattern — nothing is surfaced to the user). After staging, re-run the secrets scan from `tech-stack.md` over the newly-staged path(s) — any file staged after Phase 4 must still pass the automated secrets scan before the commit proceeds. A missing current hash (deletion or rename) cannot be silently re-baselined; surface it in Phase 6 for review.
115
+ - **Claim changed → route to the existing Phase 6 diff-review.** Propose only the affected doc or code-map edit required to reflect its changed claim. The user reviews that edit in the normal diff, and Phase 7 stages approved paths explicitly; do not silently rewrite or add unrelated documentation.
114
116
 
115
117
  ## Phase 6 — Diff review · gate: BLOCK
116
118
 
@@ -31,6 +31,13 @@ Report first. Write only after the user selects re-scout or re-baseline for that
31
31
  document; never change an unselected derived document. This owner neither stages
32
32
  nor commits. Routine commit-gate auto-heal is unchanged.
33
33
 
34
+ An **initialized refresh** belongs to this existing owner after an explicit
35
+ selection. It is separate from initial population: do not call the initialized
36
+ `/ca-create-context`/`/ca-init --brownfield` path, rerun the scaffolder,
37
+ clear `<!--INITIALIZED-->`, or repeat context finalization. An ordinary status
38
+ snapshot and the initial `/ca-status drift` report are read-only. A declined
39
+ refresh leaves every file unchanged.
40
+
34
41
  ## Pre-flight
35
42
 
36
43
  Read these before computing drift:
@@ -57,8 +64,23 @@ Use `_provenancelib` helpers in this order:
57
64
  Alternatively reuse the same logic as `startup_drift_line` by calling it for
58
65
  a human-readable summary, then inspecting `compute_drift` directly for detail.
59
66
 
60
- If the drift report is empty: report "no stale docs — provenance is fresh"
61
- and exit. No further action required.
67
+ The `entries`/Git-hash comparison above covers legacy v1 records only. For
68
+ every enrolled v2 document, call `assess_context_provenance` with the bounded
69
+ current source/target snapshot and an action-boundary snapshot probe. Inspect
70
+ its per-document states as well as aggregate coverage. A missing, corrupt or
71
+ unsupported record, incomplete acquisition, partial hash or unchecked identity
72
+ is unknown coverage, even when a neighboring v1 or v2 record is usable. Report
73
+ the usable records and the unknowns separately; never turn an empty legacy
74
+ drift report into a fresh verdict for v2. `v2_current` acknowledges matching
75
+ identities only. `semantic: unverified` and `verified_fresh: false` remain in
76
+ force until the owning semantic review and writer receipt establish otherwise;
77
+ changing hashes or choosing re-baseline does not perform that review.
78
+
79
+ Only if the relevant legacy drift report is empty and v2 coverage/identities
80
+ have been checked without unknowns may this audit report no stale identities.
81
+ That is not a claim that instruction-bearing facts are semantically verified.
82
+ Only a separately explicit full initialized refresh selection may proceed
83
+ without a stale-document list.
62
84
 
63
85
  ### Step 2 — Report stale docs
64
86
 
@@ -71,28 +93,92 @@ Stale docs (N):
71
93
  ...
72
94
  ```
73
95
 
74
- ### Step 3 — Per-doc action loop
75
-
76
- For each stale doc, present three choices and wait for the user to select one:
96
+ Also present every enrolled v2 document's `v2_current`, `v2_stale` or unknown
97
+ state from Step 1. For `v2_stale`, derive a proposed affected scope from that
98
+ document's bounded evidence references and recheck the exact paths before
99
+ selection; the legacy `changed_scope` list cannot discover v2 drift. An
100
+ unknown state needs a bounded recovery/inspection, not an inferred fresh or
101
+ stale path. Do not offer an automatic write for an unbounded scope.
102
+
103
+ ### Unsupported human content and owner reconciliation
104
+
105
+ An unsupported human Markdown layout, ambiguous duplicate anchor, unparseable
106
+ custom section, oversized document or absent managed ownership record is a
107
+ write refusal for that document, not a reason to erase it or abandon safe
108
+ task-time reading. An unrelated unknown section in an otherwise supported
109
+ document remains unowned and byte-identical during a supported field update.
110
+ Preserve exact bytes and report the specific unsupported or unowned span.
111
+ Use the existing applicable instructions under their actual precedence for the
112
+ current task; referencing those instructions unchanged does not create a new
113
+ normative rule or require a new approval. Keep observed upstream conventions
114
+ and accepted ADR references source-scoped when they do not already govern this
115
+ project. Surface a real conflict without silently displacing either source.
116
+
117
+ If the requested change would adopt or replace normative instructions, route
118
+ the proposal to its actual owner and obtain that owner's actual approval before
119
+ any supported bounded update. An unsupported template needs explicit
120
+ reconciliation or a qualified per-kind transition through the existing context
121
+ writer. Its refusal never authorizes raw Write/Edit fallback or a regex rewrite.
122
+ Task, question, audit, release and ADR files remain with their existing writers;
123
+ do not normalize, recreate or edit their history during context refresh.
124
+
125
+ ### Step 3 — Selected initialized refresh
126
+
127
+ For each stale or bounded affected document, present supported re-scout,
128
+ re-baseline and defer choices; wait for the user's selection. A user may instead
129
+ explicitly select full refresh. Do not interpret
130
+ `status drift`, the drift report itself or an ordinary status request as that
131
+ selection. Record the selected documents and declared affected source paths
132
+ before any scout or write. An incremental refresh re-scouts only the selected
133
+ drifted paths and affected logical assignments. A full refresh declares all six
134
+ logical assignments and all five content documents. Retain prior coverage as
135
+ prior evidence; a scoped `join_scout_reports` result has `full_coverage: false`
136
+ and must never be described as a newly completed full scan.
77
137
 
78
138
  **re-scout** — dispatch an incremental re-scout of the drifted paths for this
79
- doc, scoped to those paths only (like commit-gate Phase 5.5 heal but manually
80
- invoked). The scout re-reads the changed paths and reports whether claims still
81
- hold. If claims still hold: silently re-baseline the hashes via `rebaseline`.
82
- If claims changed: surface the proposed doc edits for the user to accept before
83
- re-baselining.
84
-
85
- **re-baseline** — acknowledge the drift without re-scouting: call
86
- `rebaseline(provenance, current_hashes)` to update the stored hashes silently.
87
- Use this when the source change is cosmetic (formatting, comments, whitespace)
88
- and the derived doc claims are still accurate.
139
+ doc, scoped to those paths only. Use the context-creation containment profile,
140
+ run budget, `admit_scout_attempt` and `join_scout_reports` contract for exactly
141
+ the declared affected assignments. A missing/failed report, changed snapshot,
142
+ contradiction or unresolved task-dependent decision blocks the selected write.
143
+ If the claims still hold, a valid selected owned-field metadata refresh may
144
+ keep document bytes identical only when proposed v2 provenance actually
145
+ changes. Missing selection and unchanged proposed provenance refuse; retain
146
+ the stale pair and do not claim freshness in those cases. Any update still
147
+ requires current source evidence, exact preview approval and receipt-only
148
+ apply. Surface the proposed content and provenance pair for exact review.
149
+
150
+ **re-baseline** — the legacy v1 provenance choice may acknowledge a verified
151
+ cosmetic change through its existing owner, where applicable. For an enrolled
152
+ v2 content document, use only a selected owned field and the native bounded
153
+ update with new, validated source evidence and changed proposed provenance.
154
+ If no field is selected or the proposed pair is a true no-op, retain the stale
155
+ pair and defer that selection. Never directly write the v2 provenance or use
156
+ the legacy `rebaseline` helper as a fallback for it.
157
+
158
+ **full refresh** — only after explicit selection, use the same qualified
159
+ containment and bounded join with `mode: full` and six complete logical reports.
160
+ Synthesize all five content documents from the new evidence and reconcile gaps
161
+ under the context-creation Phase 3–4 rules. Do not enter its Phase 6 lock.
162
+
163
+ For each selected document, submit its finite typed `update` preview through
164
+ `python "<plugin-root>/hooks/init-codearbiter.py" --root <exact-root> --context-request <request-file>`.
165
+ The installed qualified context writer checks the existing document/provenance
166
+ pair, current source evidence, field ownership and protected target set. Review
167
+ the exact proposed pair and obtain its own native `approve-context` reply; apply
168
+ only its receipt through the same `--context-request` bridge. Read back the
169
+ committed pair and confirm the standalone `<!--INITIALIZED-->` marker remains
170
+ for `CONTEXT.md`. The writer's five content targets exclude task, question and
171
+ audit history. Never edit those owners as a side effect, hand-write a provenance
172
+ record, bypass a refusal, stage or commit here. If the installed writer or
173
+ qualified scout profile is unavailable, report that boundary and retain state.
89
174
 
90
175
  **defer** — do nothing for this doc now. The drift line will reappear at the
91
176
  next SessionStart. Use when the change is in-progress and the doc update should
92
177
  wait for a later commit.
93
178
 
94
- After processing all stale docs, summarize which docs were re-scouted,
95
- re-baselined, or deferred.
179
+ After processing selections, summarize changed documents, deferred selections,
180
+ the declared coverage, and whether the run was full or incremental. Keep
181
+ unselected content, initialized state and prior history intact.
96
182
 
97
183
  ## Hard rule
98
184