codex-workflow-v2 2.0.0-beta.13.9 → 2.0.0-beta.14.1

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 (297) hide show
  1. package/README.md +27 -388
  2. package/dist/reviewer-runtime-build.json +98 -34
  3. package/dist/src/alpha6/adoption.d.ts +3 -1
  4. package/dist/src/alpha6/adoption.js +48 -8
  5. package/dist/src/alpha6/adoption.js.map +1 -1
  6. package/dist/src/alpha6/captured-check-evidence.d.ts +51 -0
  7. package/dist/src/alpha6/captured-check-evidence.js +152 -0
  8. package/dist/src/alpha6/captured-check-evidence.js.map +1 -0
  9. package/dist/src/alpha6/component-owner.d.ts +15 -1
  10. package/dist/src/alpha6/component-owner.js +44 -2
  11. package/dist/src/alpha6/component-owner.js.map +1 -1
  12. package/dist/src/alpha6/corrective-decision-boundary.d.ts +4 -0
  13. package/dist/src/alpha6/corrective-decision-boundary.js +53 -0
  14. package/dist/src/alpha6/corrective-decision-boundary.js.map +1 -0
  15. package/dist/src/alpha6/downstream-proof.d.ts +1 -25
  16. package/dist/src/alpha6/downstream-proof.js +0 -171
  17. package/dist/src/alpha6/downstream-proof.js.map +1 -1
  18. package/dist/src/alpha6/literal-test-invocation.d.ts +2 -0
  19. package/dist/src/alpha6/literal-test-invocation.js +106 -0
  20. package/dist/src/alpha6/literal-test-invocation.js.map +1 -0
  21. package/dist/src/alpha6/milestone.d.ts +2 -0
  22. package/dist/src/alpha6/milestone.js +10 -1
  23. package/dist/src/alpha6/milestone.js.map +1 -1
  24. package/dist/src/alpha6/navigation-dirty-carryover.d.ts +11 -0
  25. package/dist/src/alpha6/navigation-dirty-carryover.js +130 -0
  26. package/dist/src/alpha6/navigation-dirty-carryover.js.map +1 -0
  27. package/dist/src/alpha6/plan-integrity.js +7 -5
  28. package/dist/src/alpha6/plan-integrity.js.map +1 -1
  29. package/dist/src/alpha6/remediation.d.ts +8 -21
  30. package/dist/src/alpha6/remediation.js +225 -474
  31. package/dist/src/alpha6/remediation.js.map +1 -1
  32. package/dist/src/alpha6/root-cause-replan-carryover.d.ts +4 -1
  33. package/dist/src/alpha6/root-cause-replan-carryover.js +29 -5
  34. package/dist/src/alpha6/root-cause-replan-carryover.js.map +1 -1
  35. package/dist/src/alpha7/autonomy.d.ts +9 -0
  36. package/dist/src/alpha7/autonomy.js +40 -1
  37. package/dist/src/alpha7/autonomy.js.map +1 -1
  38. package/dist/src/beta1/project-transaction.d.ts +3 -1
  39. package/dist/src/beta1/project-transaction.js +20 -6
  40. package/dist/src/beta1/project-transaction.js.map +1 -1
  41. package/dist/src/checks/runner.d.ts +26 -0
  42. package/dist/src/checks/runner.js +223 -0
  43. package/dist/src/checks/runner.js.map +1 -0
  44. package/dist/src/checks/task-sync.d.ts +10 -0
  45. package/dist/src/checks/task-sync.js +41 -0
  46. package/dist/src/checks/task-sync.js.map +1 -0
  47. package/dist/src/checks/worker.d.ts +1 -0
  48. package/dist/src/checks/worker.js +154 -0
  49. package/dist/src/checks/worker.js.map +1 -0
  50. package/dist/src/cli-actions.d.ts +3 -3
  51. package/dist/src/cli-actions.js +8 -15
  52. package/dist/src/cli-actions.js.map +1 -1
  53. package/dist/src/cli.js +43 -97
  54. package/dist/src/cli.js.map +1 -1
  55. package/dist/src/contracts.d.ts +54 -34
  56. package/dist/src/delegation.d.ts +5 -1
  57. package/dist/src/delegation.js +4 -0
  58. package/dist/src/delegation.js.map +1 -1
  59. package/dist/src/dependency-provenance.d.ts +2 -2
  60. package/dist/src/dependency-provenance.js +12 -69
  61. package/dist/src/dependency-provenance.js.map +1 -1
  62. package/dist/src/domain/base-sync-conflict.d.ts +13 -0
  63. package/dist/src/domain/base-sync-conflict.js +32 -0
  64. package/dist/src/domain/base-sync-conflict.js.map +1 -0
  65. package/dist/src/domain/step-start-admission.d.ts +4 -0
  66. package/dist/src/domain/step-start-admission.js +9 -0
  67. package/dist/src/domain/step-start-admission.js.map +1 -0
  68. package/dist/src/domain/virgin-registration.d.ts +3 -0
  69. package/dist/src/domain/virgin-registration.js +65 -0
  70. package/dist/src/domain/virgin-registration.js.map +1 -0
  71. package/dist/src/errors.d.ts +1 -1
  72. package/dist/src/errors.js.map +1 -1
  73. package/dist/src/failed-checkpoint-update.d.ts +69 -0
  74. package/dist/src/failed-checkpoint-update.js +171 -0
  75. package/dist/src/failed-checkpoint-update.js.map +1 -0
  76. package/dist/src/gateway-handshake.js +0 -8
  77. package/dist/src/gateway-handshake.js.map +1 -1
  78. package/dist/src/git.d.ts +3 -1
  79. package/dist/src/git.js +41 -14
  80. package/dist/src/git.js.map +1 -1
  81. package/dist/src/graph.js +25 -3
  82. package/dist/src/graph.js.map +1 -1
  83. package/dist/src/index.d.ts +1 -0
  84. package/dist/src/lifecycle/corrective-replan-credential-core.d.ts +2 -0
  85. package/dist/src/lifecycle/corrective-replan-credential-core.js +45 -9
  86. package/dist/src/lifecycle/corrective-replan-credential-core.js.map +1 -1
  87. package/dist/src/lifecycle/corrective-replan.js +12 -8
  88. package/dist/src/lifecycle/corrective-replan.js.map +1 -1
  89. package/dist/src/lifecycle/semantic-registry.js +4 -2
  90. package/dist/src/lifecycle/semantic-registry.js.map +1 -1
  91. package/dist/src/navigation-actions.d.ts +9 -0
  92. package/dist/src/navigation-actions.js +72 -0
  93. package/dist/src/navigation-actions.js.map +1 -0
  94. package/dist/src/navigation-update-artifact.d.ts +5 -0
  95. package/dist/src/navigation-update-artifact.js +227 -0
  96. package/dist/src/navigation-update-artifact.js.map +1 -0
  97. package/dist/src/navigation-update.d.ts +39 -0
  98. package/dist/src/navigation-update.js +82 -0
  99. package/dist/src/navigation-update.js.map +1 -0
  100. package/dist/src/observation.js +52 -29
  101. package/dist/src/observation.js.map +1 -1
  102. package/dist/src/observed-routes.js +10 -6
  103. package/dist/src/observed-routes.js.map +1 -1
  104. package/dist/src/pending-review-update.d.ts +0 -13
  105. package/dist/src/pending-review-update.js +1 -6
  106. package/dist/src/pending-review-update.js.map +1 -1
  107. package/dist/src/reviewer.d.ts +1 -1
  108. package/dist/src/reviewer.js +20 -17
  109. package/dist/src/reviewer.js.map +1 -1
  110. package/dist/src/runtime.d.ts +3 -0
  111. package/dist/src/runtime.js +6 -0
  112. package/dist/src/runtime.js.map +1 -0
  113. package/dist/src/state/corrective-replan-executor.d.ts +10 -0
  114. package/dist/src/state/corrective-replan-executor.js +38 -1
  115. package/dist/src/state/corrective-replan-executor.js.map +1 -1
  116. package/dist/src/state/corrective-replan-public-schema.js +15 -2
  117. package/dist/src/state/corrective-replan-public-schema.js.map +1 -1
  118. package/dist/src/state/corrective-replan-public.d.ts +9 -1
  119. package/dist/src/state/corrective-replan-public.js +50 -8
  120. package/dist/src/state/corrective-replan-public.js.map +1 -1
  121. package/dist/src/state/corrective-replan-transaction.d.ts +1 -0
  122. package/dist/src/state/corrective-replan-transaction.js +12 -11
  123. package/dist/src/state/corrective-replan-transaction.js.map +1 -1
  124. package/dist/src/state/corrective-yield-transaction.d.ts +1 -0
  125. package/dist/src/state/corrective-yield-transaction.js +11 -10
  126. package/dist/src/state/corrective-yield-transaction.js.map +1 -1
  127. package/dist/src/state/lock.d.ts +4 -0
  128. package/dist/src/state/lock.js +21 -0
  129. package/dist/src/state/lock.js.map +1 -1
  130. package/dist/src/version.d.ts +1 -1
  131. package/dist/src/version.js +1 -1
  132. package/dist/src/workflow-blocker-route.d.ts +8 -0
  133. package/dist/src/workflow-blocker-route.js +106 -0
  134. package/dist/src/workflow-blocker-route.js.map +1 -0
  135. package/dist/src/workflow.d.ts +88 -64
  136. package/dist/src/workflow.js +832 -1456
  137. package/dist/src/workflow.js.map +1 -1
  138. package/docs/autonomy-guardrails.md +26 -304
  139. package/docs/decisions.md +14 -112
  140. package/docs/development-flow.md +36 -237
  141. package/docs/project-memory.md +31 -50
  142. package/docs/release-app-evidence.md +190 -0
  143. package/docs/release.md +101 -388
  144. package/docs/updating-existing-project.md +65 -726
  145. package/package.json +11 -13
  146. package/plugins/codex-workflow-gateway/.codex-plugin/plugin.json +2 -2
  147. package/plugins/codex-workflow-gateway/references/chat-dispatch.md +88 -200
  148. package/plugins/codex-workflow-gateway/references/codebase-memory-routing.md +57 -0
  149. package/plugins/codex-workflow-gateway/references/protocol.md +51 -458
  150. package/plugins/codex-workflow-gateway/scripts/chat-dispatch.mjs +20 -4
  151. package/plugins/codex-workflow-gateway/scripts/chat-model-policy.mjs +21 -34
  152. package/plugins/codex-workflow-gateway/scripts/chat-registry.mjs +23 -5
  153. package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +92 -778
  154. package/references/state-machine.md +7 -5
  155. package/roles/delivery-coordinator.md +31 -11
  156. package/roles/scope-lead.md +1 -1
  157. package/roles/technical-planner.md +5 -2
  158. package/schemas/adoption-posture-event.schema.json +11 -0
  159. package/schemas/authorization-event.schema.json +1 -1
  160. package/schemas/corrective-decision-event.schema.json +26 -4
  161. package/schemas/corrective-replan-credentials.private.schema.json +8 -5
  162. package/schemas/corrective-replan-execution-event.private.schema.json +9 -0
  163. package/schemas/corrective-replan-public.schema.json +2 -1
  164. package/schemas/delegation-grant.schema.json +1 -1
  165. package/schemas/project-knowledge-map.schema.json +3 -1
  166. package/schemas/remediation-event.schema.json +10 -1
  167. package/schemas/task.schema.json +64 -2
  168. package/schemas/transition-definition.schema.json +4 -0
  169. package/schemas/transition-payloads.schema.json +16 -1
  170. package/src/alpha6/adoption.ts +1146 -0
  171. package/src/alpha6/captured-check-evidence.ts +132 -0
  172. package/src/alpha6/check-support-anchor.ts +128 -0
  173. package/src/alpha6/component-owner.ts +168 -0
  174. package/src/alpha6/corrective-decision-boundary.ts +45 -0
  175. package/src/alpha6/downstream-proof.ts +520 -0
  176. package/src/alpha6/failed-step-planning-recovery.ts +88 -0
  177. package/src/alpha6/handoff.ts +1443 -0
  178. package/src/alpha6/journal.ts +473 -0
  179. package/src/alpha6/literal-test-invocation.ts +84 -0
  180. package/src/alpha6/mechanical-feasibility.ts +488 -0
  181. package/src/alpha6/milestone.ts +2192 -0
  182. package/src/alpha6/navigation-dirty-carryover.ts +154 -0
  183. package/src/alpha6/npm-check-contract.ts +47 -0
  184. package/src/alpha6/plan-integrity.ts +298 -0
  185. package/src/alpha6/plan-risk.ts +1480 -0
  186. package/src/alpha6/preexecution-replan.ts +187 -0
  187. package/src/alpha6/remediation-cause.ts +98 -0
  188. package/src/alpha6/remediation.ts +2505 -0
  189. package/src/alpha6/review.ts +1198 -0
  190. package/src/alpha6/root-cause-replan-carryover.ts +491 -0
  191. package/src/alpha6/store-sidecars.ts +335 -0
  192. package/src/alpha7/autonomy.ts +449 -0
  193. package/src/alpha7/corrective-recovery.ts +1332 -0
  194. package/src/artifacts.ts +130 -0
  195. package/src/beta1/project-transaction.ts +364 -0
  196. package/src/change-explanation.ts +153 -0
  197. package/src/checks/runner.ts +245 -0
  198. package/src/checks/task-sync.ts +41 -0
  199. package/src/checks/worker.ts +149 -0
  200. package/src/cli-actions.ts +112 -0
  201. package/src/cli.ts +1490 -0
  202. package/src/contracts.ts +1512 -0
  203. package/src/credential-output.ts +89 -0
  204. package/src/credential-transport.ts +215 -0
  205. package/src/delegation.ts +194 -0
  206. package/src/dependency-provenance.ts +472 -0
  207. package/src/diagnostics.ts +93 -0
  208. package/src/domain/base-sync-conflict.ts +35 -0
  209. package/src/domain/completed-step-carryover.ts +76 -0
  210. package/src/domain/discovery.ts +27 -0
  211. package/src/domain/plan-semantics.ts +58 -0
  212. package/src/domain/step-start-admission.ts +10 -0
  213. package/src/domain/validation.ts +177 -0
  214. package/src/domain/virgin-registration.ts +46 -0
  215. package/src/errors.ts +24 -0
  216. package/src/failed-checkpoint-update.ts +203 -0
  217. package/src/fs-utils.ts +61 -0
  218. package/src/gateway-handshake.ts +95 -0
  219. package/src/git.ts +183 -0
  220. package/src/graph.ts +342 -0
  221. package/src/historical-step-provenance.ts +136 -0
  222. package/src/index.ts +23 -0
  223. package/src/lifecycle/canonical-hash.ts +28 -0
  224. package/src/lifecycle/catalog.ts +202 -0
  225. package/src/lifecycle/compiler-inspection.ts +29 -0
  226. package/src/lifecycle/core-static-readiness.ts +132 -0
  227. package/src/lifecycle/corrective-replan-authority.ts +136 -0
  228. package/src/lifecycle/corrective-replan-binding-manifest.ts +51 -0
  229. package/src/lifecycle/corrective-replan-credential-core.ts +437 -0
  230. package/src/lifecycle/corrective-replan-credential-schema.ts +54 -0
  231. package/src/lifecycle/corrective-replan-credentials.ts +48 -0
  232. package/src/lifecycle/corrective-replan.ts +847 -0
  233. package/src/lifecycle/evaluator.ts +48 -0
  234. package/src/lifecycle/fingerprint.ts +488 -0
  235. package/src/lifecycle/immutable.ts +8 -0
  236. package/src/lifecycle/implementation-table.ts +118 -0
  237. package/src/lifecycle/index.ts +8 -0
  238. package/src/lifecycle/schema-artifact.ts +263 -0
  239. package/src/lifecycle/semantic-registry.ts +574 -0
  240. package/src/lifecycle/types.ts +838 -0
  241. package/src/memory.ts +273 -0
  242. package/src/migration.ts +161 -0
  243. package/src/navigation-actions.ts +70 -0
  244. package/src/navigation-update-artifact.ts +198 -0
  245. package/src/navigation-update.ts +121 -0
  246. package/src/observation.ts +225 -0
  247. package/src/observed-routes.ts +665 -0
  248. package/src/operational-contract.ts +125 -0
  249. package/src/pending-review-update.ts +175 -0
  250. package/src/repository.ts +99 -0
  251. package/src/reviewer.ts +1879 -0
  252. package/src/runtime.ts +6 -0
  253. package/src/state/corrective-replan-executor.ts +819 -0
  254. package/src/state/corrective-replan-public-schema.ts +83 -0
  255. package/src/state/corrective-replan-public.ts +952 -0
  256. package/src/state/corrective-replan-transaction.ts +949 -0
  257. package/src/state/corrective-yield-executor.ts +327 -0
  258. package/src/state/corrective-yield-transaction.ts +730 -0
  259. package/src/state/lock.ts +902 -0
  260. package/src/state/store.ts +567 -0
  261. package/src/transition-core.ts +330 -0
  262. package/src/ulid.ts +24 -0
  263. package/src/version.ts +2 -0
  264. package/src/workflow-blocker-route.ts +109 -0
  265. package/src/workflow.ts +10342 -0
  266. package/docs/alpha7.1-implementation-brief.md +0 -268
  267. package/docs/alpha7.2-corrective-context-refresh-brief.md +0 -484
  268. package/docs/alpha7.2.1-remediation-recovery-brief.md +0 -86
  269. package/docs/beta1-stabilization-brief.md +0 -165
  270. package/docs/beta11-plan-integrity-recovery-brief.md +0 -38
  271. package/docs/beta13.2-signal-review-recovery.md +0 -38
  272. package/docs/beta2-initial-assembly-navigation-brief.md +0 -616
  273. package/docs/change-model.md +0 -118
  274. package/docs/delegated-approval.md +0 -254
  275. package/docs/lifecycle/state-machine-stabilization.md +0 -641
  276. package/docs/pdf/README.md +0 -24
  277. package/docs/pdf/codex-workflow-v2-architecture-ru.pdf +0 -0
  278. package/docs/pdf/codex-workflow-v2-chat-only-guide-ru.pdf +0 -0
  279. package/docs/pdf/codex-workflow-v2-technical-reference-ru.pdf +0 -0
  280. package/docs/pdf/requirements.txt +0 -1
  281. package/docs/pdf/sources/codex-workflow-v2-architecture-ru.md +0 -478
  282. package/docs/pdf/sources/codex-workflow-v2-chat-only-guide-ru.md +0 -506
  283. package/docs/pdf/sources/codex-workflow-v2-technical-reference-ru.md +0 -778
  284. package/docs/pending-review-update.md +0 -15
  285. package/docs/problem-briefs/01-pre-implementation-integrity.md +0 -482
  286. package/docs/problem-briefs/02-minimal-step-integrity.md +0 -411
  287. package/docs/problem-briefs/03-minimal-agent-context-integrity.md +0 -358
  288. package/docs/problem-briefs/04-task-dependency-and-structural-replacement-integrity.md +0 -573
  289. package/docs/problem-briefs/BRIEF-TEMPLATE.md +0 -56
  290. package/docs/problem-briefs/README.md +0 -120
  291. package/docs/problem-briefs/evidence/p01-mechanical-feasibility-corpus.md +0 -90
  292. package/docs/problem-briefs/evidence/signal-v4-pre-m3-replay.md +0 -246
  293. package/docs/split-required-recovery.md +0 -47
  294. package/docs/stable-release-defect-register.md +0 -730
  295. package/docs/validation-report.md +0 -182
  296. package/scripts/generate-pdf-docs.py +0 -524
  297. package/scripts/run-pdf-docs.mjs +0 -62
