dev-flow-codex 0.3.0 → 0.5.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.
@@ -5,8 +5,10 @@ description: "Explicit-only Dev Flow entry point for Codex. Use only when the cu
5
5
 
6
6
  # Dev Flow
7
7
 
8
- This Skill is a thin admission layer for the shared Dev Flow Core. It does not own task state,
9
- workflow transitions, recovery decisions, verification budgets, or completion.
8
+ This Skill is the Contract 0.2 Codex adapter for the shared Dev Flow Core. Core owns task state,
9
+ current node, legal transitions, destinations, recovery, blockers, and terminal outcomes. The Skill
10
+ admits one explicit request, presents a complete Core Action, renders method work, and forwards one
11
+ closed result without keeping adapter state.
10
12
 
11
13
  ## Admission gate
12
14
 
@@ -15,39 +17,41 @@ Perform every check below locally and in order before any Core or Dev Flow tool
15
17
  The Skill resource/base name is `dev-flow`; the installed Skill full name is `dev-flow-codex:dev-flow`.
16
18
  The only exact explicit selector is `$dev-flow-codex:dev-flow`.
17
19
  Bare `$dev-flow` is not an alias and does not select this installed Skill. A wrong plugin namespace,
18
- a wrong Skill base name, or a missing selector also does not select it.
19
- Codex 0.147 may expose this plugin's MCP tools independently from Skill injection. This Skill does
20
- not claim selector-bound tool visibility or authorization.
21
-
22
- 1. Require the exact standalone `$dev-flow-codex:dev-flow` selector in the current user turn. Do not infer the
23
- selector from earlier turns, repository contents, or a request that merely discusses Dev Flow.
24
- If it is absent, do not treat the turn as Skill activation and do not make a task-bearing Dev Flow
25
- call. Never activate this Skill implicitly.
26
- 2. After removing the selector, accept either one substantive, bounded requirement for the current
20
+ a wrong Skill base name, or a missing selector also does not select it. Codex may expose this
21
+ plugin's MCP tools independently from Skill injection; this Skill does not claim selector-bound tool
22
+ visibility or authorization.
23
+
24
+ 1. Require the exact standalone `$dev-flow-codex:dev-flow` selector in the current user turn. Do not
25
+ infer it from earlier turns, repository contents, or discussion about Dev Flow. Without it, do not
26
+ activate this Skill or make a task-bearing Dev Flow call. Never activate implicitly.
27
+ 2. After removing the selector, accept either one substantive bounded request for the current
27
28
  repository or an explicit request to resume its compatible active Codex task. Reject an empty or
28
29
  conversational invocation before any Core call.
29
30
  3. Use read-only Git inspection to resolve one current Git worktree and its canonical root. Preserve
30
31
  spaces, Unicode, symlinks, and subdirectory invocation as one path value; do not concatenate a
31
32
  shell command.
32
- 4. Reject work that needs another repository, multiple repositories, or a repository that cannot be
33
- resolved. Preserve repository instructions and current user authority when checking whether the
34
- requested work is permitted.
33
+ 4. Reject work requiring another repository, multiple repositories, or an unresolved repository.
34
+ Preserve repository instructions and current user authority when checking whether the work is
35
+ permitted.
35
36
 
36
- If any admission check fails, explain the missing precondition and stop before Skill-owned task
37
- discovery. Do not complete a task-bearing call or create adapter state. Host-exposed read-only or
38
- Core-rejected calls are not activation and must be reported honestly.
37
+ If admission fails, explain the missing precondition and stop before Skill-owned task discovery. Do
38
+ not complete a task-bearing call or create adapter state. Host-exposed read-only or Core-rejected
39
+ calls are not activation and must be reported honestly.
39
40
 
40
41
  ## Compatibility handshake
41
42
 
42
- Only after every admission check passes, call `dev_flow_server_info({})`. It must be the first Dev
43
- Flow tool call. Require the complete structured result to establish all of the following:
43
+ Only after admission passes, call `dev_flow_server_info({})`; it must be the first Dev Flow tool
44
+ call. Require one complete structured result proving:
44
45
 
