@arbiterforge/ca-pi 0.14.10 → 0.14.16
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 +33 -9
- package/package.json +2 -1
- package/plugins/ca-pi/CHANGELOG.md +67 -0
- package/plugins/ca-pi/LICENSE +661 -0
- package/plugins/ca-pi/SKILLS.md +2 -2
- package/plugins/ca-pi/SPRINT.md +47 -0
- package/plugins/ca-pi/THIRD_PARTY_NOTICES.md +40 -0
- package/plugins/ca-pi/generated/command-catalog.json +2 -2
- 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 +6 -6
- package/plugins/ca-pi/hooks/_approvallib.py +58 -22
- package/plugins/ca-pi/hooks/_artifactauthoritylib.py +2135 -0
- package/plugins/ca-pi/hooks/_artifactlib.py +164 -7
- package/plugins/ca-pi/hooks/_artifactpromptlib.py +177 -0
- package/plugins/ca-pi/hooks/_host.py +1 -1
- package/plugins/ca-pi/hooks/_overrideappendlib.py +5 -1
- package/plugins/ca-pi/hooks/_prerequisitelib.py +44 -22
- package/plugins/ca-pi/hooks/_reconciliationlib.py +472 -0
- package/plugins/ca-pi/hooks/_releaselib.py +345 -111
- package/plugins/ca-pi/hooks/_sprintapprovallib.py +302 -0
- package/plugins/ca-pi/hooks/artifact-authority-hook.py +127 -0
- package/plugins/ca-pi/hooks/artifact-authority.py +102 -0
- package/plugins/ca-pi/hooks/artifact-reconcile.py +57 -0
- package/plugins/ca-pi/hooks/hostapi.py +1 -1
- package/plugins/ca-pi/hooks/prompt-submit.py +20 -3
- package/plugins/ca-pi/hooks/releasehash.py +36 -23
- package/plugins/ca-pi/includes/artifacts.md +120 -13
- package/plugins/ca-pi/includes/sprint-authority.md +69 -0
- package/plugins/ca-pi/package.json +1 -1
- package/plugins/ca-pi/routines/INDEX.md +7 -4
- package/plugins/ca-pi/routines/brainstorming/SKILL.md +97 -29
- package/plugins/ca-pi/routines/commit-gate/SKILL.md +7 -1
- package/plugins/ca-pi/routines/executing-plans/SKILL.md +32 -15
- package/plugins/ca-pi/routines/release/SKILL.md +220 -70
- package/plugins/ca-pi/routines/skill-author/SKILL.md +26 -5
- package/plugins/ca-pi/routines/writing-plans/SKILL.md +22 -10
- package/plugins/ca-pi/skills/ca-commit/SKILL.md +170 -16
- package/plugins/ca-pi/skills/ca-new-skill/SKILL.md +116 -21
- package/plugins/ca-pi/skills/ca-release/SKILL.md +6 -4
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# codeArbiter — executable release-command confirmation (A-2.10).
|
|
3
3
|
#
|
|
4
|
-
# A row's `pre-tag`
|
|
5
|
-
# shell that `/ca:release`
|
|
4
|
+
# A row's `pre-tag`, `release-build`, `rebuild`, and `generate` commands are
|
|
5
|
+
# operator-authored shell that `/ca:release` may execute before publication.
|
|
6
6
|
# `.codearbiter/release-targets.md` is
|
|
7
7
|
# marker-gated under H-22, so changing those commands already costs a fresh
|
|
8
8
|
# authoring marker — but that gate is about WRITING the file. Nothing made the
|
|
@@ -31,11 +31,13 @@
|
|
|
31
31
|
# file.
|
|
32
32
|
#
|
|
33
33
|
# Public API:
|
|
34
|
-
# pre_tag_digest(commands, release_build=None
|
|
34
|
+
# pre_tag_digest(commands, release_build=None, rebuild=None, generate=None)
|
|
35
|
+
# -> str
|
|
35
36
|
# confirmation_path(root, target) -> str
|
|
36
37
|
# read_confirmation(root, target) -> str | None
|
|
37
38
|
# record_confirmation(root, target, digest) -> str
|
|
38
|
-
# confirmation_state(root, target, commands, release_build=None
|
|
39
|
+
# confirmation_state(root, target, commands, release_build=None,
|
|
40
|
+
# rebuild=None, generate=None) -> str
|
|
39
41
|
# main(argv) -> int
|
|
40
42
|
#
|
|
41
43
|
# CLI:
|
|
@@ -78,7 +80,7 @@ NEVER = "never-confirmed"
|
|
|
78
80
|
NO_COMMANDS = "no-commands"
|
|
79
81
|
|
|
80
82
|
|
|
81
|
-
def pre_tag_digest(commands, release_build=None):
|
|
83
|
+
def pre_tag_digest(commands, release_build=None, rebuild=None, generate=None):
|
|
82
84
|
"""A stable digest of a row's executable release command inputs.
|
|
83
85
|
|
|
84
86
|
ORDER-SENSITIVE on purpose. The commands run in declared order and a
|
|
@@ -91,10 +93,10 @@ def pre_tag_digest(commands, release_build=None):
|
|
|
91
93
|
change to this construction cannot be mistaken for a content change
|
|
92
94
|
by an old recorded value.
|
|
93
95
|
|
|
94
|
-
Rows without
|
|
95
|
-
marker identity, so existing confirmations do not churn.
|
|
96
|
-
command is appended with a typed, length-prefixed
|
|
97
|
-
|
|
96
|
+
Rows without any newly bound scalar command deliberately retain the exact
|
|
97
|
+
v1 digest and marker identity, so existing confirmations do not churn.
|
|
98
|
+
Each present scalar command is appended with a typed, length-prefixed
|
|
99
|
+
record, so changing only one invalidates the same per-target marker.
|
|
98
100
|
|
|
99
101
|
Pure and non-raising: malformed values degrade conservatively to their
|
|
100
102
|
absent forms rather than raising inside a release lane.
|
|
@@ -108,6 +110,10 @@ def pre_tag_digest(commands, release_build=None):
|
|
|
108
110
|
parts.append(f"{len(command)}:{command}")
|
|
109
111
|
if isinstance(release_build, str) and release_build:
|
|
110
112
|
parts.append(f"release-build:{len(release_build)}:{release_build}")
|
|
113
|
+
if isinstance(rebuild, str) and rebuild:
|
|
114
|
+
parts.append(f"rebuild:{len(rebuild)}:{rebuild}")
|
|
115
|
+
if isinstance(generate, str) and generate:
|
|
116
|
+
parts.append(f"generate:{len(generate)}:{generate}")
|
|
111
117
|
joined = "\n".join(parts)
|
|
112
118
|
return hashlib.sha256(joined.encode("utf-8")).hexdigest()
|
|
113
119
|
|
|
@@ -162,22 +168,24 @@ def record_confirmation(root, target, digest):
|
|
|
162
168
|
return path
|
|
163
169
|
|
|
164
170
|
|
|
165
|
-
def confirmation_state(root, target, commands, release_build=None
|
|
171
|
+
def confirmation_state(root, target, commands, release_build=None,
|
|
172
|
+
rebuild=None, generate=None):
|
|
166
173
|
"""One of `confirmed` / `changed` / `never-confirmed` / `no-commands`.
|
|
167
174
|
|
|
168
175
|
`no-commands` is deliberately distinct from `confirmed`: a row that
|
|
169
|
-
declares
|
|
170
|
-
confirm, and reporting it as confirmed would claim an operator approved
|
|
171
|
-
something that does not exist. A
|
|
172
|
-
confirmation. The lane treats `no-commands` and `confirmed` as
|
|
176
|
+
declares none of pre-tag, release-build, rebuild, or generate has nothing
|
|
177
|
+
to confirm, and reporting it as confirmed would claim an operator approved
|
|
178
|
+
something that does not exist. A row with any one scalar command still
|
|
179
|
+
requires confirmation. The lane treats `no-commands` and `confirmed` as
|
|
173
180
|
"proceed", but only one of them is a statement about human review.
|
|
174
181
|
"""
|
|
175
|
-
if not commands and not release_build:
|
|
182
|
+
if not commands and not release_build and not rebuild and not generate:
|
|
176
183
|
return NO_COMMANDS
|
|
177
184
|
recorded = read_confirmation(root, target)
|
|
178
185
|
if recorded is None:
|
|
179
186
|
return NEVER
|
|
180
|
-
return (CONFIRMED if recorded == pre_tag_digest(
|
|
187
|
+
return (CONFIRMED if recorded == pre_tag_digest(
|
|
188
|
+
commands, release_build, rebuild, generate)
|
|
181
189
|
else CHANGED)
|
|
182
190
|
|
|
183
191
|
|
|
@@ -187,7 +195,8 @@ def _row_executable_inputs(target, targets_path=None):
|
|
|
187
195
|
row = next((r for r in rows if r["target"] == target), None)
|
|
188
196
|
if row is None:
|
|
189
197
|
return None
|
|
190
|
-
return row.get("pre_tag") or [], row.get("release_build")
|
|
198
|
+
return (row.get("pre_tag") or [], row.get("release_build"),
|
|
199
|
+
row.get("rebuild"), row.get("generate"))
|
|
191
200
|
|
|
192
201
|
|
|
193
202
|
def main(argv=None):
|
|
@@ -207,26 +216,29 @@ def main(argv=None):
|
|
|
207
216
|
if executable_inputs is None:
|
|
208
217
|
sys.stderr.write(f"unknown release target: {target}\n")
|
|
209
218
|
return 65
|
|
210
|
-
commands, release_build = executable_inputs
|
|
219
|
+
commands, release_build, rebuild, generate = executable_inputs
|
|
211
220
|
|
|
212
221
|
if command == "digest":
|
|
213
|
-
print(pre_tag_digest(commands, release_build))
|
|
222
|
+
print(pre_tag_digest(commands, release_build, rebuild, generate))
|
|
214
223
|
return 0
|
|
215
224
|
|
|
216
225
|
if command == "record":
|
|
217
226
|
path = record_confirmation(
|
|
218
|
-
root, target, pre_tag_digest(
|
|
227
|
+
root, target, pre_tag_digest(
|
|
228
|
+
commands, release_build, rebuild, generate))
|
|
219
229
|
print(f"recorded executable-command confirmation for {target}: {path}")
|
|
220
230
|
return 0
|
|
221
231
|
|
|
222
|
-
state = confirmation_state(
|
|
232
|
+
state = confirmation_state(
|
|
233
|
+
root, target, commands, release_build, rebuild, generate)
|
|
223
234
|
print(state)
|
|
224
235
|
if state in (CONFIRMED, NO_COMMANDS):
|
|
225
236
|
return 0
|
|
226
237
|
if state == CHANGED:
|
|
227
238
|
sys.stderr.write(
|
|
228
239
|
f"releasehash: {target}'s executable release commands have CHANGED "
|
|
229
|
-
"since they were last confirmed. Read every pre-tag
|
|
240
|
+
"since they were last confirmed. Read every pre-tag, release-build, "
|
|
241
|
+
"rebuild, and generate "
|
|
230
242
|
"command, and re-confirm with "
|
|
231
243
|
f"`releasehash.py record {target}` before releasing. These commands "
|
|
232
244
|
"are executed by the release lane, so a change nobody has read is "
|
|
@@ -234,7 +246,8 @@ def main(argv=None):
|
|
|
234
246
|
return 1
|
|
235
247
|
sys.stderr.write(
|
|
236
248
|
f"releasehash: {target}'s executable release commands have never been "
|
|
237
|
-
f"confirmed. Read every pre-tag
|
|
249
|
+
f"confirmed. Read every pre-tag, release-build, rebuild, and generate "
|
|
250
|
+
f"command, then run "
|
|
238
251
|
f"`releasehash.py record {target}`.\n")
|
|
239
252
|
return 2
|
|
240
253
|
|
|
@@ -10,11 +10,30 @@ default to canonical `.html`. Check the installed capability before writing; a
|
|
|
10
10
|
missing, invalid, mismatched or unqualified capability is a STOP and
|
|
11
11
|
the workflow must not fall back to Markdown or create any fallback artifact.
|
|
12
12
|
Report `CAPABILITY_MISSING` and direct the user to repair or reinstall the pinned
|
|
13
|
-
artifact payload before retrying.
|
|
13
|
+
artifact payload before retrying. The payload ships only through the release
|
|
14
|
+
channels: Claude Code `/plugin marketplace update codearbiter` then
|
|
15
|
+
`/plugin update ca@codearbiter`; Codex the `ca-codex-marketplace` ref; Pi
|
|
16
|
+
`pi install npm:@arbiterforge/ca-pi`. A main-branch checkout never carries it. An existing `.md` exact pair remains Markdown
|
|
14
17
|
and continues on the legacy path without automatic conversion. The feature
|
|
15
18
|
small lane remains an inline mini-spec and creates no artifact. HTML `--farm`
|
|
16
19
|
dispatch remains disabled and outside this rollout.
|
|
17
20
|
|
|
21
|
+
## Installed host admission
|
|
22
|
+
|
|
23
|
+
Before new full-lane or plan authoring, the bridge checks the exact installed
|
|
24
|
+
host's required producers, helpers, reviewer charter where applicable, and
|
|
25
|
+
platform-specific hook registrations. `_select_authoring_route` and
|
|
26
|
+
`_preflight_plan_authoring` require this read-only preflight in addition to the
|
|
27
|
+
native engine capability. `HOST_WORKFLOW_UNAVAILABLE` stops before authoring;
|
|
28
|
+
repair the installed package or use a supported host. Never create a fallback
|
|
29
|
+
artifact, substitute another package, or mint an authority event to proceed.
|
|
30
|
+
|
|
31
|
+
`ArtifactClient.workflow_preflight()` reports only installed resources. It does
|
|
32
|
+
not prove host trust, enabled hooks, supported host-version behavior, reviewer
|
|
33
|
+
independence, or a completed live workflow. Actual authority producers and their
|
|
34
|
+
existing validation remain required. Pi currently fails this admission check;
|
|
35
|
+
existing Markdown pairs and the inline small feature lane are unchanged.
|
|
36
|
+
|
|
18
37
|
## Internal execution contract
|
|
19
38
|
|
|
20
39
|
The normal qualified package's installation-owned `release.json` pins the native
|
|
@@ -79,10 +98,11 @@ python "<plugin-root>/hooks/_approvallib.py" cancel --root "<project-root>" --ar
|
|
|
79
98
|
```
|
|
80
99
|
|
|
81
100
|
Cancellation records no authority. Other workflow authorities must use their
|
|
82
|
-
corresponding host-owned adapters
|
|
83
|
-
|
|
84
|
-
authority
|
|
85
|
-
|
|
101
|
+
corresponding host-owned adapters. Legacy `capture` events remain readable for
|
|
102
|
+
inventory but are inspection-only: the engine refuses to wrap them in a current
|
|
103
|
+
receipt. Current authority requires `capture-observation` over a closed producer
|
|
104
|
+
profile and engine-issued evidence context; never create an authority source
|
|
105
|
+
merely to satisfy an artifact transition. `approve` checks the resulting receipt
|
|
86
106
|
against current ready content. A missing or changed receipt, captured event, or
|
|
87
107
|
still-present policy source returns `AUTHORITY_UNVERIFIED`. Receipt format 0.1.0
|
|
88
108
|
remains readable for inspection after upgrade but is not authority-bearing; the
|
|
@@ -91,11 +111,20 @@ approval, dispatch, acceptance, commit proof, or finalization. This is the
|
|
|
91
111
|
repository's cooperative same-user attestation model, not cryptographic identity
|
|
92
112
|
proof or protection from an unrestricted same-user filesystem writer.
|
|
93
113
|
|
|
94
|
-
|
|
95
|
-
to the approved spec
|
|
114
|
+
For ordinary sequential planning, create a plan as `draft_preview`, consume existing criterion IDs,
|
|
115
|
+
then `plan-bind` to the approved spec and approve the plan through its existing workflow. Initial
|
|
116
|
+
combined HTML sprint review uses the explicit paired path below instead of separate approvals.
|
|
96
117
|
A normative change invalidates its approval. Rebinding is explicit and preserves
|
|
97
118
|
history; it does not waive coverage or permit silent reinterpretation.
|
|
98
119
|
|
|
120
|
+
## Initial sprint pair and delegated methods
|
|
121
|
+
|
|
122
|
+
Only when preparing initial combined approval, replaying an observed reply, or revising a task's
|
|
123
|
+
method under its existing grant, load `<plugin-root>/includes/sprint-authority.md`. That private
|
|
124
|
+
card owns the `arm-sprint` / `resume-sprint` / `smarts` bridge and the native pair/method operations.
|
|
125
|
+
Do not bulk-load it for ordinary task reads. Scoring is not consent; the initial observed user reply,
|
|
126
|
+
protected scope, real producer, current evidence and existing security/permission gates remain required.
|
|
127
|
+
|
|
99
128
|
## Reading and dispatch
|
|
100
129
|
|
|
101
130
|
Use `index`, then `outline`, then symbol-scoped `read`. Exact reads are explicitly
|
|
@@ -147,8 +176,8 @@ python "<plugin-root>/hooks/_prerequisitelib.py" supersede --root "<project-root
|
|
|
147
176
|
```
|
|
148
177
|
|
|
149
178
|
The adapter fixes `authority_kind: user_workflow` and `verdict: satisfied`;
|
|
150
|
-
there is no caller-selected authority or bulk-satisfaction path. SMARTS remains
|
|
151
|
-
|
|
179
|
+
there is no caller-selected authority or bulk-satisfaction path. SMARTS prerequisite satisfaction remains unsupported; the plan-method producer below does not
|
|
180
|
+
grant prerequisite, security, backend or publication authority. Pi has no
|
|
152
181
|
qualified pre-model prompt seam and must remain blocked. Do not infer eligibility from one satisfied prerequisite:
|
|
153
182
|
rerun `eligible`, and resolve each remaining record independently against the
|
|
154
183
|
new current plan identity.
|
|
@@ -161,10 +190,88 @@ verification and spec review. Across checkpoints, dependencies require accepted
|
|
|
161
190
|
scope evidence. Provisional progress never counts as completion.
|
|
162
191
|
|
|
163
192
|
The orchestrator executes the declared verification through its existing governed
|
|
164
|
-
execution tool
|
|
165
|
-
a
|
|
166
|
-
|
|
167
|
-
|
|
193
|
+
execution tool through the installed production authority adapter; it never
|
|
194
|
+
constructs a successful workflow event itself. Arm an exact task request first.
|
|
195
|
+
Verification and review authority below is supported on Codex and Claude Code.
|
|
196
|
+
On Pi, stop at this boundary rather than treating model-authored results as
|
|
197
|
+
authority; its installed prompt approval seam does not imply verification or
|
|
198
|
+
review support.
|
|
199
|
+
Every distinct `cwd` label in the engine context must be mapped once to an exact
|
|
200
|
+
linked Git worktree root. Mapped worktrees must share the artifact repository's
|
|
201
|
+
Git common directory, and the adapter freezes their filesystem identity, HEAD,
|
|
202
|
+
status digest, effective argv, and executable bytes:
|
|
203
|
+
|
|
204
|
+
```sh
|
|
205
|
+
python "<plugin-root>/hooks/artifact-authority.py" arm --root "<project-root>" --artifact-id <plan-id> --record-id <task-id> --activity verification --workspace "candidate worktree=<absolute-worktree>" --workspace "baseline-evidence worktree=<absolute-worktree>"
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Use only the mappings actually named by that task; missing or extra labels fail
|
|
209
|
+
closed. Run the returned request through one plain governed exec invocation (no
|
|
210
|
+
compound shell expression), then publish only after the host's matching
|
|
211
|
+
`PostToolUse` has corroborated the wrapper's completed request-bound result:
|
|
212
|
+
|
|
213
|
+
```sh
|
|
214
|
+
python "<plugin-root>/hooks/artifact-authority.py" verify --root "<project-root>" --request-id <request-id>
|
|
215
|
+
python "<plugin-root>/hooks/artifact-authority.py" publish --root "<project-root>" --request-id <request-id>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
The verifier launches exact engine-declared argv without a shell, supervises the
|
|
219
|
+
whole process tree, bounds output, requires exact named outcomes, and rejects
|
|
220
|
+
workspace or executable drift. If an attempt is interrupted, use the adapter's
|
|
221
|
+
`recover` operation to retain it as failed or abandoned; never rerun an uncertain
|
|
222
|
+
attempt under the same request.
|
|
223
|
+
|
|
224
|
+
For `spec_review` or `quality_review`, arm the corresponding activity without
|
|
225
|
+
workspace mappings and dispatch the returned `launch_envelope` unchanged to one
|
|
226
|
+
fresh host subagent. The host hooks bind the exact launch call, child start and
|
|
227
|
+
the child's first stop; a pasted or coordinator-authored decision is not review
|
|
228
|
+
authority.
|
|
229
|
+
Publish the completed request through the same `publish` command. `task-review`
|
|
230
|
+
records the separate verification and spec-review receipts. After every task in
|
|
231
|
+
the scope reaches `REVIEW`, reverify against one current source snapshot, run the
|
|
232
|
+
combined quality review, and use `accept-scope` once. Do not accept tasks
|
|
233
|
+
individually.
|
|
234
|
+
|
|
235
|
+
An interrupted or `BLOCKED` HTML task never resumes by editing its status. Arm
|
|
236
|
+
the installed reconciliation adapter for the exact task or scope, present its
|
|
237
|
+
returned reply verbatim, and let `UserPromptSubmit` capture and apply the observed
|
|
238
|
+
user decision across repositories:
|
|
239
|
+
|
|
240
|
+
```sh
|
|
241
|
+
python "<plugin-root>/hooks/artifact-reconcile.py" --root "<project-root>" --artifact-id <plan-id> --target-id <task-id> --operation task-reconcile --target-state PENDING --reason "<reviewed reason>" --assessment "<reviewed assessment>"
|
|
242
|
+
python "<plugin-root>/hooks/artifact-reconcile.py" --root "<project-root>" --artifact-id <plan-id> --target-id <checkpoint-id> --operation scope-reconcile --assessment "<reviewed assessment>"
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Ambiguous armed requests, changed identities, stale inputs, wrong replies, or a
|
|
246
|
+
foreign Git repository all fail closed. Re-run `eligible` after reconciliation;
|
|
247
|
+
the prompt reply itself is not proof that the lifecycle mutation committed.
|
|
248
|
+
If a mutation response is lost, submit the same exact reply again: the adapter
|
|
249
|
+
replays its durable operation ID and receipt without recapturing authority. A
|
|
250
|
+
request that has not reached mutation can be cancelled with:
|
|
251
|
+
|
|
252
|
+
```sh
|
|
253
|
+
python "<plugin-root>/hooks/artifact-reconcile.py" --root "<project-root>" --artifact-id <plan-id> --cancel --prompt "<exact returned reply>"
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
If a crash left a complete pending request before its prompt route was
|
|
257
|
+
registered, use this command instead. It refuses an active route or any
|
|
258
|
+
in-flight mutation:
|
|
259
|
+
|
|
260
|
+
```sh
|
|
261
|
+
python "<plugin-root>/hooks/artifact-reconcile.py" --root "<project-root>" --artifact-id <plan-id> --cancel-orphan
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
If a durable mutation attempt exists, neither cancellation path can clear it.
|
|
265
|
+
Replay the exact stored operation and receipt under the reconciliation lock:
|
|
266
|
+
|
|
267
|
+
```sh
|
|
268
|
+
python "<plugin-root>/hooks/artifact-reconcile.py" --root "<project-root>" --artifact-id <plan-id> --recover
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Recovery clears the request only on a committed replay or a closed-set engine
|
|
272
|
+
result proving no commit (`REVISION_CONFLICT` or `OPERATION_ROLLED_BACK`). Other
|
|
273
|
+
errors retain it for investigation. Re-arm only after cancellation or recovery
|
|
274
|
+
succeeds; a committed recovery is not permission to repeat the mutation.
|
|
168
275
|
|
|
169
276
|
`IN_PROGRESS` after interruption requires reconciliation, not automatic completion.
|
|
170
277
|
`REVIEW` requires fresh evidence. Source changes stale proof; state/branding updates
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Sprint approval and delegated method authority
|
|
2
|
+
|
|
3
|
+
This private extension adds no registered command, skill or agent. Check that the verified installed
|
|
4
|
+
native capability lists `sprint-approval-context`, `sprint-approve` and `smarts-apply`; a schema name
|
|
5
|
+
or model-written event is not an implementation. Qualified exact-prompt host observation remains
|
|
6
|
+
Claude Code or Codex only. Pi must not arm it without a real pre-model prompt seam. Other existing
|
|
7
|
+
host-specific verification/review restrictions are unchanged.
|
|
8
|
+
|
|
9
|
+
Prepare the complete ready same-slug spec and plan as unapproved drafts. The private planner
|
|
10
|
+
preflight accepts `draft_for_pair: true` only for a full-lane initial sprint, never `/feature`, an
|
|
11
|
+
existing approved pair, or an execution shortcut. Keep its `draft_preview` binding until the paired
|
|
12
|
+
transaction. Run scope/criterion coverage, recorded-intent and adversarial review on both drafts.
|
|
13
|
+
Present the optional plan-method delegation in the review packet before arming:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
python "<plugin-root>/hooks/_approvallib.py" arm-sprint --root "<project-root>" --spec-id <spec-id> --plan-id <plan-id> --delegate-methods
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Omit `--delegate-methods` for approval without delegated plan-method changes. Show the returned
|
|
20
|
+
`reply` verbatim. It explicitly names both IDs, `delegate-methods` or `approve-only`, and the nonce.
|
|
21
|
+
An ordinary yes, wrong nonce/mode or changed member does not approve either. `sprint-approve`
|
|
22
|
+
recomputes both model/revision identities and the projected binding, verifies both observations
|
|
23
|
+
from the same actual reply, and commits the two approvals through the existing native journal.
|
|
24
|
+
It produces separate bound receipts and an optional `grant_receipt`. No partial approval is visible
|
|
25
|
+
while recovery is required. Generic `capture-observation` and single-artifact `approve` cannot reuse
|
|
26
|
+
these pair events to approve one half. Confirm both current `approved` gates before dispatch.
|
|
27
|
+
|
|
28
|
+
An interrupted observed submission retains its exact source events, operation ID and both CAS
|
|
29
|
+
identities. Resume it without asking the user to repeat the same decision:
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
python "<plugin-root>/hooks/_approvallib.py" resume-sprint --root "<project-root>" --plan-id <plan-id>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Arming without an observed reply cannot be resumed as authority. Recovery completes only this
|
|
36
|
+
exact observed transaction, not an unrelated pending operation. A committed replay is success;
|
|
37
|
+
a closed-set `REVISION_CONFLICT` or `OPERATION_ROLLED_BACK` proves this mutation did not commit and
|
|
38
|
+
retires only its stale pending request while preserving source history. Changed content needs a
|
|
39
|
+
new genuine approval, not an invented receipt. Other failures retain the request for diagnosis.
|
|
40
|
+
Before observation, the existing `cancel --artifact-id <plan-id>` clears an unapproved arm. After
|
|
41
|
+
submission, resume/recover first; cancellation cannot erase an uncertain transaction.
|
|
42
|
+
|
|
43
|
+
With an explicit paired user grant, evaluate an existing task-method choice using SMARTS Step 0,
|
|
44
|
+
all six lens verdicts and the actual supporting reasons. Query only the `smarts-apply` request schema.
|
|
45
|
+
Provide the exact current plan `artifact_id`, `expected` revision/model hash, unique `operation_id`,
|
|
46
|
+
original `grant_receipt`, and `decision` with task ID, options, selected index, strength and rationale.
|
|
47
|
+
Each option contains label, steps and the six qualitative verdict/reason cells. There is no new
|
|
48
|
+
numeric threshold, mandatory invented alternative or tie-triggered user interview. Persist the
|
|
49
|
+
bounded JSON request as inert input and invoke the installation-owned bridge:
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
python "<plugin-root>/hooks/_approvallib.py" smarts --root "<project-root>" --request-file <decision-request.json>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The native producer validates the original user grant and current bound spec/plan. Only the selected
|
|
56
|
+
existing task's method `steps` may change. Every path, criterion, test/verification definition,
|
|
57
|
+
prerequisite, dependency, checkpoint, rollback and input policy stays protected. Changes that widen
|
|
58
|
+
this scope or need a different authority use their real owner. The producer does not turn step text
|
|
59
|
+
into shell permission and never grants commit, network/provider, spending, disclosure, publication,
|
|
60
|
+
prerequisite or security authority. Normal execution gates still apply to the chosen method.
|
|
61
|
+
|
|
62
|
+
An affected `IN_PROGRESS` writer must quiesce before mutation. A successful method change emits an
|
|
63
|
+
actual `smarts_workflow` event/receipt and current plan approval together, invalidates affected
|
|
64
|
+
checkpoint/dependency proof to `PENDING` while preserving `BLOCKED` members and their reasons,
|
|
65
|
+
retains evidence refs as history and requires fresh context,
|
|
66
|
+
verification and reviews. It never accepts work. An identical method needs no new approval; retain
|
|
67
|
+
current evidence rather than manufacturing another attempt. Log material reasoning and record
|
|
68
|
+
citations in the existing sprint audit. Recorded judgments remain model judgments: integrity and
|
|
69
|
+
scope checks do not independently prove their truth or create a malicious-same-user sandbox.
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Skill bodies load on routing only. This index is the surface scan; never bulk-read
|
|
4
4
|
`skills/*/SKILL.md`. Each skill is an orchestrator routine with gated phases, routed to, never
|
|
5
|
-
"triggered."
|
|
5
|
+
"triggered." Command-backed owners `commit-gate` and `skill-author` supply their
|
|
6
|
+
complete public entries at build time. Claude keeps the owner discoverable and the
|
|
7
|
+
command explicit-only; Codex/Pi expose the entry and keep the routine private. Read a needed owner directly or use the complete public body,
|
|
8
|
+
not both merely to repeat the same procedure. This index lists what each skill OWNS; to decide WHERE a trigger routes, load
|
|
6
9
|
`<plugin-root>/includes/routing-table.md` (the authoritative trigger→route surface).
|
|
7
10
|
|
|
8
11
|
| Skill | Routed to by | Owns |
|
|
@@ -14,9 +17,9 @@ Skill bodies load on routing only. This index is the surface scan; never bulk-re
|
|
|
14
17
|
| [refactor](refactor/SKILL.md) | `/refactor` | Behavior-preserving change behind a parity-coverage proof gate; routes to `tdd` Phase 1 only when new test seams are needed. |
|
|
15
18
|
| [context-creation](context-creation/SKILL.md) | `/create-context` (brownfield) | Back-fills `.codearbiter/` from existing source via parallel scouts; writes `CONTEXT.md` (`arbiter: enabled` + `stage:`) and locks it `<!--INITIALIZED-->`. |
|
|
16
19
|
| [decompose](decompose/SKILL.md) | greenfield startup, `/decompose` | Six-layer senior-architect interview, compaction-resilient via per-layer disk drafts + DRAFT ADRs; populates `.codearbiter/` and locks it initialized. |
|
|
17
|
-
| [brainstorming](brainstorming/SKILL.md) | `/feature` (front), `/sprint` planning |
|
|
18
|
-
| [writing-plans](writing-plans/SKILL.md) | `/feature`, `/sprint` (after the spec) | Decomposes
|
|
19
|
-
| [executing-plans](executing-plans/SKILL.md) | `/feature` |
|
|
20
|
+
| [brainstorming](brainstorming/SKILL.md) | `/feature` (front), `/sprint` planning | Caller-scoped feature or coherent sprint specification. Initial approval is user-owned; delegated choices require existing authority. Uses the selected artifact format, preserves recorded intent, and returns or forwards to the caller's required planning step before execution. |
|
|
21
|
+
| [writing-plans](writing-plans/SKILL.md) | `/feature`, `/sprint` (after the spec) | Decomposes the exact approved spec, or a ready draft through the initial sprint-only pair preflight. Retains same-format criterion/task coverage, paths and verification; combined drafts return for one real spec-and-plan reply before execution. Ordinary sequential binding remains unchanged. |
|
|
22
|
+
| [executing-plans](executing-plans/SKILL.md) | `/feature` | Attended coordinator: uses authored HTML checkpoint membership or bounded legacy batches, delegates to `subagent-driven-development`, and retains the user checkpoint. A display batch never changes an HTML acceptance scope; sprint does not inherit these pauses. |
|
|
20
23
|
| [subagent-driven-development](subagent-driven-development/SKILL.md) | `/sprint` (engine), `executing-plans` (batch scope) | Fresh subagent per task → spec-compliance then quality review → fresh-run verification; accepts only on proof. A quality failure blocks acceptance; approved sprint recovery owns correction. Security CRITICAL and unresolved `[CONFIRM-NN]` remain stops. |
|
|
21
24
|
| [dispatching-parallel-agents](dispatching-parallel-agents/SKILL.md) | `subagent-driven-development`, `/sprint`, parallel `/review` | Reusable fan-out primitive: bound concurrency, collect, dedupe, funnel through `finding-triage`→`verdict-aggregator`. Results unused until the read-only funnel runs. |
|
|
22
25
|
| [finishing-a-development-branch](finishing-a-development-branch/SKILL.md) | `/feature`, `/sprint` (terminal) | The terminal step after `commit-gate`: open-PR / merge-via-PR / discard. No direct-to-main, no force-push; `/sprint` auto-selects open-PR and never merges. |
|