@@ -1,458 +1,51 @@
1
- # Gateway Protocol V2
2
-
3
- ## beta.12.6 compatibility transitions and continuable remediation
4
-
5
- - When fresh `next` advertises `task plan-integrity-recover`, consume its exact Task revision,
6
- Step, actor, and writer-token contract. This route is valid only for the Core-derived
7
- first-failure missing-root-npm-script evidence and must be followed by fresh `status -> next`.
8
- It records a replan posture without changing Plan or product files; corrective yield and the
9
- existing state-bound corrective-replan Human gate remain mandatory.
10
-
11
- - When fresh `next` advertises `task downstream-proof-recover`, Core has proved that every dirty
12
- file outside the active Step belongs to a completed transitive predecessor and that recorded Git
13
- history is intact. Invoke the exact lease-bound transition once. It preserves product files and
14
- HEAD, invalidates stale predecessor completion authority with an append-only event, yields C1,
15
- and routes the same Task to ordinary `task plan-set`. The replacement Plan, risk audit, and
16
- execution authorization are fresh authority; no Task or Milestone recreation is involved.
17
-
18
- - When an older installed package cannot reach that recovery because its normal update preflight
19
- requires a clean checkout, beta.12.6 permits one bounded dependency transport. The active
20
- Milestone base and Task branch must first receive separate exact commits changing only
21
- `package.json` and `package-lock.json`; product work remains dirty and uncommitted. Fresh beta.12.6
22
- `next` must then advertise `update downstream-proof-dependency-recover`. Its preflight proves the
23
- Task history at `HEAD^`, the dependency candidate at `HEAD`, aligned version surfaces, no lease or
24
- transaction, exact predecessor ownership, and a content hash of the dirty set. Recovery registers
25
- only the dependency commit. It does not mutate product files or Step state; fresh `next` must
26
- proceed to `task downstream-proof-recover`, which outranks manifest-induced Knowledge staleness.
27
-
28
- - `update dependency-provenance-preflight --id <TASK-ID>` is read-only. The matching
29
- `update dependency-provenance-recover --id <TASK-ID> --expected-revision <N> --actor <ACTOR>
30
- --reason <TEXT>` is valid only when preflight and fresh `next` both advertise it. Historical
31
- product commits absent from the current corrective Step are recognized only through intact passed
32
- strict-review plus verified reviewer-attestation chains and remain separately auditable as
33
- `retainedHistoricalCommits`.
34
- Task-local manifest/lock fields from recorded history may differ from the base, but the candidate
35
- commit must preserve them exactly while changing only the Workflow dependency entries.
36
- - `task historical-step-provenance-preflight --id <TASK-ID>` is read-only. The matching
37
- `task historical-step-provenance-recover` is available only for one unexpected product commit
38
- with an intact passed strict-review chain, matching prior final acceptance, no lease or pending
39
- operation, and dirty files confined to the current active Step. It retains historical authority
40
- without changing Git, worktree bytes, or the current Plan.
41
- - `update historical-step-dependency-preflight/recover` handles the same proof when the beta.12.9
42
- dependency-only commit is the unregistered HEAD. It binds the exact dependency candidate and the
43
- reviewed historical Step commit in one recovery record, preserves active product bytes, and then
44
- requires fresh `status` and `next`.
45
- - `task stop-override-prepare` is a read-only Human gate for the exact beta.11 attempt-four stop
46
- shape. `task stop-override-apply` requires the same Task revision, Step, actor, reason, Plan, HEAD,
47
- evidence binding, and returned `SOO-*` code in a later user turn. It appends evidence without
48
- deleting `stop-escalate`; it never applies to `split-required`.
49
- - After an applied stop override, one or more ordinary delegated `task context-refresh` transitions
50
- may rebind the Plan before attempt four. Fresh `next` returns `task run` only when Core validates
51
- the complete contiguous Plan/rebind/audit chain, mechanical equivalence at every hop, shared
52
- delegated authority, and append-only chronology. HEAD may differ from the override only when every
53
- intervening commit is an exact registered dependency-provenance recovery changing only
54
- `package.json` and `package-lock.json`. If C1 remains claimed but the lease was lost at the Human
55
- boundary, use only the simultaneously advertised `task writer-credential-replace` action.
56
- A provenance recovery recorded after the final context-refresh audit may explain exactly one
57
- additional Task revision only when it belongs to that verified Git chain. Any unexplained
58
- revision remains a `doctor` boundary.
59
- - Before a credential-consuming mutation, check the public `writerCredentialReference.expiresAt`
60
- against the current time and its actor/action binding. Lease heartbeat or renewal does not
61
- extend that reference's expiry. An expired, missing, consumed or unverifiable reference requires
62
- the simultaneously advertised `next.writerCredentialRecovery` action with its exact Task,
63
- revision and `requiredActor`, followed by fresh `status` and `next`; use the new reference.
64
- If no recovery is advertised, stop before mutation. Never read or patch the vault, extend expiry
65
- manually, or reuse the old reference. This check also applies after independent reviews and pauses.
66
- - `milestone progress --id <MS-ID>` is a read-only projection and the sole source for Coordinator
67
- progress tables. It preserves cancelled/replacement Tasks as distinct membership rows.
68
- - `scripts/chat-registry.mjs` atomically allocates project-monotonic `#NNN`, builds all six title
69
- families, verifies exact readback, supplies deterministic fallbacks, and binds the verified chat.
70
- It also journals a single creation permit, pending/actual IDs, evidence-based resolution and
71
- supervision cursors. Missing App listings never permit a retry. See `chat-dispatch.md` for
72
- dispatch commands and the explicit role/phase model + thinking policy. These are App routing
73
- helpers; they do not change Workflow protocol/state schema or grant approval authority.
74
-
75
- ## Handshake
76
-
77
- Run:
78
-
79
- ```text
80
- codex-workflow gateway handshake --repo <git-root>
81
- ```
82
-
83
- Require:
84
-
85
- - package name `codex-workflow-v2`
86
- - protocol version `2`
87
- - state schema version `2`
88
- - the capabilities needed for the requested operation
89
-
90
- Current capability set:
91
-
92
- - `project-memory-v1`
93
- - `graph-binding-v1`
94
- - `local-state-v1`
95
- - `milestone-lifecycle-v1`
96
- - `milestone-human-final-gate-v1`
97
- - `delegated-approval-v1`
98
- - `task-knowledge-rebind-v1`
99
- - `task-context-refresh-v1`
100
- - `structural-task-replacement-disabled-v1`
101
- - `project-composite-transaction-journal-v1`
102
- - `corrective-plan-audit-v1`
103
- - `safe-update-preflight-v1`
104
- - `bounded-dependency-provenance-recovery-v1`
105
- - `task-local-dependency-provenance-recovery-v1`
106
- - `legacy-stop-escalate-override-v1`
107
- - `stop-override-context-rebind-v1`
108
- - `stop-override-context-rebind-chain-v1`
109
- - `stop-override-post-audit-dependency-revision-v1`
110
- - `retained-reviewed-history-recovery-v1`
111
- - `milestone-progress-projection-v1`
112
- - `strict-reviewer-v1`
113
- - `legacy-snapshot-v1`
114
- - `plan-risk-audit-sidecar-v1`
115
- - `step-strict-review-sidecar-v1`
116
- - `step-remediation-circuit-breaker-sidecar-v1`
117
- - `milestone-scope-change-sidecar-v1`
118
- - `milestone-membership-integrity-v1`
119
- - `milestone-task-dependency-dag-v1`
120
- - `milestone-initial-plan-transaction-v1`
121
- - `task-c1-handoff-sidecar-v1`
122
- - `task-mechanical-feasibility-v1`
123
- - `semantic-plan-risk-audit-v2`
124
- - `guarded-remediation-continuation-v1`
125
- - `milestone-reverse-membership-integrity-v1`
126
- - `task-c1-handoff-bundle-v2`
127
- - `alpha6-adoption-posture-v1`
128
- - `alpha6-strict-review-rescue-v1`
129
- - `milestone-initial-assembly-v1`
130
- - `milestone-initial-assembly-navigation-v2`
131
- - `milestone-autonomy-contract-v1`
132
- - `milestone-autonomy-content-refresh-v1`
133
- - `milestone-autonomous-membership-evolution-v1`
134
- - `task-c1-derived-worker-actor-v1`
135
- - `guarded-corrective-auditor-routing-v1`
136
- - `corrective-decision-context-recovery-v1`
137
- - `remediation-mode-recovery-v1`
138
- - `plan-proof-obligations-v1`
139
- - `bounded-plan-integrity-recovery-v1`
140
- - `downstream-proof-predecessor-recovery-v1`
141
- - `active-downstream-proof-dependency-recovery-v1`
142
- - `corrective-yield-journal-v1`
143
- - `corrective-replan-journal-v1`
144
- - `corrective-replan-human-gate-v1`
145
- - `corrective-replan-protocol-v2`
146
-
147
- Protocol `1` and schema `2` remain valid only because alpha.7 is additive. The gateway must
148
- not claim compatibility if canonical entity shapes or non-additive command semantics change.
149
-
150
- ## Alpha.6 adoption posture
151
-
152
- For an existing schema 2 project without alpha.6 posture, repository-level `next` blocks
153
- execution behind adoption:
154
-
155
- - `action: "state adoption-apply"` when the repository is already at a safe boundary
156
- - `action: "restore safe boundary, then state adoption-prepare"` otherwise
157
-
158
- Use:
159
-
160
- ```text
161
- codex-workflow state adoption-prepare --repo <git-root>
162
- codex-workflow state adoption-apply --repo <git-root> \
163
- --actor <HUMAN-ACTOR> --confirmation-code <ADA-CODE>
164
- ```
165
-
166
- The confirmation is bound to project identity, package version, protocol version, schema
167
- version, canonical entity summaries, and the current sidecar baseline hash. Adoption is not
168
- `state migrate`.
169
-
170
- ## Worker Step completion and strict Step Review
171
-
172
- `task run` dispatches one Step and returns a first-field `writerLeaseReceipt`, followed by the
173
- credential-free lease metadata, Task state, and Worker envelope. Consume the receipt before the
174
- remaining payload and retain its token only in working memory. The Worker
175
- must leave all changes uncommitted and must not stage, commit, amend, reset, rebase, or
176
- modify Git history.
177
-
178
- While that Step is `in_progress`, repository-level `next` normally returns
179
- `action: "task step-complete"`, the exact `stepId`, and a `commitPolicy` declaring
180
- `workflow-core` ownership. The coordinator invokes that transition with the current revision
181
- and writer token. Core then runs configured checks, validates `allowedWrites`, stages the
182
- changes, creates the atomic commit, and records evidence.
183
- When `next` also includes `gitMutationPolicy`, obtain bounded permission for that exact
184
- Git-writing transition before the first call; do not probe and retry after a
185
- `.git/index.lock` failure. For `task start`, the policy applies only when the coordinator
186
- chooses `--workspace-owner local`.
187
-
188
- When `next` also includes `writerTokenContract`, the coordinator must retain the active writer
189
- lease from `writerLeaseReceipt` and pass it with the advertised option on the first transition call.
190
- The contract never contains the token value. Do not print, persist, reconstruct, or replace the
191
- token with a redacted fingerprint; stop before mutation when the active lease is unavailable.
192
- Satisfy this contract separately from any `gitMutationPolicy` on the same response.
193
-
194
- `codex-workflow <noun> [action] --help` is a read-only command-discovery route. It exits without
195
- constructing workflow state or validating lifecycle inputs. Use exact option lists only when the
196
- response says `exactOptionContractAvailable=true`; otherwise consult this packaged protocol. After
197
- help, obtain a fresh `next` before invoking the lifecycle transition.
198
-
199
- If the current Plan Risk Audit marks that Step for strict review, the commit is still
200
- workflow-owned, but `next` then returns `action: "task step-review"` with the same `stepId`
201
- and the exact `completionCommit`. Canonical Step completion remains blocked until the strict
202
- review and reviewer attestation sidecars verify against that exact commit.
203
- Invoke `task step-review` with the same lifecycle actor advertised by `next`
204
- (`c1Handoff.claimant` or `requiredActor` when present). The isolated reviewer is launched
205
- inside Core; do not substitute the reviewer identity into `--actor`. In claimed C1 posture,
206
- `next.writerTokenContract` is mandatory for both `task step-review` and the later
207
- `task review-launch`; pass the retained active lease on the first call of each exact action.
208
-
209
- After submission, a pending Task review is advertised as `action: "task review-launch"`, not
210
- `task review-record`. That compound route launches the read-only reviewer and atomically
211
- records the returned review. If claimant-bound mutation is active, pass the same lifecycle
212
- actor through `--actor`; reviewer identity remains internal to the route.
213
-
214
- An unrecorded commit is Git history drift. Stop instead of adding another commit or editing
215
- workflow state manually; recovery remains coordinator-controlled.
216
-
217
- If a Docker proof fails with `EPERM`, `operation not permitted`, or `permission denied` at the
218
- Docker socket/CLI boundary, classify it as sandbox access, not daemon failure. Re-run the exact
219
- read-only health probe or Plan command once with sandbox escalation; do not charge an infrastructure
220
- retry. Restarting Docker Desktop or pulling another image is forbidden on this evidence alone. A
221
- Docker infrastructure failure exists only when an escalated call reaches Docker and independently
222
- proves the daemon unavailable.
223
-
224
- ## Plan Risk Audit and remediation breaker
225
-
226
- Before `task authorize`, every new alpha.7 Task requires:
227
-
228
- ```text
229
- codex-workflow task plan-risk-audit --repo <git-root> \
230
- --id <TASK-ID> --expected-revision <REVISION> --file <audit.json>
231
- ```
232
-
233
- The audit must classify every current Step exactly once, name distinct planner/auditor
234
- actors, bind guarded failure modes to exact Step checks, and map each guarded failure mode to
235
- one hostile counterexample, expected safe result, and exact executable evidence command. Use `decision=approved` for an
236
- unguarded Plan. Missing, stale, `split-required`, or `stop-escalate` evidence blocks
237
- authorization.
238
-
239
- For guarded remediation, the first two failed cycles are recorded as `ordinary` and later cycles as
240
- `corrective`. This mode is diagnostic: a third or later retry remains executable and still requires
241
- a fresh strict review. A finding defaults to `route=fix`; `route=replan` is accepted only with exact
242
- Plan-conflict evidence and routes to ordinary `task plan-set` for implementation-Step changes.
243
-
244
- An explicit corrective disposition can still be recorded when the actor deliberately chooses a
245
- stop, split, or compatible historical recovery route:
246
-
247
- ```text
248
- codex-workflow task corrective-decision --repo <git-root> \
249
- --id <TASK-ID> --step <STEP-ID> --expected-revision <REVISION> --file <decision.json>
250
- ```
251
-
252
- `continue-fix` permits continuation; `replan-required`, `split-required`, and `stop-escalate` are
253
- explicit stop or redirection decisions. They are never inferred from attempt count. Without such an
254
- explicit decision, another failed strict review continues the same Task through its evidence-bound
255
- `fix`/`replan` route.
256
-
257
- One append-only compatibility exception exists for a beta.11 policy-created attempt-four stop.
258
- Fresh `next` must advertise `task stop-override-prepare`; run it with exact human inputs, present the
259
- complete binding, and stop. A later explicit user turn may run `task stop-override-apply` with the
260
- same inputs and confirmation code. Any split decision, Plan/revision/HEAD drift, missing attempt-3
261
- continue authority, lease, transaction, or journal damage blocks the route.
262
-
263
- ## Context refresh
264
-
265
- Before `task plan-set`, compare exact Step `allowedWrites` and expected output paths with scanner
266
- classifications. A planned new scanner-visible Knowledge file must be declared with
267
- `knowledgeImpact: create` and an exact path/category `knowledgeTargets` entry. Wildcards,
268
- directories, and inferred authority are not declarations; only Core may decide whether the final
269
- diff is eligible for delegated refresh.
270
-
271
- For every `task plan-set` navigation, consume `next.taskPlanContract` before building the Plan.
272
- Its `requiredRequirementIds` and `requiredAcceptanceIds` are exact-membership preconditions, not
273
- descriptive hints. Preserve each ID verbatim in the corresponding Plan array and use the returned
274
- Brief hash plus Knowledge Map revision/hash as the planning binding. Missing or stale contract data
275
- is a stop condition.
276
-
277
- Use `task context-refresh` only when the same `next` response returns it as the top-level action and
278
- exposes `contextRefresh` for the exact grant. Pass Task revision, map revision, delegate actor, and
279
- grant ID. Never run standalone `project-memory reconcile` first; Core blocks that non-atomic route
280
- when the exact delegated composite is available. The composite
281
- operation accepts content-hash-only drift and, under a Milestone Autonomy Grant, an exact
282
- supporting-source addition predeclared by the current execution-authorized Task Plan. Core checks
283
- the full fail-closed predicate; do not reconstruct it in the gateway. When `next` instead returns
284
- `contextRefreshBlocked.unsafeDifferences`, keep the change on the normal visible Knowledge path.
285
-
286
- Before updating the installed package, run `update preflight`. Continue only for `safe=true`.
287
- For an alpha.6 project trapped between a pending strict review and forbidden Knowledge rebind,
288
- an exact external alpha.7 runner may run `update rescue-preflight`. Continue only for
289
- `eligible=true` and only with the returned lock-repair and strict-review actions.
290
-
291
- ## C1 handoff
292
-
293
- `C1` coordination is machine-bound and local. Use:
294
-
295
- ```text
296
- codex-workflow task handoff-prepare --repo <git-root> --id <TASK-ID> \
297
- --expected-revision <REVISION> --actor <CURRENT-ACTOR> \
298
- [--target-actor <TARGET-ACTOR>] --reason <TEXT> [--writer-token <TOKEN>] \
299
- [--delegation-grant <GRANT>] [--expires-at <ISO-TIMESTAMP>]
300
- codex-workflow task handoff-show --repo <git-root> --id <TASK-ID>
301
- codex-workflow task claim --repo <git-root> --id <TASK-ID> \
302
- --expected-revision <REVISION> --actor <TARGET-ACTOR> --claim-token <TOKEN> \
303
- [--writer-token <WRITER-TOKEN>]
304
- codex-workflow task handback-create --repo <git-root> --id <TASK-ID> \
305
- --expected-revision <REVISION> --actor <CLAIMANT> --reason <TEXT> \
306
- --recommended-next <TEXT> [--limitation <TEXT>] [--writer-token <TOKEN>]
307
- ```
308
-
309
- While a handoff is pending, `next` blocks the previous action behind `task claim`. While
310
- claimed, only the claimant may mutate the Task, and lease-bound mutations must present the
311
- bound writer token. Milestone-linked Tasks must be claimed before start, and handback is
312
- terminal and evidence-bound. When target actor is omitted, Core derives
313
- `agent:worker:<task-id>`. No thread id is required or accepted as authority.
314
- The successful prepare response begins with `credentialHandoff`. Consume that receipt before the
315
- Task/event/bundle payload, retain its token only in working memory, and pass it exactly once to the
316
- declared `task claim --claim-token` action for the declared target actor. The later bundle remains
317
- contextual and intentionally contains no second copy of the claim token.
318
- The successful claim response then begins with `writerLeaseReceipt`. Retain that token only in
319
- working memory. In claimed C1 posture, fresh `next` exposes `writerTokenContract` on `task run`;
320
- pass the receipt token through its declared `--writer-token` option on the first run call. The
321
- successful run returns the refreshed writer receipt for later lease-bound transitions.
322
-
323
- `task result-set` is also lease-bound. It requires the active `--writer-token` and the exact C1
324
- claimant in `--actor` when the Task is claimed. Success releases the lease before the Task enters
325
- `awaiting_final_acceptance`; the token is no longer valid. The Human gate must therefore remain
326
- lease-free for an arbitrary amount of time. After acceptance, obtain the new merge credential only
327
- through the `writerCredentialRecovery` action advertised by fresh `next`.
328
-
329
- ## Milestone assembly, autonomy, and human gate
330
-
331
- During initial planning, materialize every linked Task and then call `milestone plan-set` once
332
- with the complete membership. Execution is blocked while reverse membership is incomplete.
333
- Before Task 1 and between linked Tasks, follow top-level `next.action = "milestone initial-assembly"`.
334
- Its `linked-task-assembly.commands` permit `discovery start` and `discovery materialize`; after the
335
- first linked Task exists, the separate closing option permits `milestone plan-set`. If `status` or `next` fails, stop: never label
336
- the gap expected and invoke `milestone plan-set` directly.
337
-
338
- Every required navigation checkpoint is strictly sequential: start `status`, wait until its
339
- terminal result is recorded, then start `next` and wait for its terminal result. Never issue the
340
- pair concurrently or through a parallel tool call. The trusted transcript validator treats a
341
- second invocation before the first terminal result as indeterminate release evidence.
342
-
343
- After that Plan, one human may prepare and grant a maximum-72-hour Milestone Autonomy Contract:
344
-
345
- ```text
346
- codex-workflow milestone autonomy-prepare --repo <git-root> --id <MS-ID> \
347
- --expected-revision <REVISION> --principal <HUMAN> --delegate <AGENT> --expires-at <ISO>
348
- codex-workflow milestone autonomy-grant --repo <git-root> --id <MS-ID> \
349
- --expected-revision <REVISION> --principal <HUMAN> --delegate <AGENT> --expires-at <ISO> \
350
- --confirmation-code <MAC-CODE>
351
- ```
352
-
353
- The contract issues a milestone-scoped grant for the existing Task/Milestone approval transitions
354
- and Project Memory approval only inside an atomic Task context refresh for the same Milestone.
355
- That composite path covers content-only drift plus exact Plan-bounded supporting-source additions;
356
- it cannot approve Project Memory independently. `milestone autonomy-evolve --file
357
- <plan.json>` is permitted only when outcome, success signal, acceptance, checks, discovery, and
358
- base branch still match the contract. It journals agent actor plus contract evidence and requires
359
- reauthorization afterward.
360
-
361
- After the initial empty planning posture, Milestone scope updates use:
362
-
363
- ```text
364
- codex-workflow milestone scope-change-prepare --repo <git-root> \
365
- --id <MS-ID> --expected-revision <REVISION> --actor <HUMAN-ACTOR> --file <plan.json>
366
- codex-workflow milestone scope-change-apply --repo <git-root> \
367
- --id <MS-ID> --expected-revision <REVISION> --actor <HUMAN-ACTOR> \
368
- --confirmation-code <MSC-CODE> --file <plan.json>
369
- ```
370
-
371
- This ordinary semantic-change path is human-only. Generic delegated approval never authorizes it.
372
-
373
- At `awaiting_final_acceptance`, `next` returns `requiredHumanGate` with kind
374
- `milestone_final_acceptance`, Milestone ID, revision, Plan/Result/evidence hashes, validated
375
- HEAD, and a confirmation code. Display the complete object and end the turn. Only a later
376
- explicit user message that approves the same code authorizes:
377
-
378
- ```text
379
- codex-workflow milestone accept --repo <git-root> --id <MS-ID> \
380
- --expected-revision <REVISION> --actor <USER-ACTOR> \
381
- --confirmation-code <MSA-CODE>
382
- ```
383
-
384
- Do not infer approval from the request that initiated validation. A changed revision, hash,
385
- or HEAD requires a new gate.
386
-
387
- ## Delegated Approval
388
-
389
- `delegation prepare --file <policy.json>` returns a `delegation_grant_issuance` gate with a
390
- project-bound policy hash and `DGA-*` confirmation code. Display it and end the turn. A later
391
- explicit user message containing the exact code permits `delegation grant`.
392
-
393
- Active eligible grants appear in `next.delegatedApprovalOptions`. Use only the option whose
394
- transition matches the requested command, with the named delegate as actor and the grant ID
395
- as `--delegation-grant`. The resulting authorization event records the grant and both actors.
396
- For `milestone.final_accept`, also pass the current `MSA-*` code; the existing grant replaces
397
- the later-message requirement, not the state binding.
398
- Do not pass `--delegation-grant` to ordinary C1 handoff, claim, run, step-complete,
399
- step-review, merge, or sync-base calls. Those transitions are not authorized by a Milestone
400
- approval grant unless the same `next` response explicitly advertises an eligible grant for the
401
- exact transition.
402
-
403
- Delegated approval does not cover adoption apply or the ordinary semantic Milestone scope-change
404
- path. Membership-only evolution requires the separate Milestone Autonomy Contract.
405
-
406
- ## Graph Refresh Request
407
-
408
- The package returns:
409
-
410
- ```json
411
- {
412
- "protocolVersion": 1,
413
- "requestId": "uuid",
414
- "projectId": "local-project-id",
415
- "graphKind": "product",
416
- "sourceRoot": "/absolute/local/path",
417
- "rootFingerprint": "sha256",
418
- "indexedHead": "git-sha-or-null",
419
- "packageVersion": null,
420
- "manifestHash": null,
421
- "mode": "moderate",
422
- "persistence": false,
423
- "issuedAt": "ISO-8601"
424
- }
425
- ```
426
-
427
- `workflow` requests set packageVersion and manifestHash and point sourceRoot to
428
- the prepared versioned workflow view.
429
-
430
- ## Evidence
431
-
432
- Return the request unchanged with:
433
-
434
- ```json
435
- {
436
- "requestId": "same-uuid",
437
- "provider": "codebase-memory-mcp",
438
- "projectKey": "provider-project-key",
439
- "rootFingerprint": "same-sha256",
440
- "indexedHead": "same-git-sha-or-null",
441
- "packageVersion": null,
442
- "manifestHash": null,
443
- "mode": "moderate",
444
- "status": "ready",
445
- "nodeCount": 100,
446
- "edgeCount": 200,
447
- "observedAt": "ISO-8601"
448
- }
449
- ```
450
-
451
- The package rejects mismatched or stale requests. Absolute source paths remain
452
- local workflow data and are not project knowledge.
453
-
454
- ## Retention
455
-
456
- Product binding stores only the current evidence. Workflow binding stores the
457
- current package evidence plus one previous package snapshot. A new snapshot is
458
- retained only after the new binding is ready.
1
+ # Current action inputs
2
+
3
+ Fresh Core navigation defines eligibility; current help/schemas define serialization.
4
+ Read this reference for planning, context refresh and sealed review, not as another transition catalog.
5
+
6
+ ## Planning and Knowledge
7
+
8
+ For `task plan-set`, use `taskPlanContract`: retain every `requiredRequirementIds` and
9
+ `requiredAcceptanceIds` member, Brief hash and Knowledge Map revision/hash. Prose cannot replace IDs.
10
+ Replanning preserves completed evidence and semantic/safety boundaries; contradictory bindings block submission.
11
+ Compare exact `allowedWrites`/outputs with scanner classifications. New Knowledge sources require
12
+ `knowledgeImpact: create` and exact normalized path/category in `knowledgeTargets`, not wildcards/directories.
13
+ Approved repository evidence defines source authority; planners cannot infer delegated eligibility.
14
+
15
+ For advertised `task context-refresh`, use its exact Task/map revisions, delegate and grant atomically;
16
+ do not reconcile/approve separately first. Unsafe differences follow Core's Knowledge approval route.
17
+ Additional scope uses `change explain` with a closed proposal; its diagnostic is not approval.
18
+
19
+ ## Sealed review
20
+
21
+ For `external-sealed`, obtain the advertised Step/Task packet and send only immutable evidence and
22
+ the read-only role to an independent reviewer. Thread identity alone proves no review: obtain the
23
+ actual result with unchanged bindings. Do not substitute a nested local App-sandbox reviewer.
24
+ Record the full envelope: `protocol`, `packetHash`, `repositorySealHash`, `reviewerThreadId`,
25
+ `reviewMode`, and nested `review` containing `status`, `reviewer`, `summary`, `findings`.
26
+ Use `task step-review-record --help` or `task review-sealed-record --help` for its schema/example.
27
+ Mode belongs in the envelope, not an invented CLI option. Use the lifecycle actor/reference from
28
+ `next`, separately from reviewer identity. Discard results with changed packet, commit or seal.
29
+ Unverified launch or permission denial is not a semantic implementation failure.
30
+
31
+ ## Context and authority changes
32
+
33
+ Help and derived actor names waive no claim, lease, audit or authority checks. Review findings grant
34
+ no scope expansion/new Task: follow current fix/replan/stop and preserve history. Choose alternatives
35
+ consistent with user intent; advertised cancellation/publication/grant issuance is not authorization.
36
+ Result submission may release the lease before acceptance; use fresh navigation/credential recovery,
37
+ not the old reference. Normal updates require installed `update preflight` with `safe=true`; for an
38
+ explicit blocked-checkpoint update follow the gateway's exact-target exception. Unsafe state never
39
+ permits manual state editing or deleting retained work.
40
+
41
+ ## Delegated corrective replan
42
+
43
+ For `task corrective-replan-authorize`, retain the independently validated candidate and add
44
+ `delegation: {grantId, actor}` from the eligible execution option. `authority.actorIdentityHash` is
45
+ SHA256 of the exact grant delegate UTF-8 string; `authority.humanPrincipalIdentityHash` hashes its
46
+ principal string as provenance, not new Human confirmation. Preserve objective, requirements,
47
+ acceptance and completed evidence. Core revalidates grant at issuance and execution.
48
+ Run authorize with `--id --file`, then `task corrective-replan-execute` with its exact returned
49
+ credential. The receipt contains `delegated`, no `human` confirmation; never use prepare/confirm
50
+ for it. Missing/expired authority returns to grant issuance/expansion; unattainable acceptance returns
51
+ to Discovery, never a weakened Plan.
@@ -29,7 +29,17 @@ function promptMatches(value, digest) {
29
29
  if (typeof value !== 'string') return false;
30
30
  if (hash(value) === digest) return true;
31
31
  const wrapped = /^<codex_delegation>\s*<source_thread_id>[^<]+<\/source_thread_id>\s*<input>([\s\S]*)<\/input>\s*<\/codex_delegation>$/.exec(value);
32
- return wrapped !== null && hash(wrapped[1]) === digest;
32
+ if (wrapped === null) return false;
33
+ const input = wrapped[1];
34
+ // Older App transports carried literal input. Keep exact bytes authoritative.
35
+ if (hash(input) === digest) return true;
36
+ // Decode only the five XML text entities, exactly once. No trimming, recursive
37
+ // unescape, HTML/numeric entities or Unicode normalization may alter the packet.
38
+ // In particular, original literal `&gt;` arrives as `&amp;gt;` and stays `&gt;`.
39
+ if (input.includes('<') || /&(?!amp;|lt;|gt;|quot;|apos;)/.test(input)) return false;
40
+ const entities = { amp: '&', lt: '<', gt: '>', quot: '"', apos: "'" };
41
+ const decoded = input.replace(/&(amp|lt|gt|quot|apos);/g, (_match, name) => entities[name]);
42
+ return hash(decoded) === digest;
33
43
  }