45
- - product is exactly `dev-flow`;
46
- - Core version equals the packaged product version;
47
- - schema identifies Core Contract `0.1`;
48
- - transport is exactly `stdio` and health is exactly `ready`;
49
- - the supported host set contains `codex`;
50
- - the reported tool catalog contains exactly these six raw names, in this order:
46
+ - product is exactly `dev-flow`, and Core version equals the packaged product version;
47
+ - `schema_version` is exactly `2` and `core_limits_version` is exactly `0.2`;
48
+ - transport is exactly `stdio`, health is exactly `ready`, and the supported host set contains
49
+ `codex`;
50
+ - `supported_processes` contains exactly one closed `standard-development@1` entry:
51
+ `process_id` is `standard-development`, `process_version` is `1`, `definition_digest` is present
52
+ and canonical, and `new_task_supported` is exactly `true`;
53
+ - `method_profiles` is exactly `plain`, `spec-kit`, `openspec` in that order;
54
+ - the tool catalog contains exactly these six raw names, in this order:
51
55
 
52
56
  1. `dev_flow_server_info`
53
57
  2. `dev_flow_open_task`
@@ -56,110 +60,198 @@ Flow tool call. Require the complete structured result to establish all of the f
56
60
  5. `dev_flow_apply_action`
57
61
  6. `dev_flow_cancel_task`
58
62
 
59
- An incomplete, truncated, malformed, incompatible, missing, additional, or reordered catalog is a
60
- failed handshake. Stop without probing an undocumented tool or continuing to task discovery.
63
+ Any other schema, unsupported process version, absent process digest, false new-task support,
64
+ incomplete method-profile set, missing/additional/reordered tool, or incomplete, truncated, malformed,
65
+ or incompatible result fails the handshake. Stop without task discovery or undocumented probing. Do
66
+ not inspect local source or an installed binary, and do not start a second MCP server to bypass a
67
+ failed handshake.
61
68
 
62
69
  ## Task discovery
63
70
 
64
- After the handshake, call `dev_flow_open_task` with `host=codex` and the canonical current
65
- worktree.
66
-
67
- - For an explicit resume request, omit `new_task` and let Core select the unique compatible active
68
- Codex task.
69
- - For a new substantive request, provide a bounded contract derived only from the current user
70
- request, repository instructions, stated exclusions, observable acceptance criteria, and the
71
- granted verification authority.
72
- - Forward `new_task` with exactly the members `goal`, `scope`, `out_of_scope`,
73
- `acceptance_criteria`, and `verification_budget`, with no additional members. Forward
74
- `verification_budget` with exactly `level`, `max_automatic_commands`, `allow_full_suite`, and
75
- `allow_manual_handoff`; do not invent aliases for any of these Core-declared fields.
76
- - `goal` is a JSON string. `scope`, `out_of_scope`, and `acceptance_criteria` are JSON arrays of strings;
77
- never collapse an array into one prose string. `verification_budget.level` is exactly `minimal`,
78
- `targeted`, or `full`; do not translate phrases such as "focused verification" into a new enum.
79
- - Use this exact `new_task` JSON shape, replacing only the values derived from the admitted request:
71
+ After the handshake, call `dev_flow_open_task` with `host=codex` and the canonical current worktree.
72
+
73
+ - For an explicit resume, omit `new_task` or send `new_task=null`. Do not resend a guessed intent or
74
+ select another profile; accept the immutable profile returned by Core.
75
+ - For a new request, select one profile from explicit current user intent. An explicit `plain`,
76
+ `spec-kit`, or `openspec` request selects that exact profile. An explicit request to use Spec Kit
77
+ selects `spec-kit`; an explicit request to use OpenSpec selects `openspec`; otherwise use the
78
+ conservative `plain` profile.
79
+ - Installed tooling does not select or switch a profile. Never change the profile after creation. If
80
+ the user explicitly requests conflicting profiles, report the profile conflict and stop.
81
+ - Derive the new-task contract only from the admitted user request, repository instructions, known
82
+ initial bounds, known acceptance, and granted verification authority. Formal acceptance does not
83
+ need to be complete at creation; the current requirements work forms that authority.
84
+ - Forward `new_task` with exactly the members `request`, `initial_scope`,
85
+ `initial_out_of_scope`, `known_acceptance_criteria`, `verification_budget`, and `method_profile`,
86
+ with no additional members. Forward `verification_budget` with exactly `level`,
87
+ `max_automatic_commands`, `allow_full_suite`, and `allow_manual_handoff`.
88
+ - `request` is a JSON string. `initial_scope`, `initial_out_of_scope`, and
89
+ `known_acceptance_criteria` are JSON arrays of strings and may be empty. Never collapse an array
90
+ into prose. `verification_budget.level` is exactly `minimal`, `targeted`, or `full`.
91
+
92
+ Use this exact `new_task` JSON shape, changing only values derived from the admitted request:
80
93
 
