@shenlee/devcrew 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +15 -7
  2. package/README.zh-CN.md +12 -7
  3. package/dist/packages/adapters/src/index.js +60 -7
  4. package/dist/packages/core/src/artifacts.js +14 -4
  5. package/dist/packages/core/src/config.js +1 -1
  6. package/dist/packages/core/src/paths.js +7 -6
  7. package/dist/packages/core/src/store.js +30 -0
  8. package/dist/packages/core/src/types.js +4 -1
  9. package/dist/packages/core/src/validation.js +7 -1
  10. package/dist/packages/core/src/version.js +1 -1
  11. package/dist/packages/core/src/workflow.js +70 -12
  12. package/dist/packages/orchestrator/src/index.js +230 -15
  13. package/dist/packages/plugins/src/index.js +2 -32
  14. package/dist/packages/service/src/tools.js +43 -4
  15. package/docs/claude-code.md +5 -3
  16. package/docs/codex.md +9 -5
  17. package/docs/quickstart.md +1 -1
  18. package/docs/superpowers/plans/2026-07-13-safety-semantics.md +313 -0
  19. package/docs/superpowers/specs/2026-07-13-execution-boundaries-design.md +126 -0
  20. package/docs/workflow.md +19 -4
  21. package/package.json +1 -1
  22. package/packages/adapters/src/index.ts +84 -9
  23. package/packages/core/src/artifacts.ts +16 -4
  24. package/packages/core/src/config.ts +1 -1
  25. package/packages/core/src/paths.ts +7 -6
  26. package/packages/core/src/store.ts +34 -1
  27. package/packages/core/src/types.ts +46 -2
  28. package/packages/core/src/validation.ts +10 -0
  29. package/packages/core/src/version.ts +1 -1
  30. package/packages/core/src/workflow.ts +82 -11
  31. package/packages/orchestrator/src/index.ts +252 -14
  32. package/packages/plugins/src/index.ts +2 -44
  33. package/packages/service/src/tools.ts +44 -3
  34. package/plugins/devcrew-codex/.codex-plugin/plugin.json +1 -1
  35. package/plugins/devcrew-codex/.mcp.json +1 -1
  36. package/plugins/devcrew-codex/skills/devcrew/SKILL.md +8 -7
  37. package/scripts/smoke-codex-plugin.mjs +1 -1
  38. package/plugins/devcrew-codex/agents/architect.toml +0 -12
  39. package/plugins/devcrew-codex/agents/implementer.toml +0 -12
  40. package/plugins/devcrew-codex/agents/pm.toml +0 -13
  41. package/plugins/devcrew-codex/agents/tester.toml +0 -12
@@ -1,5 +1,5 @@
1
1
  import { getArtifact, getActiveRunId, getWorkflowStatus, setActiveRun, } from "../../core/src/index.js";
2
- import { answerOrchestratedWorkflow, approveOrchestratedWorkflow, continueOrchestratedWorkflow, rejectOrchestratedWorkflow, startOrchestratedWorkflow, } from "../../orchestrator/src/index.js";
2
+ import { answerOrchestratedWorkflow, approveOrchestratedWorkflow, completeOrchestratedExecution, continueOrchestratedWorkflow, rejectOrchestratedWorkflow, startOrchestratedWorkflow, waiveOrchestratedVerification, } from "../../orchestrator/src/index.js";
3
3
  const cwdProperty = { type: "string", description: "Repository working directory." };
4
4
  const runIdProperty = { type: "string", description: "DevCrew run id." };
5
5
  const hostValues = ["codex", "claude"];
@@ -39,6 +39,11 @@ export function listDevCrewTools() {
39
39
  enum: ["plan", "apply"],
40
40
  description: "Execution mode. Defaults to plan; apply must be explicit.",
41
41
  },
42
+ executionPolicy: {
43
+ type: "string",
44
+ enum: ["interactive-host", "headless-restricted", "headless-unattended"],
45
+ description: "Apply execution policy. Defaults to interactive-host; headless policies are explicit DevCrew SDK policies.",
46
+ },
42
47
  request: { type: "string" },
