@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.
- package/README.md +1 -1
- package/package.json +1 -1
- package/plugins/ca-pi/CHANGELOG.md +26 -0
- package/plugins/ca-pi/SKILLS.md +1 -1
- package/plugins/ca-pi/agents/infra-author.md +7 -1
- package/plugins/ca-pi/agents/scout.md +40 -8
- package/plugins/ca-pi/generated/command-catalog.json +1 -1
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-darwin-amd64 +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-darwin-arm64 +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-linux-amd64 +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-linux-arm64 +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-windows-amd64.exe +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-windows-arm64.exe +0 -0
- package/plugins/ca-pi/helpers/artifacts/release.json +104 -6
- package/plugins/ca-pi/hooks/_activationlib.py +97 -13
- package/plugins/ca-pi/hooks/_arbiterstatelib.py +7 -2
- package/plugins/ca-pi/hooks/_artifactauthoritylib.py +206 -2
- package/plugins/ca-pi/hooks/_artifactlib.py +166 -2
- package/plugins/ca-pi/hooks/_artifactpromptlib.py +106 -2
- package/plugins/ca-pi/hooks/_bashguardlib.py +14 -0
- package/plugins/ca-pi/hooks/_contextreportlib.py +564 -6
- package/plugins/ca-pi/hooks/_contextselectlib.py +464 -0
- package/plugins/ca-pi/hooks/_contextsnapshotlib.py +999 -0
- package/plugins/ca-pi/hooks/_debughandofflib.py +767 -0
- package/plugins/ca-pi/hooks/_hooklib.py +1 -0
- package/plugins/ca-pi/hooks/_host.py +1 -1
- package/plugins/ca-pi/hooks/_intentlib.py +5 -5
- package/plugins/ca-pi/hooks/_protectedlib.py +3 -3
- package/plugins/ca-pi/hooks/_protectedstatelib.py +152 -2
- package/plugins/ca-pi/hooks/_provenancelib.py +604 -34
- package/plugins/ca-pi/hooks/_readinjectlib.py +131 -1
- package/plugins/ca-pi/hooks/artifact-authority.py +20 -1
- package/plugins/ca-pi/hooks/debug-handoff.py +85 -0
- package/plugins/ca-pi/hooks/doctor.py +4 -2
- package/plugins/ca-pi/hooks/hostapi.py +1 -1
- package/plugins/ca-pi/hooks/init-codearbiter.py +143 -15
- package/plugins/ca-pi/hooks/prompt-submit.py +14 -0
- package/plugins/ca-pi/hooks/session-start.py +26 -7
- package/plugins/ca-pi/includes/author-tdd-workflow.md +16 -4
- package/plugins/ca-pi/includes/helper-invocation.md +128 -0
- package/plugins/ca-pi/includes/pi-host-notes.md +13 -0
- package/plugins/ca-pi/includes/routing-table.md +1 -1
- package/plugins/ca-pi/package.json +1 -1
- package/plugins/ca-pi/routines/INDEX.md +1 -1
- package/plugins/ca-pi/routines/commit-gate/SKILL.md +5 -3
- package/plugins/ca-pi/routines/context-check/SKILL.md +103 -17
- package/plugins/ca-pi/routines/context-creation/SKILL.md +290 -54
- package/plugins/ca-pi/routines/debug/SKILL.md +303 -55
- package/plugins/ca-pi/routines/debug/references/debug-handoff.schema.json +879 -0
- package/plugins/ca-pi/routines/debug/references/handoff.md +155 -0
- package/plugins/ca-pi/routines/decompose/SKILL.md +13 -0
- package/plugins/ca-pi/routines/subagent-driven-development/SKILL.md +34 -0
- package/plugins/ca-pi/routines/tdd/SKILL.md +91 -17
- package/plugins/ca-pi/skills/ca-commit/SKILL.md +5 -3
- package/plugins/ca-pi/skills/ca-context-check/SKILL.md +103 -17
- package/plugins/ca-pi/skills/ca-create-context/SKILL.md +290 -54
- package/plugins/ca-pi/skills/ca-debug/SKILL.md +303 -55
- package/plugins/ca-pi/skills/ca-decompose/SKILL.md +13 -0
- package/plugins/ca-pi/skills/ca-feature/SKILL.md +1 -1
- package/plugins/ca-pi/skills/ca-fix/SKILL.md +36 -3
- package/plugins/ca-pi/skills/ca-init/SKILL.md +19 -0
- package/plugins/ca-pi/skills/ca-review/SKILL.md +33 -4
- package/plugins/ca-pi/skills/ca-status/SKILL.md +5 -0
- 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
|
-
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
`<project-root>/.codearbiter/specs/<slug>.md`. It is the
|
|
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. **
|
|
55
|
-
acceptance criteria of an already-approved spec (full-lane spec or small-lane
|
|
56
|
-
approved that list once; do not re-ask. **User review is required** only for
|
|
57
|
-
BEYOND
|
|
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
|
-
|
|
64
|
-
|
|
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
|
-
|
|
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
|
|
84
|
-
|
|
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 →
|
|
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
|
-
|
|
113
|
-
|
|
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
|
-
|
|
61
|
-
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
|
95
|
-
|
|
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
|
|