81
94
  <!-- new-task-example:start -->
82
95
  ```json
83
96
  {
84
- "goal": "Return the requested field from the bounded endpoint.",
85
- "scope": ["Update the endpoint response"],
86
- "out_of_scope": ["Change unrelated endpoints"],
87
- "acceptance_criteria": ["The response contains the requested field"],
97
+ "request": "Return the requested field from the bounded endpoint.",
98
+ "initial_scope": ["Update the endpoint response"],
99
+ "initial_out_of_scope": ["Change unrelated endpoints"],
100
+ "known_acceptance_criteria": ["The response contains the requested field"],
88
101
  "verification_budget": {
89
102
  "level": "targeted",
90
103
  "max_automatic_commands": 4,
91
104
  "allow_full_suite": false,
92
105
  "allow_manual_handoff": true
93
- }
106
+ },
107
+ "method_profile": "plain"
94
108
  }
95
109
  ```
96
110
  <!-- new-task-example:end -->
97
111
 
98
- - Ask before opening a new task if a material goal, scope, acceptance, or verification choice
99
- cannot be derived without changing user intent.
100
- - Let Core decide whether an exactly compatible contract creates or resumes a task. Never choose,
101
- merge, or take over task records locally.
102
-
103
- The complete open result is authoritative. Report a Core ownership or contract conflict unchanged
104
- in meaning and stop.
112
+ Ask before opening only when a material request, initial-bound, verification, or profile choice
113
+ cannot be derived without changing user intent. Let Core decide whether a compatible intent creates
114
+ or resumes a task. Report an ownership or contract conflict unchanged in meaning and stop.
105
115
 
106
116
  ## Governed action loop
107
117
 
118
+ The inseparable Action fields are exactly `task_id`, `revision`, `action_id`, `action_kind`,
119
+ `process_id`, `process_version`, `process_definition_digest`, `current_node`, `node_purpose`,
120
+ `entry_conditions`, `completion_conditions`, `allowed_effects`, `required_evidence`,
121
+ `method_profile`, `method_steps`, `available_transitions`, `payload_contract`, `guidance`,
122
+ `repository_binding_digest`, and `issued_at`.
123
+
108
124
  For an active task, perform each iteration in this order:
109
125
 