34
44
  function view(entry) {
35
45
  const d = entry.dispatch;
@@ -64,7 +74,13 @@ export function dispatchAction(action, entry, input = {}) {
64
74
  const selection = selectChatModel(entry.type, input.modelRequest);
65
75
  const id = randomUUID();
66
76
  const marker = `[workflow-dispatch:${id}:${hash(prompt)}]`;
67
- const dispatchedPrompt = `${marker}\n${prompt}\nExecution boundary: use the actual child checkout returned by App readback. Before any write, reconcile it with the exact Task branch and run dispatch-context-check. A repository path in this packet is identity context, not authorization to write outside that checkout.`;
77
+ // Only the registry's explicit review/audit roles receive a read-only boundary.
78
+ // A model phase or packet prose cannot turn a product Worker into a reviewer.
79
+ const reviewRole = ['step-review', 'final-review', 'corrective-audit', 'plan-audit'].includes(entry.type);
80
+ const boundary = reviewRole
81
+ ? 'Review boundary: use the exact canonical repository and immutable commit, packet/seal or audit-request bindings supplied for this independent review. Verify those bindings before reading evidence and before returning the result; stop if they change. The App checkout may be detached or on another branch: do not switch it or require Task-branch dispatch-context-check for read-only inspection. Do not modify product files, Git history, or Workflow state, and do not invoke lifecycle mutations. Save the review result only to an explicitly requested artifact path outside all repository checkouts, under actual filesystem permissions; this instruction grants no filesystem access. A repository path identifies read evidence, never write authority.'
82
+ : 'Execution boundary: use the actual child checkout returned by App readback. Before any product or repository write, reconcile it with the exact Task branch and run dispatch-context-check. A repository path in this packet is identity context, not authorization to write outside that checkout.';
83
+ const dispatchedPrompt = `${marker}\n${prompt}\n${boundary}`;
68
84
  entry.dispatch = {
69
85
  version: 1, id, state: 'creating', appProjectId, hostId, repositoryRoot, gitDir, executionMode,
70
86
  promptPath, promptHash: hash(prompt), dispatchedPromptHash: hash(dispatchedPrompt), marker,
@@ -73,7 +89,7 @@ export function dispatchAction(action, entry, input = {}) {
73
89
  };
74
90
  return { ...view(entry), createAllowed: true, nextAction: 'create-thread-once', createArgs: {
75
91
  target: { type: 'project', projectId: appProjectId, environment: { type: executionMode } },
76
- title: entry.requestedTitle, prompt: dispatchedPrompt, model: selection.model, thinking: selection.thinking,
92
+ title: entry.requestedTitle, prompt: dispatchedPrompt, ...selection.dispatchArgs,
77
93
  } };
78
94
  }
79
95
  const d = entry.dispatch;
@@ -291,7 +307,7 @@ export function dispatchAction(action, entry, input = {}) {
291
307
  d.selection = selection;
292
308
  d.selectionHistory.push(selection);
293
309
  return { ...view(entry), followUpArgs: { threadId: entry.threadId, hostId: entry.hostId,
294
- model: selection.model, thinking: selection.thinking } };
310
+ ...selection.dispatchArgs } };
295
311
  }