43
48
  backend: { type: "string", enum: ["codex", "claude", "local"] },
44
49
  },
@@ -71,7 +76,7 @@ export function listDevCrewTools() {
71
76
  properties: {
72
77
  cwd: cwdProperty,
73
78
  runId: runIdProperty,
74
- gate: { type: "string", enum: ["requirements", "architecture", "implementation", "testing"] },
79
+ gate: { type: "string", enum: ["requirements", "architecture", "implementation", "implementation-review", "testing"] },
75
80
  note: { type: "string" },
76
81
  },
77
82
  },
@@ -85,7 +90,7 @@ export function listDevCrewTools() {
85
90
  properties: {
86
91
  cwd: cwdProperty,
87
92
  runId: runIdProperty,
88
- gate: { type: "string", enum: ["requirements", "architecture", "implementation", "testing"] },
93
+ gate: { type: "string", enum: ["requirements", "architecture", "implementation", "implementation-review", "testing"] },
89
94
  feedback: { type: "string" },
90
95
  },
91
96
  },
@@ -99,6 +104,32 @@ export function listDevCrewTools() {
99
104
  properties: { cwd: cwdProperty, runId: runIdProperty },
100
105
  },
101
106
  },
107
+ {
108
+ name: "devcrew_complete_execution",
109
+ description: "Record completion by the native host for an interactive-host execution or testing step.",
110
+ inputSchema: {
111
+ type: "object",
112
+ required: ["cwd", "summary"],
113
+ properties: {
114
+ cwd: cwdProperty,
115
+ runId: runIdProperty,
116
+ summary: { type: "string" },
117
+ verification: {
118
+ type: "array",
119
+ description: "Required only when completing testing: command, exitCode, output, startedAt, and completedAt for each validation command.",
120
+ },
121
+ },
122
+ },
123
+ },
124
+ {
125
+ name: "devcrew_waive_verification",
126
+ description: "Record a reasoned risk waiver after failed apply-mode verification, then reopen the testing gate for approval.",
127
+ inputSchema: {
128
+ type: "object",
129
+ required: ["cwd", "reason"],
130
+ properties: { cwd: cwdProperty, runId: runIdProperty, reason: { type: "string" } },
131
+ },
132
+ },
102
133
  {
103
134
  name: "devcrew_artifact",
104
135
  description: "Read a generated workflow artifact.",
@@ -110,7 +141,7 @@ export function listDevCrewTools() {
110
141
  runId: runIdProperty,
111
142
  name: {
112
143
  type: "string",
113
- enum: ["requirements", "architecture", "implementation-plan", "implementation-review", "test-report", "acceptance"],
144
+ enum: ["requirements", "architecture", "implementation-plan", "implementation-review", "architecture-review", "test-report", "acceptance"],
114
145
  },
115
146
  },
116
147
  },
@@ -165,6 +196,14 @@ export async function callDevCrewTool(name, args) {
165
196
  const state = await continueOrchestratedWorkflow((await withActiveRun(args)));
166
197
  return success(`${summarizeState(state)}.`, { state });
167
198
  }