110
- 1. Obtain one complete, fresh action from the open result or `dev_flow_get_next_action`.
111
- 2. Treat the returned task ID, revision, action ID, action kind, repository-binding digest, allowed
112
- effects, required evidence, payload schema, guidance, blocker, and outcome as one inseparable
113
- Core result.
114
- 3. Stop when that result reports a blocker or terminal outcome.
115
- 4. Perform only the current action's allowed effects, under the repository instructions and
116
- current user authority.
117
- 5. Count verification commands and label evidence by how it actually ran.
118
- 6. Build only the closed payload requested by the returned payload schema.
119
- 7. Before dispatch, generate and retain an opaque request ID with the exact identity and payload.
120
- 8. Submit exactly one mutation through `dev_flow_apply_action` using that retained material.
121
- 9. After a complete successful mutation, continue only from the returned authoritative next action
122
- or outcome, or make one fresh Core read before doing more work.
123
-
124
- Do not infer a transition, reinterpret an error, or decide completion from repository contents or
125
- host judgment.
126
+ 1. Obtain one complete fresh Action from the open result or `dev_flow_get_next_action`, and bind it as
127
+ `fresh_action` from `result.task.current_action` or `result.action` respectively.
128
+ 2. Treat its task ID, revision, action ID, action kind, process ID, process version,
129
+ process-definition digest, current node, node purpose, entry conditions, completion conditions,
130
+ allowed effects, required evidence, method profile, method steps, available transitions, payload
131
+ schema/contract, guidance, repository-binding digest, and issued time as one inseparable Core
132
+ result. Stop if any field is absent, malformed, or truncated.
133
+ 3. Present the current node, purpose, entry and completion conditions, allowed effects, required
134
+ evidence, immutable method profile, every method step, and all `available_transitions`. For every
135
+ returned transition show its identifier, Core-returned destination for visibility, description or
136
+ `when` selection condition, guard identifier, and reason rule. Do not reduce this to one
137
+ recommended next step.
138
+ 4. Stop when the complete result reports a blocker or terminal outcome.
139
+ 5. Render and perform each current method operation under the allowed effects, repository
140
+ instructions, verification budget, and current user authority.
141
+ 6. Build only the closed payload branch named by the Action and select only a Core-returned
142
+ transition consistent with the actual typed node facts.
143
+ 7. Before dispatch, generate and retain one opaque request ID plus the exact Action identity and
144
+ payload. Submit exactly one `dev_flow_apply_action` mutation.
145
+ 8. After a complete committed result, continue only from its authoritative next Action/outcome or a
146
+ fresh ordinary Core read.
147
+
148
+ Repository contents, adapter judgment, artifacts, or method-tool status never determine the current
149
+ node or completion.
150
+
151
+ ## Method operation rendering
152
+
153
+ Read [the method profile rendering reference](references/method-profiles.md) from the packaged path
154
+ `references/method-profiles.md` after receiving the complete Action. For each Core-returned method
155
+ step, preserve its `step_id`, purpose, required flag, and order, then render the operation for the
156
+ immutable profile:
157
+
158
+ - `plain` renders the catalog's plain-equivalent bounded work with no external capability.
159
+ - `spec-kit` and `openspec` render only an actually visible and appropriate capability ID. A catalog
160
+ entry is not proof of availability.
161
+ - If a capability is unavailable or unknown, report that state and show the exact plain-equivalent
162
+ work. Never automatically install a tool or silently substitute another tool.
163
+ - A tool invocation is not semantic completion. Record evidence only after the work and expected
164
+ result actually complete.
165
+
166
+ Build exactly one `MethodEvidence` item for every current Action step, in the same order:
167
+
168
+ - actual capability completion uses `status=completed` and the actual capability ID;
169
+ - completed ordinary work uses `status=plain_fallback` and an empty capability;
170
+ - incomplete work uses `status=unavailable` or `status=not_run` honestly.
171
+
172
+ An unavailable or not-run required step is unsatisfied, so do not call `dev_flow_apply_action`.
173
+ Capability output cannot substitute for the typed `node_result`, node obligations, evidence, or
174
+ user decision. Artifact references contain only an observed role, repository-relative path, digest,
175
+ and summary.
176
+
177
+ Existing authorized spec, plan, or tasks artifacts should be reviewed, revised, or amended as
178
+ needed, not regenerated or rerun mechanically because a semantic step appears. Resolve the active
179
+ Feature from explicit repository context, never only from the branch name. Checklist state,
180
+ analysis output, implementation completion, proposal state, verification state, sync, or archive
181
+ state does not advance Core.
182
+
183
+ ## Transition selection
184
+
185
+ Select only from `fresh_action.available_transitions`. Match the actual current typed `node_result`,
186
+ the Core-returned description or selection condition, current `problem_class`, any explicit user
187
+ decision, and the returned reason rule. Submit the matching transition identifier; Core validates
188
+ the facts and owns/derives the destination.
189
+
190
+ Never infer an edge from a fixed stage sequence, artifact checkbox, AI belief, profile, method-tool
191
+ result, or capability status. A checkbox or method tool cannot advance, select, or complete Core.
192
+ Never submit a transition absent from the fresh Action and never maintain a copied transition list.
126
193
 
127
194
  ## Closed forwarding contract
128
195
 
