@shenlee/devcrew 0.1.4 → 0.1.5

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.
@@ -1,313 +0,0 @@
1
- # Safety Semantics Implementation Plan
2
-
3
- > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
-
5
- **Goal:** Make apply-mode execution policy explicit and prevent failed or absent verification from silently promoting an isolated patch.
6
-
7
- **Architecture:** Add a persistent execution policy and verification outcome to the workflow state. Interactive apply runs pause with a host-execution handoff instead of launching a nested SDK; explicitly selected headless policies retain SDK execution with declared permissions. Testing only opens a normal promotion gate after successful verification; a separate waiver records the reason before an exception can be approved.
8
-
9
- **Tech Stack:** TypeScript, Node.js test runner, MCP JSON-RPC tools, Git worktrees.
10
-
11
- ---
12
-
13
- ## File Structure
14
-
15
- - Modify: `packages/core/src/types.ts` — policy, verification, handoff, and waiver state contracts.
16
- - Modify: `packages/core/src/validation.ts` — parse policy and waiver input.
17
- - Modify: `packages/core/src/workflow.ts` — default/apply-policy invariants and waiver transition.
18
- - Modify: `packages/core/src/store.ts` — migrate persisted legacy runs safely.
19
- - Modify: `packages/adapters/src/index.ts` — explicit headless SDK options; no implicit approval inheritance.
20
- - Modify: `packages/orchestrator/src/index.ts` — interactive execution pause/submission and verification gate blocking.
21
- - Modify: `packages/service/src/tools.ts` — MCP schemas and handlers for execution completion and verification waiver.
22
- - Modify: `packages/core/src/artifacts.ts` — render policy, verification status, and waiver evidence.
23
- - Modify: `tests/core.test.ts`, `tests/adapters-sdk.test.ts`, `tests/orchestrator.test.ts`, `tests/service.test.ts` — red/green coverage for every new state transition.
24
- - Modify: `README.md`, `docs/workflow.md`, `docs/codex.md`, `docs/claude-code.md`, `packages/plugins/src/index.ts` — correct public behavior and generated skill copy.
25
-
26
- ### Task 1: Persist explicit execution and verification semantics
27
-
28
- **Files:**
29
- - Modify: `packages/core/src/types.ts`
30
- - Modify: `packages/core/src/validation.ts`
31
- - Modify: `packages/core/src/store.ts`
32
- - Test: `tests/core.test.ts`
33
-
34
- - [ ] **Step 1: Write failing state-contract tests**
35
-
36
- Add tests that start an apply workflow with `executionPolicy: "headless-restricted"`, assert the policy persists through `loadState`, and assert unknown policy values fail validation. Add a migration fixture without the new fields and assert it loads as an interactive-host apply run with `verificationStatus: "not_run"` and no waiver.
37
-
38
- ```ts
39
- assert.equal(state.executionPolicy, "headless-restricted");
40
- await assert.rejects(
41
- () => startWorkflow({ ...input, executionMode: "apply", executionPolicy: "unsafe" }),
42
- /executionPolicy/,
43
- );
44
- assert.equal(loaded.verificationStatus, "not_run");
45
- ```
46
-
47
- - [ ] **Step 2: Run the focused core test and verify RED**
48
-
49
- Run: `node --import tsx --test tests/core.test.ts`
50
-
51
- Expected: FAIL because `executionPolicy` and `verificationStatus` are not yet represented in state or input validation.
52
-
53
- - [ ] **Step 3: Add the minimal state and parsing contracts**
54
-
55
- In `types.ts`, add:
56
-
57
- ```ts
58
- export const EXECUTION_POLICIES = ["interactive-host", "headless-restricted", "headless-unattended"] as const;
59
- export type ExecutionPolicy = (typeof EXECUTION_POLICIES)[number];
60
- export type VerificationStatus = "not_run" | "passed" | "failed";
61
-
62
- export interface VerificationWaiver { reason: string; createdAt: string; }
63
- ```
64
-
65
- Add `executionPolicy` to `StartWorkflowInput` and `RunState`, plus
66
- `verificationStatus` and optional `verificationWaiver` to `RunState`. Add
67
- `parseExecutionPolicy()` and `parseWaiverReason()` in `validation.ts`. In
68
- `loadState`, use `interactive-host` for legacy apply runs and `not_run` for
69
- missing verification status.
70
-
71
- - [ ] **Step 4: Run the focused core test and verify GREEN**
72
-
73
- Run: `node --import tsx --test tests/core.test.ts`
74
-
75
- Expected: PASS, including new persistence and invalid-policy cases.
76
-
77
- - [ ] **Step 5: Commit the state contract**
78
-
79
- ```bash
80
- git add packages/core/src/types.ts packages/core/src/validation.ts packages/core/src/store.ts tests/core.test.ts
81
- git commit -m "feat: record execution and verification policy"
82
- ```
83
-
84
- ### Task 2: Make SDK execution explicitly headless
85
-
86
- **Files:**
87
- - Modify: `packages/adapters/src/index.ts`
88
- - Test: `tests/adapters-sdk.test.ts`
89
-
90
- - [ ] **Step 1: Write failing adapter-policy tests**
91
-
92
- Replace the assertion that Claude apply uses `acceptEdits` with tests proving
93
- that an interactive-host execution is rejected before SDK invocation and that
94
- headless policies select explicit SDK options. For Claude restricted mode, the
95
- test must assert `permissionMode: "dontAsk"` and a narrow tool list. For Codex,
96
- assert `approvalPolicy: "never"` only for `headless-unattended` and no implicit
97
- approval-policy value for read-only planning.
98
-
99
- ```ts
100
- await assert.rejects(
101
- () => runRole({ ...baseInput, phase: "execution", executionMode: "apply", executionPolicy: "interactive-host", backend: "claude" }),
102
- /interactive-host execution must be performed by the host/,
103
- );
104
- ```
105
-
106
- - [ ] **Step 2: Run the focused adapter test and verify RED**
107
-
108
- Run: `node --import tsx --test tests/adapters-sdk.test.ts`
109
-
110
- Expected: FAIL because `RoleRunInput` lacks the policy and Claude currently
111
- sets `acceptEdits` with bare `Bash` permission.
112
-
113
- - [ ] **Step 3: Implement explicit headless profiles**
114
-
115
- Add `executionPolicy` to `RoleRunInput`. Make `roleCanApply()` require a
116
- headless policy. Reject SDK execution for `interactive-host`. Replace the
117
- Claude restricted profile with `dontAsk`: implementers receive only `Read`,
118
- `Grep`, `Glob`, `Edit`, and `Write`; testers receive only `Read`, `Grep`, and
119
- `Glob`. Neither restricted role receives `Bash`; DevCrew's configured command
120
- runner supplies verification evidence separately. For the explicitly selected
121
- unattended policy, add the SDK's dangerous-skip opt-in and set Claude to
122
- `bypassPermissions`; this is an auditable CI-only policy. Pass Codex
123
- `approvalPolicy: "never"` only for that unattended policy. Document that both
124
- headless profiles are DevCrew policies, not inherited host approval.
125
-
126
- - [ ] **Step 4: Run the focused adapter test and verify GREEN**
127
-
128
- Run: `node --import tsx --test tests/adapters-sdk.test.ts`
129
-
130
- Expected: PASS with no `acceptEdits` assertion remaining.
131
-
132
- - [ ] **Step 5: Commit the adapter boundary**
133
-
134
- ```bash
135
- git add packages/adapters/src/index.ts tests/adapters-sdk.test.ts
136
- git commit -m "fix: make SDK apply policies explicit"
137
- ```
138
-
139
- ### Task 3: Add the interactive execution handoff
140
-
141
- **Files:**
142
- - Modify: `packages/orchestrator/src/index.ts`
143
- - Modify: `packages/service/src/tools.ts`
144
- - Test: `tests/orchestrator.test.ts`
145
- - Test: `tests/service.test.ts`
146
-
147
- - [ ] **Step 1: Write failing handoff tests**
148
-
149
- Add an apply workflow with `executionPolicy: "interactive-host"`. After the
150
- implementation gate is approved, `devcrew_continue` must create the isolated
151
- worktree but not call the injected `RoleRunner`; it returns
152
- `status: "awaiting_execution"` and structured instruction data. A new
153
- `devcrew_complete_execution` call captures the worktree patch and advances to
154
- testing without modifying the requester repository. Repeat the same handoff
155
- for the tester: it receives the test-report instruction, returns exact command
156
- result records, and DevCrew derives the verification status from those records.
157
-
158
- ```ts
159
- assert.equal(paused.status, "awaiting_execution");
160
- assert.equal(runnerCalls.filter((call) => call.phase === "execution").length, 0);
161
- assert.equal(paused.executionInstruction?.cwd, paused.executionWorkspace?.path);
162
- ```
163
-
164
- - [ ] **Step 2: Run focused orchestrator and service tests and verify RED**
165
-
166
- Run: `node --import tsx --test tests/orchestrator.test.ts tests/service.test.ts`
167
-
168
- Expected: FAIL because the current orchestrator immediately invokes the SDK
169
- runner and no completion MCP tool exists.
170
-
171
- - [ ] **Step 3: Implement pause and completion transitions**
172
-
173
- Add `awaiting_execution` to `RunStatus` and an `ExecutionInstruction` state
174
- object containing role, phase, worktree cwd, request, standards, approved
175
- artifacts, and required result sections. In the execution and testing branches
176
- of `runCurrentPhaseRole`, ensure the worktree, write the instruction, persist
177
- the state, and return without calling `runner` or `runConfiguredVerification`
178
- when policy is `interactive-host`.
179
-
180
- Add `completeInteractiveExecution(input)` to orchestrator. It requires an
181
- `awaiting_execution` state and a required Markdown summary supplied by the
182
- host. For execution it captures changes, runs no nested SDK or shell command,
183
- writes implementation-review evidence, and moves to `testing/ready`. For
184
- testing it accepts a validated array of `{ command, exitCode, output,
185
- startedAt, completedAt }`, writes the test report, derives the verification
186
- status, and either opens the gate or enters the failure path. Expose it as
187
- `devcrew_complete_execution` with an input schema that includes `summary` and
188
- optional `verification` records.
189
-
190
- - [ ] **Step 4: Run focused handoff tests and verify GREEN**
191
-
192
- Run: `node --import tsx --test tests/orchestrator.test.ts tests/service.test.ts`
193
-
194
- Expected: PASS; the requester repository remains unchanged until a later
195
- testing approval.
196
-
197
- - [ ] **Step 5: Commit the interactive handoff**
198
-
199
- ```bash
200
- git add packages/orchestrator/src/index.ts packages/service/src/tools.ts tests/orchestrator.test.ts tests/service.test.ts
201
- git commit -m "feat: hand interactive apply execution to host"
202
- ```
203
-
204
- ### Task 4: Block failed verification and require a recorded waiver
205
-
206
- **Files:**
207
- - Modify: `packages/core/src/workflow.ts`
208
- - Modify: `packages/orchestrator/src/index.ts`
209
- - Modify: `packages/service/src/tools.ts`
210
- - Modify: `packages/core/src/artifacts.ts`
211
- - Test: `tests/orchestrator.test.ts`
212
- - Test: `tests/service.test.ts`
213
-
214
- - [ ] **Step 1: Write failing verification tests**
215
-
216
- Create an apply fixture with `verifyCommands: ["node -e \"process.exit(7)\""]`.
217
- After testing, assert `verificationStatus === "failed"`, `status ===
218
- "awaiting_input"`, and that `approveOrchestratedWorkflow({ gate: "testing" })`
219
- rejects without promoting the patch. Add a second test showing that
220
- `devcrew_waive_verification` rejects an empty reason, persists a non-empty
221
- reason, reopens the testing gate, and permits promotion only after normal
222
- testing approval.
223
-
224
- ```ts
225
- await assert.rejects(
226
- () => approveOrchestratedWorkflow({ cwd, runId, gate: "testing" }),
227
- /verification failed/,
228
- );
229
- assert.equal(waived.verificationWaiver?.reason, "Known upstream test outage");
230
- ```
231
-
232
- - [ ] **Step 2: Run focused workflow tests and verify RED**
233
-
234
- Run: `node --import tsx --test tests/orchestrator.test.ts tests/service.test.ts`
235
-
236
- Expected: FAIL because a nonzero command currently still opens the pending
237
- testing gate and no waiver tool exists.
238
-
239
- - [ ] **Step 3: Implement verification outcome and waiver flow**
240
-
241
- After `runConfiguredVerification`, set `verificationStatus` from every result:
242
- empty is `not_run`, all-zero is `passed`, otherwise `failed`. A failed status
243
- sets `awaiting_input` and does not set the testing gate to pending. Add
244
- `waiveVerification(input)` that requires failed verification and a non-empty
245
- reason, records `VerificationWaiver`, changes the testing gate to pending, and
246
- sets `awaiting_approval`. Add `devcrew_waive_verification` to the MCP schema
247
- and handler.
248
-
249
- Make `approveOrchestratedWorkflow` reject a testing promotion unless status is
250
- passed or a waiver exists. Render the status, command exit evidence, and waiver
251
- reason in both the test report and acceptance artifact.
252
-
253
- - [ ] **Step 4: Run focused verification tests and verify GREEN**
254
-
255
- Run: `node --import tsx --test tests/orchestrator.test.ts tests/service.test.ts`
256
-
257
- Expected: PASS; failed verification cannot mutate the requester repository,
258
- while a recorded waiver remains visible and permits intentional approval.
259
-
260
- - [ ] **Step 5: Commit verification safety**
261
-
262
- ```bash
263
- git add packages/core/src/workflow.ts packages/orchestrator/src/index.ts packages/service/src/tools.ts packages/core/src/artifacts.ts tests/orchestrator.test.ts tests/service.test.ts
264
- git commit -m "fix: block failed verification promotion"
265
- ```
266
-
267
- ### Task 5: Correct generated instructions and user-facing documentation
268
-
269
- **Files:**
270
- - Modify: `README.md`
271
- - Modify: `docs/workflow.md`
272
- - Modify: `docs/codex.md`
273
- - Modify: `docs/claude-code.md`
274
- - Modify: `packages/plugins/src/index.ts`
275
- - Test: `tests/plugins.test.ts`
276
-
277
- - [ ] **Step 1: Write failing generated-skill/doc assertions**
278
-
279
- Extend plugin tests to require the generated skill to distinguish
280
- interactive-host execution from headless policy and to mention
281
- `devcrew_complete_execution` and `devcrew_waive_verification`.
282
-
283
- - [ ] **Step 2: Run plugin tests and verify RED**
284
-
285
- Run: `node --import tsx --test tests/plugins.test.ts`
286
-
287
- Expected: FAIL because the generated skill promises inherited host approvals
288
- and lacks the new handoff/waiver tools.
289
-
290
- - [ ] **Step 3: Update generated skill and docs**
291
-
292
- Document that interactive host execution uses the host's native agent after
293
- DevCrew supplies a worktree instruction; it does not run a nested SDK. Document
294
- headless policies as explicit DevCrew policies. Replace all claims that DevCrew
295
- inherits a current host approval boundary. Add the failed-verification and
296
- recorded-waiver transition to workflow diagrams and tool lists.
297
-
298
- - [ ] **Step 4: Run plugin tests and verify GREEN**
299
-
300
- Run: `node --import tsx --test tests/plugins.test.ts`
301
-
302
- Expected: PASS with the checked-in plugin matching regenerated text.
303
-
304
- - [ ] **Step 5: Run full validation and commit documentation**
305
-
306
- Run: `npm run validate`
307
-
308
- Expected: exit code 0 with all tests passing.
309
-
310
- ```bash
311
- git add README.md docs/workflow.md docs/codex.md docs/claude-code.md packages/plugins/src/index.ts plugins/devcrew-codex plugins/devcrew-claude tests/plugins.test.ts
312
- git commit -m "docs: describe explicit apply execution policies"
313
- ```
@@ -1,213 +0,0 @@
1
- # P0 Verification and Review Remediation Implementation Plan
2
-
3
- > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
-
5
- **Goal:** Prevent unverified apply patches from being promoted and send architecture-review findings back through implementation.
6
-
7
- **Architecture:** Keep `verificationStatus` as the single source for testing-gate policy. Treat `failed` and `not_run` identically for blocking, but allow the existing persisted waiver to reopen either state. Reuse the existing testing-rejection recovery pattern for implementation-review findings, preserving the isolated worktree while returning the state machine to `execution/ready`.
8
-
9
- **Tech Stack:** TypeScript, Node.js test runner, Git worktrees, existing DevCrew MCP/orchestrator APIs.
10
-
11
- ---
12
-
13
- ### Task 1: Block missing verification evidence
14
-
15
- **Files:**
16
- - Modify: `tests/orchestrator.test.ts:483-533`
17
- - Modify: `packages/orchestrator/src/index.ts:241-253, 552-558`
18
- - Modify: `packages/core/src/workflow.ts:297-314`
19
-
20
- - [ ] **Step 1: Write failing no-verification tests**
21
-
22
- Add a test after the failed-verification test that creates an apply fixture with
23
- an empty `verifyCommands` list and no discoverable manifest. Advance it through
24
- testing and assert the following:
25
-
26
- ```ts
27
- assert.equal(tested.verificationStatus, "not_run");
28
- assert.equal(tested.gates.testing, "rejected");
29
- assert.equal(tested.status, "awaiting_input");
30
- await assert.rejects(
31
- () => approveOrchestratedWorkflow({ cwd, runId: tested.runId, gate: "testing" }),
32
- /not pending approval/i,
33
- );
34
- ```
35
-
36
- In the same test, call `waiveOrchestratedVerification` with a non-empty reason,
37
- assert `testing: pending` and `awaiting_approval`, then approve testing and
38
- assert the reviewed file was promoted. Add a second assertion that directly
39
- sets a persisted test fixture to `verificationStatus: "not_run"`, a pending
40
- testing gate, and no waiver, then expects `approveOrchestratedWorkflow` to
41
- throw `Verification must pass before promotion`.
42
-
43
- - [ ] **Step 2: Run the focused test and verify RED**
44
-
45
- Run:
46
-
47
- ```bash
48
- node --import tsx --test tests/orchestrator.test.ts
49
- ```
50
-
51
- Expected: the new test fails because `not_run` currently opens a pending gate
52
- and the waiver operation rejects it.
53
-
54
- - [ ] **Step 3: Implement the minimal verification policy**
55
-
56
- In `setTestingGateFromVerification`, replace the `failed`-only branch with a
57
- non-passed branch. Preserve the existing failed message and add a distinct
58
- missing-evidence message:
59
-
60
- ```ts
61
- if (state.verificationStatus !== "passed") {
62
- state.gates.testing = "rejected";
63
- state.status = "awaiting_input";
64
- state.feedback.push({
65
- gate: "testing",
66
- message: state.verificationStatus === "failed"
67
- ? "Automated verification failed. Inspect the test report, revise the implementation, or record an explicit verification waiver with its reason."
68
- : "No verification evidence was recorded. Configure or run validation, revise the implementation, or record an explicit verification waiver with its reason.",
69
- createdAt: now(),
70
- });
71
- return;
72
- }
73
- ```
74
-
75
- Update `waiveVerificationWorkflow` to accept either `failed` or `not_run` and
76
- change its error message to mention failed or missing verification. In
77
- `approveOrchestratedWorkflow`, replace the failed-only promotion check with:
78
-
79
- ```ts
80
- if (before.verificationStatus !== "passed" && !before.verificationWaiver) {
81
- throw new Error("Verification must pass before promotion or have an explicit verification waiver");
82
- }
83
- ```
84
-
85
- - [ ] **Step 4: Run focused tests and verify GREEN**
86
-
87
- Run:
88
-
89
- ```bash
90
- node --import tsx --test tests/orchestrator.test.ts
91
- ```
92
-
93
- Expected: all orchestrator tests pass, including failed and missing
94
- verification waiver paths.
95
-
96
- - [ ] **Step 5: Commit the verification fix**
97
-
98
- ```bash
99
- git add packages/core/src/workflow.ts packages/orchestrator/src/index.ts tests/orchestrator.test.ts
100
- git commit -m "fix: block promotion without verification evidence"
101
- ```
102
-
103
- ### Task 2: Return review findings to execution
104
-
105
- **Files:**
106
- - Modify: `tests/orchestrator.test.ts:365-421`
107
- - Modify: `packages/orchestrator/src/index.ts:639-658`
108
- - Modify: `docs/workflow.md:45-49`
109
-
110
- - [ ] **Step 1: Write the failing review-remediation test**
111
-
112
- Extend `architecture review blocks testing when it requires changes` after its
113
- current rejection assertions. Call `answerOrchestratedWorkflow` with a
114
- non-empty answer and assert:
115
-
116
- ```ts
117
- assert.equal(revised.phase, "execution");
118
- assert.equal(revised.status, "ready");
119
- assert.equal(revised.gates["implementation-review"], "not_started");
120
- assert.equal(revised.executionWorkspace?.path, workspacePath);
121
- ```
122
-
123
- Then call `continueOrchestratedWorkflow` with a runner that records its phase
124
- and assert the next executed role has `phase === "execution"` and
125
- `role === "implementer"`, not `review`/`architect`.
126
-
127
- - [ ] **Step 2: Run the focused test and verify RED**
128
-
129
- Run:
130
-
131
- ```bash
132
- node --import tsx --test tests/orchestrator.test.ts
133
- ```
134
-
135
- Expected: the new assertions fail because `devcrew_answer` currently re-runs
136
- the review phase.
137
-
138
- - [ ] **Step 3: Implement the remediation transition**
139
-
140
- Add this branch in `answerOrchestratedWorkflow` immediately after the existing
141
- testing-rejection branch:
142
-
143
- ```ts
144
- if (
145
- before.executionMode === "apply" &&
146
- before.phase === "review" &&
147
- before.gates["implementation-review"] === "rejected" &&
148
- before.architectureReview?.decision === "changes_required"
149
- ) {
150
- state.phase = "execution";
151
- state.status = "ready";
152
- state.gates["implementation-review"] = "not_started";
153
- return saveState(state);
154
- }
155
- ```
156
-
157
- Do not clear `executionWorkspace`, `architectureReview`, feedback, or the
158
- prior review artifact; they remain audit evidence and the next execution phase
159
- will refresh the captured diff and create a new review.
160
-
161
- - [ ] **Step 4: Update the workflow documentation**
162
-
163
- Replace the current claim that feedback must be addressed before another review
164
- with text stating that `devcrew_answer` returns the run to the isolated
165
- `execution/ready` state and a later `devcrew_continue` performs the revised
166
- implementation before a fresh architect review.
167
-
168
- - [ ] **Step 5: Run focused tests and verify GREEN**
169
-
170
- Run:
171
-
172
- ```bash
173
- node --import tsx --test tests/orchestrator.test.ts
174
- ```
175
-
176
- Expected: all orchestrator tests pass and the remediation test observes an
177
- implementer execution before a subsequent review.
178
-
179
- - [ ] **Step 6: Commit the remediation fix**
180
-
181
- ```bash
182
- git add docs/workflow.md packages/orchestrator/src/index.ts tests/orchestrator.test.ts
183
- git commit -m "fix: return architecture findings to execution"
184
- ```
185
-
186
- ### Task 3: Full verification
187
-
188
- **Files:**
189
- - Verify: `packages/core/src/workflow.ts`
190
- - Verify: `packages/orchestrator/src/index.ts`
191
- - Verify: `tests/orchestrator.test.ts`
192
-
193
- - [ ] **Step 1: Run the complete repository validation**
194
-
195
- Run:
196
-
197
- ```bash
198
- npm run validate
199
- ```
200
-
201
- Expected: TypeScript compilation succeeds and every test passes.
202
-
203
- - [ ] **Step 2: Inspect the final diff**
204
-
205
- Run:
206
-
207
- ```bash
208
- git diff main...HEAD --check
209
- git status --short
210
- ```
211
-
212
- Expected: no whitespace errors; only the two implementation commits and this
213
- plan/spec commits are present on the branch.