199
+ if (name === "devcrew_complete_execution") {
200
+ const state = await completeOrchestratedExecution((await withActiveRun(args)));
201
+ return success(`${summarizeState(state)}. Native host completion recorded.`, { state });
202
+ }
203
+ if (name === "devcrew_waive_verification") {
204
+ const state = await waiveOrchestratedVerification((await withActiveRun(args)));
205
+ return success(`${summarizeState(state)}. Verification waiver recorded.`, { state });
206
+ }
168
207
  if (name === "devcrew_artifact") {
169
208
  const artifact = await getArtifact((await withActiveRun(args)));
170
209
  return success(artifact.content, { artifact });
@@ -17,18 +17,20 @@ It contains:
17
17
 
18
18
  - `.claude-plugin/plugin.json`
19
19
  - `skills/devcrew/SKILL.md`
20
- - `agents/*.md`
21
20
  - `.mcp.json`
22
21
 
22
+ Role behavior is defined by the DevCrew MCP service and its shared runtime role
23
+ schema. The plugin intentionally does not bundle inactive subagent templates.
24
+
23
25
  For local plugin testing:
24
26
 
25
27
  ```bash
26
28
  claude --plugin-dir plugins/devcrew-claude
27
29
  ```
28
30
 
29
- Then ask Claude Code to use DevCrew for a feature or product workflow. The generated `.mcp.json` starts the version-locked npm package with an `npm exec --package=@shenlee/devcrew@0.1.2` wrapper.
31
+ Then ask Claude Code to use DevCrew for a feature or product workflow. The generated `.mcp.json` starts the version-locked npm package with an `npm exec --package=@shenlee/devcrew@0.1.3` wrapper.
30
32
 
31
- Claude Code permissions, hooks, and approval settings remain authoritative. DevCrew inherits the host boundary.
33
+ The default apply policy is `interactive-host`: Claude Code performs implementation and testing with its native controls. Explicit `headless-restricted` and `headless-unattended` policies are independent DevCrew SDK policies and do not inherit the current Claude Code approval session.
32
34
 
33
35
  For apply mode, `@anthropic-ai/claude-agent-sdk` must be resolvable from the installed DevCrew package. Published DevCrew packages declare it as an optional dependency, which npm installs by default. If `devcrew doctor` reports it as missing, reinstall DevCrew with optional dependencies enabled:
34
36
 
package/docs/codex.md CHANGED
@@ -13,7 +13,7 @@ Restart Codex, open the plugin directory, select the DevCrew marketplace, and in
13
13
  The plugin launches the MCP server with:
14
14
 
15
15
  ```bash
16
- npm exec --silent --yes --package=@shenlee/devcrew@0.1.2 -- node -e "<DevCrew CLI wrapper>" -- serve --stdio
16
+ npm exec --silent --yes --package=@shenlee/devcrew@0.1.3 -- node -e "<DevCrew CLI wrapper>" -- serve --stdio
17
17
  ```
18
18
 
19
19
  Use this path when you want to use DevCrew without cloning the repository first. The version is locked to the published npm package that matches the plugin manifest.
@@ -38,7 +38,9 @@ It contains:
38
38
  - `.codex-plugin/plugin.json`
39
39
  - `skills/devcrew/SKILL.md`
40
40
  - `.mcp.json`
41
- - role agent TOML templates under `agents/`
41
+
42
+ Role behavior is defined by the DevCrew MCP service and its shared runtime role
43
+ schema. The plugin intentionally does not bundle inactive subagent templates.
42
44
 
43
45
  For local development, point a Codex marketplace entry at the generated plugin folder, or copy the plugin into your existing local marketplace workflow.
44
46
 
@@ -50,11 +52,13 @@ The DevCrew skill tells Codex to use these MCP tools:
50
52
  - `devcrew_approve`
51
53
  - `devcrew_reject`
52
54
  - `devcrew_continue`
55
+ - `devcrew_complete_execution`
56
+ - `devcrew_waive_verification`
53
57
  - `devcrew_artifact`
54
58
 
55
- Codex sandbox and approval settings remain authoritative. DevCrew does not bypass them.
59
+ The default apply policy is `interactive-host`: Codex performs the implementation and testing with its native controls. A DevCrew nested SDK is not used in this path. Explicit `headless-restricted` and `headless-unattended` policies are separate DevCrew policies and do not inherit the current Codex approval session.
56
60
 
57
- Apply mode keeps implementation planning read-only. After the implementation gate is approved, call `devcrew_continue` once to run the implementer in `.devcrew/worktrees/<run-id>`, then call it again to run the tester and verification commands in that worktree. Testing approval promotes the exact reviewed patch to the requester repository. Rejecting testing and answering the feedback returns the isolated run to execution without touching the requester repository.
61
+ Apply mode keeps implementation planning read-only. With `interactive-host`, after the implementation gate is approved, call `devcrew_continue`; DevCrew creates `.devcrew/worktrees/<run-id>` and waits at `awaiting_execution`. Use Codex natively in that worktree, then call `devcrew_complete_execution`. Repeat for testing and include command, exit-code, and output evidence. A failed verification cannot open the testing gate; revise it or record an explicit reason through `devcrew_waive_verification`. Testing approval promotes the exact reviewed patch to the requester repository.
58
62
 
59
63
  Apply mode requires a Git repository, a clean requester worktree at execution and promotion, and a real Codex SDK backend.
60
64
 
@@ -66,7 +70,7 @@ npm install -g @shenlee/devcrew --include=optional
66
70
 
67
71
  ## Marketplace smoke test
68
72
 
69
- After publishing `@shenlee/devcrew@0.1.2`, run the real marketplace smoke test. Do not treat this as a pre-publication check because the plugin is locked to that npm version:
73
+ After publishing `@shenlee/devcrew@0.1.3`, run the real marketplace smoke test. Do not treat this as a pre-publication check because the plugin is locked to that npm version:
70
74
 
71
75
  ```bash
72
76
  npm run smoke:codex-plugin
@@ -37,7 +37,7 @@ devcrew serve --stdio
37
37
  ```
38
38
 
39
39
  Normally the generated plugin starts this command for the host agent.
40
- Codex and Claude plugin bundles use a version-locked `npm exec --package=@shenlee/devcrew@0.1.2` wrapper so the MCP service is locked to the published package version.
40
+ Codex and Claude plugin bundles use a version-locked `npm exec --package=@shenlee/devcrew@0.1.3` wrapper so the MCP service is locked to the published package version.
41
41
 
42
42
  ## 4. Run A Workflow
43
43
 
@@ -0,0 +1,313 @@
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
+ ```
@@ -0,0 +1,126 @@
1
+ # DevCrew Execution Boundaries Design
2
+
3
+ ## Goal
4
+
5
+ Make DevCrew's approval, verification, and role boundaries match its public
6
+ product claims. Interactive work must execute through the host agent's native
7
+ permission model. Headless work may use host SDKs only under an explicit,
8
+ auditable DevCrew execution policy.
9
+
10
+ ## Scope
11
+
12
+ This change is delivered in three independently releasable slices:
13
+
14
+ 1. Safety semantics: explicit execution policy and verification-failure
15
+ promotion blocking.
16
+ 2. Workflow semantics: execution-time architecture compliance review and
17
+ structured role questions/results.
18
+ 3. Productisation: effective artifact configuration and real-host integration
19
+ coverage.
20
+
21
+ The existing isolated Git worktree and binary patch promotion remain the sole
22
+ mechanism for moving apply-mode changes into the requester repository.
23
+
24
+ ## Execution Planes
25
+
26
+ ### Interactive host plane
27
+
28
+ Interactive Codex and Claude Code workflows do not invoke the Codex or Claude
29
+ SDK to modify repository files. DevCrew MCP owns durable workflow state,
30
+ artifacts, gate validation, execution worktree creation, patch capture, and
31
+ promotion. It exposes a structured execution instruction containing the role,
32
+ worktree path, approved context, and required result schema. The active host
33
+ agent or a native host subagent performs the work with the host's ordinary
34
+ sandbox and approval UI, then submits the result to DevCrew.
35
+
36
+ This plane must never claim that a nested SDK session inherits the interactive
37
+ host's current approval decisions.
38
+
39
+ ### Headless SDK plane
40
+
41
+ Headless and CI workflows retain SDK orchestration, but `apply` requires an
42
+ explicit `executionPolicy`. The initial policy set is:
43
+
44
+ - `interactive-host`: no nested SDK execution; valid only for an interactive
45
+ host integration.
46
+ - `headless-restricted`: SDK execution in the DevCrew worktree with a declared
47
+ minimal tool surface and no hidden user-prompt assumption.
48
+ - `headless-unattended`: an explicitly opted-in unattended SDK policy for CI;
49
+ its audit record makes the autonomy clear.
50
+
51
+ The policy, backend, allowed capabilities, and any waiver are recorded in run
52
+ state and shown in review artifacts. `acceptEdits`, bare `allowedTools`, and an
53
+ implicit Codex approval policy are not described as inherited host approvals.
54
+
55
+ ## Verification And Promotion
56
+
57
+ After isolated testing, DevCrew computes a verification status:
58
+
59
+ - `passed`: every configured or discovered verification command exited zero.
60
+ - `failed`: at least one command exited nonzero or timed out.
61
+ - `not_run`: no verification command was available.
62
+
63
+ Only `passed` can open the normal `testing` approval gate. A failed result
64
+ moves the run to `awaiting_input` with the failure evidence and preserves the
65
+ worktree. A requester may either supply feedback that returns the run to
66
+ `execution`, or invoke a dedicated risk-waiver operation with a non-empty
67
+ reason. The waiver is persistent, appears in the test report and acceptance
68
+ artifact, and is the only path that can open a testing approval gate after a
69
+ failed verification.
70
+
71
+ `not_run` remains reviewable but is visibly distinct from `passed`; it cannot
72
+ be silently represented as successful verification.
73
+
74
+ ## Execution-Time Architecture Review
75
+
76
+ The current implementation-plan gate approves a plan and cannot approve the
77
+ subsequent code diff. Add an `implementation-review` gate after execution and
78
+ before testing. The architect role receives the approved architecture artifact,
79
+ captured binary diff, changed-file list, lint evidence, and structured
80
+ implementation result. It returns a structured compliance decision.
81
+
82
+ Only an approved implementation review advances to testing. Rejection records
83
+ feedback and returns to execution with the existing isolated worktree intact.
84
+ The existing `implementation-review.md` remains an artifact, but becomes the
85
+ architect's real review output rather than a rendered checklist.
86
+
87
+ ## Structured Role Results And Clarification
88
+
89
+ Each role result is a validated JSON envelope with a Markdown body plus
90
+ role-specific fields. At minimum, PM returns `questions`, architect returns a
91
+ compliance decision, implementer returns changed-file and command evidence, and
92
+ tester returns case/evidence summaries. Markdown remains the human-facing
93
+ artifact format.
94
+
95
+ If PM returns one or more questions, requirements enter `awaiting_input`
96
+ without opening an approval gate. `devcrew_answer` records the answer and
97
+ re-runs PM. A requirements gate opens only when the PM result has no open
98
+ questions.
99
+
100
+ ## Configuration
101
+
102
+ `workflow.artifactDirectory` is used by all artifact path helpers, relative to
103
+ the repository root and validated to remain within that root. Core safety gates
104
+ are not freely removable. `workflow.gates` is replaced or constrained by a
105
+ validated sequence that must include requirements, architecture,
106
+ implementation, implementation-review, and testing for apply workflows.
107
+
108
+ ## Integration Coverage
109
+
110
+ Add tests for failed verification, risk waiver, no-verification status,
111
+ architecture-review rejection/revision, structured PM questions, and configured
112
+ artifact output. Preserve existing worktree-promotion coverage.
113
+
114
+ The production-like Codex marketplace smoke remains plan-mode and must verify
115
+ the published package version. Add isolated integration coverage for the
116
+ interactive execution handoff protocol and a real Claude plugin install/start
117
+ smoke. A real unattended apply smoke uses only a disposable fixture repository
118
+ and an explicitly selected headless policy.
119
+
120
+ ## Non-goals
121
+
122
+ - Do not remove worktree isolation or binary patch promotion.
123
+ - Do not automatically approve failed verification.
124
+ - Do not make arbitrary workflow graph customisation part of this release.
125
+ - Do not use generated role files as an execution mechanism until a host-native
126
+ integration consumes them explicitly.