129
- For every mutation, forward `host=codex`; the task ID and revision from the same fresh result; the
130
- exact action ID, action kind, and repository-binding digest; one caller-generated request ID; and a
131
- closed payload containing only fields allowed by Core's returned schema. Do not add unknown fields,
132
- aliases, command logs, environment dumps, inferred status, or locally invented recovery flags.
133
-
134
- Use the fresh action's `payload_contract` as the discriminator for the corresponding closed schema
135
- branch in the `dev_flow_apply_action` input. `required_evidence` names describe obligations; they are
136
- not payload field names. If you cannot identify and read that exact schema branch, stop before
137
- calling `dev_flow_apply_action` instead of guessing or deriving keys from evidence names.
138
-
139
- Before calling, read the `dev_flow_apply_action` tool's supplied `inputSchema`: under `allOf`, choose
140
- the `oneOf` branch whose `action_kind.const` equals the fresh action kind, resolve the payload `$ref`
141
- through the same schema's `$defs`, and send exactly its `required` members. Do not search the
142
- repository or installed package, inspect a binary or log, or start another MCP server to recover the
143
- schema.
144
-
145
- At the top-level, forward `request_id`, `host`, `task_id`, `revision`, `action_id`, `action_kind`,
146
- and `repository_binding_digest`. The `payload` object contains only phase schema fields; never nest
147
- the enclosing request inside `payload`.
148
-
149
- Bind a source-neutral `fresh_action` from `result.task.current_action` when Core returns a task, or
150
- from `result.action` when `dev_flow_get_next_action` returns the action directly. Map that same
151
- fresh action into the tool input exactly:
196
+ Use the same `fresh_action` already bound from `result.task.current_action` or `result.action`; do
197
+ not construct another Action view.
198
+
199
+ Read [the node payload construction reference](references/node-payloads.md) from the packaged path
200
+ `references/node-payloads.md` before every ordinary apply. The reference is construction guidance;
201
+ the fresh Action, live `dev_flow_apply_action` `inputSchema`, and Core remain authoritative.
202
+
203
+ Before calling `dev_flow_apply_action`, perform this order exactly:
204
+
205
+ `fresh_action.payload_contract` identifies the payload branch that must agree with the live schema
206
+ and packaged template.
207
+
208
+ 1. Rebind the complete `fresh_action` and read its `action_kind`, `current_node`, `payload_contract`,
209
+ `method_steps`, and all `available_transitions`.
210
+ 2. Read the live `dev_flow_apply_action` `inputSchema`; under `allOf`, choose the `oneOf` payload
211
+ branch whose `action_kind.const` matches the current action kind and source node.
212
+ 3. Open the corresponding marked template in `references/node-payloads.md`.
213
+ 4. Preserve the template's complete common envelope and `node_result` wrapper; replace only dynamic
214
+ values with facts from the current Task, Action, user decision, repository work, and actual check.
215
+ 5. Use current baseline revisions, work-item IDs, record IDs, acceptance, and evidence sets; never
216
+ guess or reuse stale values.
217
+ 6. Confirm all six common payload members exist and no seventh member exists.
218
+ 7. Confirm every branch-specific required `node_result` key exists and arrays remain arrays.
219
+ 8. Confirm every ArtifactReference role belongs to the live closed enum. Never convert a
220
+ `required_evidence` kind such as `repository_observation` into an artifact role. Use
221
+ `"artifacts": []` when no real repository-relative process artifact exists.
222
+ 9. Confirm MethodEvidence exactly matches current Action steps in ID, order, and count. Completed
223
+ `plain` work uses `plain_fallback` with an empty capability.
224
+ 10. Confirm the selected transition is present in the fresh Action and its reason rule matches.
225
+ 11. Confirm `destination`, `next_node`, `next_cursor`, caller classification, repository facts,
226
+ payload digest, raw output, and unknown members are absent.
227
+ 12. Map the mutation top-level identity from that same fresh Action.
228
+ 13. Retain the exact request and call `dev_flow_apply_action` once.
229
+
230
+ If the live schema and packaged reference disagree, stop before mutation and report the packaging
231
+ contract defect. Do not choose whichever shape appears more convenient.
232
+
233
+ Do not derive payload keys from `required_evidence`. Do not search the repository or installed
234
+ package, inspect a binary or log, or start another MCP server to recover a schema. The selected
235
+ payload contains exactly `transition_id`, `summary`, `reason`, `artifacts`, `method_evidence`, and
236
+ `node_result`; put `problem_class` exactly where that node branch's actual schema requires it. Keep
237
+ arrays as arrays and the payload as an object. Do not add unknown fields, caller classification,
238
+ caller digest, authoritative repository facts, command/output/configuration data, `destination`,
239
+ `next_node`, or `next_cursor`, and do not wrap the whole request in an outer `payload`.
240
+
241
+ Map every mutation top-level field from the same fresh Action:
152
242
 
153
243
  - caller-generated opaque identity -> top-level `request_id`;
154
244
  - exact value `codex` -> top-level `host`;
155
245
  - `fresh_action.task_id` -> top-level `task_id`;
156
246
  - `fresh_action.revision` -> top-level `revision`;
157
247
  - `fresh_action.action_id` -> top-level `action_id`;