296
312
  throw new Error(`Unknown dispatch action: ${action}`);
297
313
  }
@@ -1,43 +1,30 @@
1
- // Relative cost/latency policy, not a price list or an availability oracle.
2
- export const MODEL_POLICY_VERSION = 'chat-model-policy-v1';
3
- const PROFILES = {
4
- mechanical: [['gpt-5.4-mini', 'low'], ['gpt-5.6-luna', 'low']],
5
- scoped: [['gpt-5.6-luna', 'medium'], ['gpt-5.6-terra', 'medium']],
6
- implementation: [['gpt-5.6-terra', 'medium'], ['gpt-5.6-sol', 'medium']],
7
- planning: [['gpt-5.6-sol', 'medium'], ['gpt-6-astra', 'medium']],
8
- review: [['gpt-5.6-sol', 'high'], ['gpt-6-astra', 'high']],
9
- 'scoped-review': [['gpt-5.6-terra', 'medium'], ['gpt-5.6-sol', 'medium']],
10
- complex: [['gpt-6-astra', 'high'], ['gpt-5.6-sol', 'high']],
11
- };
12
- const TYPES = ['coordinator', 'task', 'step-review', 'final-review', 'corrective-audit', 'plan-audit'];
1
+ // Destination settings are authoritative unless the user explicitly chose an override.
2
+ export const MODEL_POLICY_VERSION = 'chat-model-policy-v3';
3
+ const TYPES = [
4
+ 'coordinator', 'task', 'step-review', 'final-review', 'corrective-audit', 'plan-audit', 'workflow-blocker',
5
+ ];
13
6
  export function selectChatModel(type, request) {
14
7
  if (!TYPES.includes(type)) throw new Error('Unknown chat type.');
15
- if (!request || !['routine', 'standard', 'complex'].includes(request.complexity)
16
- || !['planning', 'implementation', 'mechanical', 'review', 'coordination'].includes(request.phase)
17
- || typeof request.rationale !== 'string' || !request.rationale.trim()
18
- || typeof request.highRisk !== 'boolean') throw new Error('Explicit phase, complexity, highRisk and rationale are required.');
8
+ if (request == null) return {
9
+ policyVersion: MODEL_POLICY_VERSION, profile: 'destination-default', dispatchArgs: {},
10
+ };
11
+ // This records the caller's explicit-user-selection assertion; it is not an App
12
+ // permission or a substitute for the actual user instruction at dispatch time.
13
+ if (request.userAuthorized !== true || typeof request.model !== 'string' || !request.model.trim()) {
14
+ throw new Error('Model override requires an explicit user-authorized model; otherwise omit modelRequest and use destination defaults.');
15
+ }
19
16
  if (!Array.isArray(request.availableModels) || request.availableModels.length === 0
20
17
  || request.availableModels.some(m => !m || typeof m.id !== 'string' || !Array.isArray(m.reasoningEfforts)
21
18
  || m.reasoningEfforts.some(e => typeof e !== 'string'))
22
19
  || new Set(request.availableModels.map(m => m.id)).size !== request.availableModels.length) {
23
20
  throw new Error('Provide the destination host model/effort catalog; never infer availability.');
24
21
  }
25
- const reviewRole = type.endsWith('review') || type.endsWith('audit');
26
- let profile;
27
- if (request.highRisk || request.complexity === 'complex') profile = 'complex';
28
- else if (type === 'step-review' && request.complexity === 'routine') profile = 'scoped-review';
29
- else if (reviewRole || request.phase === 'review') profile = 'review';
30
- else if (request.phase === 'planning') profile = 'planning';
31
- else if (request.phase === 'mechanical') {
32
- if (request.complexity !== 'routine') throw new Error('Mechanical phase requires routine complexity.');
33
- profile = 'mechanical';
34
- } else if (type === 'coordinator' || request.phase === 'coordination' || request.complexity === 'routine') profile = 'scoped';
35
- else profile = 'implementation';
36
- const selected = PROFILES[profile].find(([id, effort]) => request.availableModels.some(m => m.id === id && m.reasoningEfforts.includes(effort)));
37
- if (!selected) throw new Error(`No supported model/effort for ${profile}; explicit policy revision required, never inherit coordinator settings.`);
38
- return {
39
- policyVersion: MODEL_POLICY_VERSION, profile, model: selected[0], thinking: selected[1],
40
- phase: request.phase, complexity: request.complexity, highRisk: request.highRisk,
41
- rationale: request.rationale.trim(), fallback: selected !== PROFILES[profile][0],
42
- };
22
+ const selected = request.availableModels.find(m => m.id === request.model);
23
+ if (!selected || (request.thinking !== undefined && !selected.reasoningEfforts.includes(request.thinking))) {
24
+ throw new Error('User-selected model/effort is unavailable on the destination host; no automatic substitution.');
25
+ }
26
+ const dispatchArgs = { model: request.model,
27
+ ...(request.thinking === undefined ? {} : { thinking: request.thinking }) };
28
+ return { policyVersion: MODEL_POLICY_VERSION, profile: 'explicit-user-selection',
29
+ ...dispatchArgs, userAuthorized: true, dispatchArgs };
43
30
  }