158
- - `fresh_action.kind` -> top-level `action_kind`;
248
+ - `fresh_action.action_kind` -> top-level `action_kind`;
249
+ - `fresh_action.process_id` -> top-level `process_id`;
250
+ - `fresh_action.process_version` -> top-level `process_version`;
251
+ - `fresh_action.process_definition_digest` -> top-level `process_definition_digest`;
252
+ - `fresh_action.current_node` -> top-level `source_cursor`;
159
253
  - `fresh_action.repository_binding_digest` -> top-level `repository_binding_digest`;
160
- - the payload object built from the selected schema branch -> top-level `payload`.
161
-
162
- Use this type-preserving structure for the `dev_flow_apply_action` arguments:
254
+ - the selected closed payload -> top-level `payload`.
163
255
 
164
256
  ```text
165
257
  apply_arguments = {
@@ -168,38 +260,73 @@ apply_arguments = {
168
260
  "task_id": fresh_action.task_id,
169
261
  "revision": fresh_action.revision,
170
262
  "action_id": fresh_action.action_id,
171
- "action_kind": fresh_action.kind,
263
+ "action_kind": fresh_action.action_kind,
264
+ "process_id": fresh_action.process_id,
265
+ "process_version": fresh_action.process_version,
266
+ "process_definition_digest": fresh_action.process_definition_digest,
267
+ "source_cursor": fresh_action.current_node,
172
268
  "repository_binding_digest": fresh_action.repository_binding_digest,
173
269
  "payload": payload_for_selected_schema_branch
174
270
  }
175
271
  ```
176
272
 
177
- `revision` remains an integer, not a string. `payload` remains an object, not a string, containing
178
- exactly the selected branch's required members.
273
+ `revision` remains an integer, not a string. `payload` remains an object, not a string. Do not wrap
274
+ that request inside an outer `payload` object. For an ordinary mutation, omit `recovery_apply` or
275
+ send `recovery_apply=null`.
179
276
 
180
- Do not wrap that request inside an outer `payload` object.
277
+ If Core returns `INVALID_ARGUMENT`, treat it as a complete payload-contract rejection. Stop the
278
+ current mutation, report the failing action/payload contract without private data, and do not delete
279
+ fields, submit a second candidate payload for the same Action, automatically retry, or treat the
280
+ result as transport uncertainty.
181
281
 
182
- Use `recovery_apply` only when a fresh Core recovery assessment explicitly requires the exact
183
- Core-defined form. Resolve context ambiguity through an ordinary Core read, never by guessing.
282
+ ## Comprehension user interaction
283
+
284
+ At `COMPREHENSION_REVIEW`, present a bounded explanation of current requirements, design, and major
285
+ code paths; list unnecessary abstractions and maintenance risks; explicitly ask whether the
286
+ developer can explain and maintain the result; and wait for an explicit user answer or verdict.
287
+
288
+ Use that answer and only the fresh Core transitions to form a candidate transition and matching
289
+ typed facts. `comprehension_passed` requires explicit current user confirmation. AI must not answer,
290
+ self-confirm, or infer that the user understands. Neither Spec Kit nor OpenSpec can own or replace
291
+ the verdict.
292
+
293
+ ## SCHEMA_UNSUPPORTED
294
+
295
+ When Core returns `SCHEMA_UNSUPPORTED`, explain that the selected data directory contains pre-graph
296
+ or otherwise incompatible data and that Core did not modify or delete the old data. The user must
297
+ act explicitly outside Core by choosing a fresh `DEV_FLOW_DATA_DIR`, manually archiving the old
298
+ directory, manually renaming it, or manually deleting it.
299
+
300
+ Stop current task discovery and do not continue open/create, automatically retry, reset, convert,
301
+ migrate, install a migration tool, or create a substitute task. Never run delete, move, truncate, or
302
+ reset operations for the user. Do not search for a local data directory or database path, and do not
303
+ display, reveal, or expose a private path or location. Report only the stable error code and bounded
304
+ guidance: never include a `HOME` value, username, result-envelope data path, raw SQLite error, or raw
305
+ Git error. After the user completes an explicit external choice, they may invoke the exact Skill
306
+ selector again; no background handling is promised.
184
307
 
185
308
  ## Recovery-before-retry contract
186
309
 
187
- A mutation result is uncertain when it is missing, malformed, cancelled, truncated, or
188
- transport-failed instead of returning one complete structured result. All five shapes use the same
189
- read-before-retry procedure.
310
+ A mutation result is uncertain when it is missing, cancelled, malformed, truncated, or
311
+ transport-failed instead of returning one complete structured result. Do not immediately repeat
312
+ `dev_flow_apply_action` and do not infer the result from repository state or worktree contents.
190
313
 
191
- Before calling `dev_flow_apply_action`, retain the original `request_id`, `task_id`, `source_phase`,
192
- `revision`, `action_id`, `action_kind`, `repository_binding_digest`, and exact closed `payload` from
193
- the same fresh action and the same apply dispatch. Never derive or reconstruct any of them from an
194
- incomplete response or partial output.
314
+ Before calling `dev_flow_apply_action`, retain the original `request_id`, `task_id`, `process_id`,
315
+ `process_version`, `process_definition_digest`, `source_cursor`, `revision`, `action_id`,
316
+ `action_kind`, `repository_binding_digest`, and exact closed `payload` from the same fresh action and
317
+ the same apply dispatch. Never derive or reconstruct them from an incomplete response or partial
318
+ output.
195
319
 
196
- When all required non-payload original identity values are retained, construct the operation probe
197
- as exactly this closed `operation_probe`:
320
+ When all required original identity values are retained, construct exactly this closed
321
+ `operation_probe`:
198
322
 
199
323
  ```json
200
324
  {
201
325
  "operation_id": "<original apply request_id>",
202
- "source_phase": "<original source phase>",
326
+ "process_id": "standard-development",
327
+ "process_version": 1,
328
+ "process_definition_digest": "<original process definition digest>",
329
+ "source_cursor": "<original source cursor>",
203
330
  "expected_revision": 3,
204
331
  "action_id": "<original action id>",
205
332
  "action_kind": "<original action kind>",
@@ -208,58 +335,74 @@ as exactly this closed `operation_probe`:
208
335
  }
209
336
  ```
210
337
 
211
- `operation_id` is the original apply `request_id`, never the current read request ID.
338
+ `operation_id` is the original apply `request_id`, never a read request ID.
212
339
  `expected_revision` is the original action `revision`. `repository_binding_digest` is the original
213
- issuance binding. `payload` is the exact original closed payload. If the payload was not completely
214
- retained, `payload` must be JSON `null`; never reconstruct it from partial output, repository text,
215
- or model memory. Do not add a caller-supplied payload digest or any other member.
216
-
217
- 1. The Skill does not immediately repeat `dev_flow_apply_action` or automatically retry.
218
- 2. Use the original `task_id` to call `dev_flow_get_task` with the exact `operation_probe`.
219
- 3. Call `dev_flow_get_next_action` only when a current action or outcome is needed. If both reads
220
- carry a probe, both reads use the same original `operation_probe`.
221
- 4. A stale pre-dispatch Task snapshot is not an authoritative read-back. Obey only a complete fresh
222
- Core result and obey the complete Core recovery assessment and advice.
223
- 5. Permit retry or recovery only when Core explicitly says it is safe to retry or recover. Do not
224
- branch on, decide, or interpret any recovery classification in the Skill.
225
- 6. Otherwise stop and report the authoritative blocker or recovery condition.
340
+ issuance binding. `payload` is the exact original closed payload; when it was not completely
341
+ retained, send JSON `null`. Never reconstruct it from partial output, repository text, or model
342
+ memory.
343
+
344
+ Use the original `task_id` to call `dev_flow_get_task` with that exact probe. A stale pre-dispatch
345
+ Task snapshot is not an authoritative read-back. Require one complete `recovery_assessment` with the
346
+ original graph operation identity, binding relations, operation evidence, optional committed proof,
347
+ retry flag, `next_advice`, optional unblock condition, and observation time. Stop if it is absent,
348
+ truncated, malformed, or refers to another operation.
349
+
350
+ Do not implement or branch on the five-class decision table. Obey only Core's complete
351
+ `next_advice`:
352
+
353
+ - `retry_current_action`: retry the ordinary current action only when Core also returns
354
+ `action_retry_safe=true` and the authoritative task still exposes the exact original action;
355
+ - `submit_recovery_apply`: submit the retained original top-level operation identity and payload,
356
+ adding exactly `recovery_apply={"operation_id":<original request_id>,"source_cursor":<original
357
+ source_cursor>}`; do not add a new recovery operation ID, destination, or classification;
358
+ - `read_next_action`: read the authoritative next action and continue only from that result;
359
+ - `resolve_blocker`: stop ordinary work and handle only the Core-returned current
360
+ `RESOLVE_BLOCKER` action;
361
+ - `stop_for_repository_drift`: report the bounded drift condition and stop.
362
+
363
+ Never infer that an unlisted action is safe. A recovery read itself cannot create a blocker or adopt
364
+ work. Only a Core-requested explicit recovery apply may do so, and its result becomes the next
365
+ authority.
226
366
 
227
367
  If any required identity is missing or incomplete, do not construct or send an `operation_probe`;
228
- send no fabricated probe and no half probe. Do not complete missing values from a partial response,
229
- do not assume `not_started`, and do not automatically retry. Stop and report that the Skill cannot
230
- prove the mutation state.
368
+ send no fabricated or half probe. Do not fill missing values from a partial response, do not assume
369
+ `not_started`, and do not automatically retry. Stop and report that the Skill cannot prove the
370
+ mutation state.
371
+
372
+ Do not branch, decide, or interpret any recovery classification and do not guess from repository
373
+ state. Core owns classification, effect proof, blocker eligibility, and mutation directives.
231
374
 
232
- A complete structured `ok=false` result is a domain error, not transport uncertainty. Never convert
233
- that domain error to missing or transport-failed. When it reports `retry_safe=false` and
234
- `action=none`, stop. Do not call `dev_flow_get_next_action` or `dev_flow_apply_action` to repair or
235
- retry that rejected mutation.
375
+ A complete structured `ok=false` result is an authoritative domain error, not transport
376
+ uncertainty. Never convert or treat that domain error as missing or transport failure. Obey Core's
377
+ `code`, `message`, `recovery.retry_safe`, `recovery.action`, and `recovery.message`. When it reports
378
+ `retry_safe=false` and `action=none`, stop; do not call `dev_flow_get_next_action` or
379
+ `dev_flow_apply_action`.
236
380
 
237
381
  ## Evidence and verification budget
238
382
 
239
- - Count verification commands exactly against Core's budget.
240
- - Do not run a prohibited full suite. When automatic capacity is exhausted, present the remaining
241
- allowed work as a manual handoff.
242
- - Preserve repository instructions and explicit user authority even when broader work is possible.
383
+ - Count verification commands exactly against Core's immutable budget.
384
+ - Do not run a prohibited full suite. When automatic capacity is exhausted, report the remaining
385
+ permitted work as manual handoff without claiming it ran.
386
+ - Preserve repository instructions and explicit user authority.
243
387
  - Keep static inspection, simulated Core execution, user-performed evidence, and native automated
244
388
  evidence distinctly labelled.
245
- - Submit actual evidence sources and outcomes. Never relabel a failed, skipped, or unavailable
246
- check as passed.
389
+ - Submit actual sources and outcomes. Never relabel failed, skipped, or unavailable work as passed.
247
390
 
248
391
  ## Blocked and terminal behavior
249
392
 
250
- Stop repository work when Core returns an authoritative blocker, ownership or contract conflict,
251
- `DONE`, or `CANCELLED`. Report Core's blocker and unblock condition, exact terminal outcome and
393
+ Stop repository work when Core returns authoritative `BLOCKED`, `DONE`, `CANCELLED`, an ownership or
394
+ contract conflict, or another safe-stop. Report Core's blocker and condition, terminal outcome,
252
395
  evidence summary, cancellation, or conflict without replacing or merging a task. Use
253
396
  `dev_flow_cancel_task` only after explicit user authority and a fresh current Core identity.
254
397
 
255
- Codex's belief that source work is complete does not override Core, and a blocker is not success.
398
+ Codex's belief that work is complete does not override Core, and a blocker is not success.
256
399
 
257
400
  ## Presentation contract
258
401
 
259
- Use complete structured Core results for every decision. A concise user summary must still preserve
260
- task identity, current revision, whether a mutation committed, any blocker or recovery condition,
261
- verification evidence and limits, and the terminal outcome. Never request or display private
262
- database locations.
402
+ Use complete structured Core results for every decision. A concise user summary still preserves task
403
+ identity, revision, current node, whether a mutation committed, method capability/fallback status,
404
+ verification evidence and limits, every blocker or recovery condition, and the terminal outcome.
405
+ Never request or display private database locations.
263
406
 
264
- If only a truncated preview is available, treat the operation as uncertain and follow the recovery
265
- contract. Do not fill missing data from a local catalog or silently discard outcome-bearing fields.
407
+ Treat a truncated preview as uncertainty and follow the recovery-before-retry contract. Never fill
408
+ missing data from a local catalog or discard outcome-bearing fields.