codex-workflow-v2 2.0.0-beta.13 → 2.0.0-beta.13.10

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 (86) hide show
  1. package/README.md +6 -1
  2. package/dist/reviewer-runtime-build.json +44 -20
  3. package/dist/src/alpha6/failed-step-planning-recovery.d.ts +10 -0
  4. package/dist/src/alpha6/failed-step-planning-recovery.js +93 -0
  5. package/dist/src/alpha6/failed-step-planning-recovery.js.map +1 -0
  6. package/dist/src/alpha6/plan-risk.d.ts +4 -0
  7. package/dist/src/alpha6/plan-risk.js +50 -13
  8. package/dist/src/alpha6/plan-risk.js.map +1 -1
  9. package/dist/src/alpha6/preexecution-replan.d.ts +38 -0
  10. package/dist/src/alpha6/preexecution-replan.js +130 -0
  11. package/dist/src/alpha6/preexecution-replan.js.map +1 -0
  12. package/dist/src/alpha6/remediation.d.ts +4 -2
  13. package/dist/src/alpha6/remediation.js +155 -20
  14. package/dist/src/alpha6/remediation.js.map +1 -1
  15. package/dist/src/alpha6/root-cause-replan-carryover.d.ts +18 -0
  16. package/dist/src/alpha6/root-cause-replan-carryover.js +396 -0
  17. package/dist/src/alpha6/root-cause-replan-carryover.js.map +1 -0
  18. package/dist/src/alpha7/autonomy.d.ts +3 -0
  19. package/dist/src/alpha7/autonomy.js +89 -42
  20. package/dist/src/alpha7/autonomy.js.map +1 -1
  21. package/dist/src/change-explanation.d.ts +64 -0
  22. package/dist/src/change-explanation.js +150 -0
  23. package/dist/src/change-explanation.js.map +1 -0
  24. package/dist/src/cli-actions.d.ts +3 -2
  25. package/dist/src/cli-actions.js +6 -0
  26. package/dist/src/cli-actions.js.map +1 -1
  27. package/dist/src/cli.js +73 -1
  28. package/dist/src/cli.js.map +1 -1
  29. package/dist/src/contracts.d.ts +38 -0
  30. package/dist/src/dependency-provenance.d.ts +3 -2
  31. package/dist/src/dependency-provenance.js +33 -2
  32. package/dist/src/dependency-provenance.js.map +1 -1
  33. package/dist/src/domain/plan-semantics.d.ts +11 -0
  34. package/dist/src/domain/plan-semantics.js +49 -0
  35. package/dist/src/domain/plan-semantics.js.map +1 -0
  36. package/dist/src/gateway-handshake.js +2 -0
  37. package/dist/src/gateway-handshake.js.map +1 -1
  38. package/dist/src/lifecycle/corrective-replan.js +3 -3
  39. package/dist/src/lifecycle/corrective-replan.js.map +1 -1
  40. package/dist/src/observed-routes.js +1 -0
  41. package/dist/src/observed-routes.js.map +1 -1
  42. package/dist/src/pending-review-update.d.ts +49 -0
  43. package/dist/src/pending-review-update.js +132 -0
  44. package/dist/src/pending-review-update.js.map +1 -0
  45. package/dist/src/repository.js +16 -4
  46. package/dist/src/repository.js.map +1 -1
  47. package/dist/src/reviewer.js +4 -1
  48. package/dist/src/reviewer.js.map +1 -1
  49. package/dist/src/state/corrective-replan-executor.js +3 -1
  50. package/dist/src/state/corrective-replan-executor.js.map +1 -1
  51. package/dist/src/state/corrective-replan-public.js +5 -4
  52. package/dist/src/state/corrective-replan-public.js.map +1 -1
  53. package/dist/src/state/corrective-yield-executor.js +12 -3
  54. package/dist/src/state/corrective-yield-executor.js.map +1 -1
  55. package/dist/src/state/store.d.ts +1 -1
  56. package/dist/src/state/store.js +17 -3
  57. package/dist/src/state/store.js.map +1 -1
  58. package/dist/src/version.d.ts +1 -1
  59. package/dist/src/version.js +1 -1
  60. package/dist/src/version.js.map +1 -1
  61. package/dist/src/workflow.d.ts +84 -1
  62. package/dist/src/workflow.js +1616 -355
  63. package/dist/src/workflow.js.map +1 -1
  64. package/docs/beta13.2-signal-review-recovery.md +38 -0
  65. package/docs/change-model.md +118 -0
  66. package/docs/delegated-approval.md +26 -0
  67. package/docs/pdf/codex-workflow-v2-architecture-ru.pdf +0 -0
  68. package/docs/pdf/codex-workflow-v2-chat-only-guide-ru.pdf +0 -0
  69. package/docs/pdf/codex-workflow-v2-technical-reference-ru.pdf +0 -0
  70. package/docs/pdf/sources/codex-workflow-v2-architecture-ru.md +9 -1
  71. package/docs/pdf/sources/codex-workflow-v2-chat-only-guide-ru.md +9 -5
  72. package/docs/pdf/sources/codex-workflow-v2-technical-reference-ru.md +18 -3
  73. package/docs/pending-review-update.md +15 -0
  74. package/docs/release.md +267 -2
  75. package/docs/updating-existing-project.md +36 -6
  76. package/docs/validation-report.md +30 -9
  77. package/package.json +2 -1
  78. package/plugins/codex-workflow-gateway/references/chat-dispatch.md +204 -0
  79. package/plugins/codex-workflow-gateway/references/protocol.md +11 -0
  80. package/plugins/codex-workflow-gateway/scripts/chat-dispatch.mjs +298 -0
  81. package/plugins/codex-workflow-gateway/scripts/chat-model-policy.mjs +43 -0
  82. package/plugins/codex-workflow-gateway/scripts/chat-registry.mjs +55 -3
  83. package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +218 -21
  84. package/schemas/plan-risk-audit-event.schema.json +1 -0
  85. package/schemas/preexecution-replan-event.schema.json +45 -0
  86. package/schemas/task.schema.json +55 -0
@@ -22,23 +22,45 @@ state schema. Совпадение `stateSchemaVersion` до и после об
22
22
  нужна. Для alpha.6 при `stateSchemaVersion: 2` применяется не migration, а sidecar-only
23
23
  adoption posture.
24
24
 
25
+ ### beta.13.1: legacy PRA compatibility after beta.13
26
+
27
+ `2.0.0-beta.13.1` preserves the beta.13 protocol/schema `2/2` and adds no state migration. The
28
+ structural production-edge rule is prospective: every newly written ordinary or atomic
29
+ corrective-replan PRA receives the hash-chained `structuralProductionEdgeAuthority=required-v1`
30
+ marker, and its current Plan must satisfy the edge contract. A markerless PRA and Task written
31
+ before that authority existed remain readable; Workflow must not reinterpret their historical
32
+ `runtime-composition` classification as proof that their old Plan contained beta.13 fields.
33
+ Historical PRA events from an earlier Plan are hash/shape validated but are not compared with the
34
+ current Plan's edges. This compatibility rule never edits, migrates or silently approves external
35
+ state. A later Plan/PRA recorded by beta.13.1 must satisfy the full structural boundary.
36
+
37
+ This does not add signed provenance to local Workflow state. A full privileged rewrite of Task
38
+ state and its complete self-hashed sidecar chain remains outside the trust model; repository rules
39
+ continue to prohibit manual state edits. The regression proves compatibility and fail-closed
40
+ partial mismatch, not authenticity against the machine owner.
41
+
42
+ The normal safe-update sequence below targets exact `2.0.0-beta.13.1`. It is also the supported
43
+ patch path from beta.13 when `status` or `next` reports `STATE_CORRUPT` solely because a markerless
44
+ pre-beta.13 PRA lacks production-edge fields: run the old-version read-only preflight first, install
45
+ the patch dependency-only, and resume from a fresh handshake. Never edit the PRA sidecar manually.
46
+
25
47
  ### beta.13: coherent continuation and host-safe credentials
26
48
 
27
- `2.0.0-beta.13` сохраняет `protocolVersion: 2` и `stateSchemaVersion: 2`; отдельная state migration
49
+ `2.0.0-beta.13.1` сохраняет `protocolVersion: 2` и `stateSchemaVersion: 2`; отдельная state migration
28
50
  для перехода с beta.12.19 не нужна. Обновление выполняется только на безопасной границе обычного
29
51
  `update preflight`: нет running Step, active/stale writer lease, незавершённой transaction/Core
30
52
  operation и неучтённых dirty product bytes. Если хотя бы одно условие не выполнено, сначала
31
- завершите advertised recovery текущей repository-local версией; установка beta.13 сама по себе не
53
+ завершите advertised recovery текущей repository-local версией; установка beta.13.1 сама по себе не
32
54
  является recovery-route и не разрешает переносить или редактировать внешний state.
33
55
 
34
56
  Точный путь обновления:
35
57
 
36
58
  1. Старой repository-local версией зафиксируйте `handshake`, `status`, `next` и read-only
37
59
  `update preflight`; продолжайте только при `safe=true`.
38
- 2. Установите exact `codex-workflow-v2@2.0.0-beta.13` без диапазона и измените только
60
+ 2. Установите exact `codex-workflow-v2@2.0.0-beta.13.1` без диапазона и измените только
39
61
  `package.json` и lock-файл.
40
62
  3. Новой repository-local версией подтвердите совпадение declared, locked и installed
41
- `2.0.0-beta.13`, прежний `projectId`, protocol/schema `2/2`, затем выполните `handshake`,
63
+ `2.0.0-beta.13.1`, прежний `projectId`, protocol/schema `2/2`, затем выполните `handshake`,
42
64
  `doctor`, компактный `status` и `next`.
43
65
  4. Обновите персональный `codex-workflow-gateway` только штатным installer из установленного
44
66
  exact пакета и продолжайте работу в новом чате, который загрузит новую skill-инструкцию.
@@ -614,8 +636,16 @@ title в registry readback и применяйте только возвращё
614
636
  быть уникален и содержать exact `#NNN`, membership ordinal и ID. Input должен состоять из
615
637
  TaskContextPacket; допустима только добавленная Codex App служебная `codex_delegation`-обёртка с
616
638
  `source_thread_id`, но не parent turns или transcript. Если title отсутствует или нормализован
617
- неверно, переименуйте и перепроверьте. Ошибка `create_thread` допускает один
618
- последовательный retry после проверки списка, но не разрешает fallback на `fork_thread`.
639
+ неверно, переименуйте и перепроверьте. Pending `clientThreadId`, тайм-аут или отсутствие в
640
+ `list_threads` не доказывают, что создание не состоялось, и не разрешают повторный `create_thread`.
641
+ До первого вызова сохраните `dispatch-begin`; после него используйте `dispatch-result/status`,
642
+ поиск коррелированного сеанса и `dispatch-observe` с фактическим `read_thread`. На одну
643
+ резервацию выдаётся только одно разрешение создания. Не обходите его новой резервацией или fork.
644
+ Полный контракт восстановления, сохранения supervisor/cursor и явного выбора `model`/`thinking`
645
+ по роли, фазе и сложности находится в
646
+ `plugins/codex-workflow-gateway/references/chat-dispatch.md`. Выбор модели требует соответствующего
647
+ поручения пользователя и актуального списка поддерживаемых пар на целевом host; нельзя молча
648
+ наследовать дорогую конфигурацию координатора или снижать уровень независимого аудита.
619
649
  Создавайте или переиспользуйте Task-чат непосредственно перед dispatch этой Task, а не как пустой
620
650
  placeholder для всего membership; `T<NN>` берите только из утверждённого membership order.
621
651
 
@@ -1,13 +1,34 @@
1
- # V2 beta.13 Validation Report
1
+ # V2 beta.13.1 Validation Report
2
2
 
3
- Release candidate `2.0.0-beta.13` was validated during 2026-09-02--03 (Europe/Moscow) with
3
+ Release candidate `2.0.0-beta.13.1` was validated during 2026-09-02--03 (Europe/Moscow) with
4
4
  Node.js 24.17.0.
5
5
 
6
+ ## beta.13.1 post-publication compatibility correction
7
+
8
+ After published beta.13 was installed dependency-only into the clean Signal `main` checkout,
9
+ declared, locked and installed versions and registry integrity matched, but the first compact
10
+ `status` failed before navigation. The loader had applied the new structural production-edge rule
11
+ to the first markerless beta.12.19 PRA for `TASK-01M1B79C660YMNSRRZ236NTR1T`; that historical Task
12
+ contains neither `requiresProductionEdges` nor `productionEdges`. This was a runtime compatibility
13
+ defect, not corrupt Signal state.
14
+
15
+ beta.13.1 makes the authority prospective and Plan-bound. New ordinary and atomic
16
+ corrective-replan PRA writers persist one hash-chained marker. Stored structural validation runs only
17
+ for the current Plan when either that marker or the new Task fields establish the boundary.
18
+ Markerless pre-authority events remain hash/shape validated and readable, while marker-bearing
19
+ current events still fail closed if Task structural fields are removed. A source-built read-only
20
+ probe against the untouched real Signal external state changed the exact failing observation into
21
+ the expected `project-memory reconcile` route with the retained-historical frozen-M3 cancellation
22
+ option. The focused production-edge and corrective-replan executor suites passed `14/14` before
23
+ the full release gate. The compatibility gate does not claim signed provenance against a privileged
24
+ rewrite of the entire local Task and self-hashed chain; it proves ordinary read compatibility and
25
+ fail-closed partial mismatch within the existing trusted-local-state model.
26
+
6
27
  ## Automated release evidence
7
28
 
8
29
  - A clean `npm ci` completed from the exact lockfile. A network-enabled `npm audit --json` reported
9
30
  zero vulnerabilities at every severity across all eight installed dependencies.
10
- - `npm run validate` passed typecheck and `408/408` sequential tests with no failures, skips,
31
+ - `npm run validate` passed typecheck and `409/409` sequential tests with no failures, skips,
11
32
  cancellations or todos in 2,761,796.900458 ms.
12
33
  - `npm run test:signal-t10-check-support-e2e` passed `8/8` after the final clean install in
13
34
  203,155.332125 ms. It covers an impossible selector-less check, machine-derived support scope,
@@ -20,7 +41,7 @@ Node.js 24.17.0.
20
41
  recovers an accidental rebind, replans and completes the consolidated guarded Step.
21
42
  - `npm run test:signal-t04-recovery` passed `11/11` in 22,021.439625 ms. It preserves only exact
22
43
  reviewed Step provenance and rejects pending, corrupt, unrelated or stale recovery evidence.
23
- - `npm run pack:check` produced the exact `2.0.0-beta.13` tarball with 309 files, package size
44
+ - `npm run pack:check` produced the exact `2.0.0-beta.13.1` tarball with 309 files, package size
24
45
  1.2 MB and unpacked size 4.8 MB. It includes the shared gateway-handshake module and the
25
46
  hash-verifiable reviewer runtime build manifest.
26
47
  - `npm run smoke:downstream` packed the release, installed it into an empty project and returned
@@ -28,7 +49,7 @@ Node.js 24.17.0.
28
49
  network-enabled invocation passed.
29
50
  - `npm run plugin:check`, `npm run docs:pdf:check`, `npm run typecheck` and `git diff --check` all
30
51
  passed. The PDF checker reported no stale generated document. `npm run release:check` passed
31
- `103/103` tests in 300,945.515375 ms and returned the exact package/version assertion.
52
+ `104/104` tests in 298,521.790541 ms and returned the exact package/version assertion.
32
53
 
33
54
  ## Release-candidate regressions found and closed
34
55
 
@@ -92,8 +113,8 @@ stale nearer-copy regressions expanded the complete suite.
92
113
  A real native reviewer preflight then exposed an API-level Structured Output incompatibility: every
93
114
  declared object property must also be present in `required`. The reviewer schema now makes nullable
94
115
  optional semantics explicit, while the semantic parser still rejects absent or contradictory
95
- cause/plan-conflict evidence. The complete suite consequently reached `408/408`, and the expanded
96
- release check reached `103/103`.
116
+ cause/plan-conflict evidence. The complete suite consequently reached `409/409`, and the expanded
117
+ release check reached `104/104`.
97
118
 
98
119
  The same real-agent exercise corrected the release proof boundary without weakening Core. A nested
99
120
  `codex exec` reviewer is not treated as independent production evidence: the Coordinator stops at a
@@ -154,8 +175,8 @@ mutation. This changes release-evidence interpretation only; it grants no lifecy
154
175
  - This report does not claim commit/tag/push, npm publication, installation into Signal or Milestone
155
176
  4 readiness until those operations receive exact readback.
156
177
 
157
- Confidence is high for package behavior and the stated compatibility boundary: the final `408/408`
158
- run, `103/103` release check, four Signal-shaped E2E suites, package/downstream smoke, CPU-saturation,
178
+ Confidence is high for package behavior and the stated compatibility boundary: the final `409/409`
179
+ run, `104/104` release check, four Signal-shaped E2E suites, package/downstream smoke, CPU-saturation,
159
180
  warm-cache and fail-closed negative cases agree. Live Signal readiness remains conditional on
160
181
  publication, exact repository-local installation, safe
161
182
  closure of the frozen Milestone 3 authority and a fresh read-only `status`/`next` observation.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-workflow-v2",
3
- "version": "2.0.0-beta.13",
3
+ "version": "2.0.0-beta.13.10",
4
4
  "description": "Requirements-first Codex development workflow with local state and explicit Git ownership.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -68,6 +68,7 @@
68
68
  },
69
69
  "devDependencies": {
70
70
  "@types/node": "24.10.1",
71
+ "codex-workflow-source-beta136": "npm:codex-workflow-v2@2.0.0-beta.13.6",
71
72
  "typescript": "5.9.3"
72
73
  },
73
74
  "license": "MIT"
@@ -0,0 +1,204 @@
1
+ # Durable App dispatch and explicit model selection
2
+
3
+ This is an App orchestration journal, not Workflow authority. It does not call the App, approve
4
+ Git writes, renew grants, mint credentials, or replace Core status/next. All commands below use
5
+ `node <exact-package>/plugins/codex-workflow-gateway/scripts/chat-registry.mjs` and the existing
6
+ 24-hex Workflow `--project-id`. The App project ID is a separate field.
7
+
8
+ ## One reservation, one creation attempt
9
+
10
+ `allocate` reuses the same non-abandoned role/entity/membership/attempt reservation. Task and
11
+ Coordinator allocations also reuse it when a caller changes the attempt number. Review attempts
12
+ advance only after the actual Workflow review cycle advances. Never invent a new attempt or
13
+ reservation to bypass unresolved creation. Existing v1 registries remain readable; legacy bound
14
+ threads remain usable with explicit model/thinking arguments from the same policy; `model-select`
15
+ and `supervision-record` currently require a tracked dispatch and do not retrofit legacy evidence.
16
+ Legacy unbound reservations may have already created a chat: reconcile
17
+ those using real App/source evidence before using the new dispatch flow.
18
+
19
+ 1. Save the closed context packet to a private local file. Do not include bearer credentials,
20
+ parent transcript, or approval narratives. Prepare a private dispatch request JSON:
21
+
22
+ ```json
23
+ {
24
+ "repositoryRoot": "/absolute/canonical/repository",
25
+ "appProjectId": "project-id-from-list-projects",
26
+ "hostId": "local",
27
+ "promptFile": "/private/tmp/task-context.txt",
28
+ "modelRequest": {
29
+ "phase": "planning",
30
+ "complexity": "standard",
31
+ "highRisk": false,
32
+ "rationale": "New multi-file implementation plan with established requirements.",
33
+ "availableModels": [
34
+ {"id": "gpt-5.6-sol", "reasoningEfforts": ["low", "medium", "high", "xhigh", "max", "ultra"]}
35
+ ]
36
+ }
37
+ }
38
+ ```
39
+
40
+ Populate `availableModels` from the destination App tool's actual model/effort contract, not
41
+ this example, the parent's settings, API pricing pages, or a guessed alias. Explicit user
42
+ authorization to select models is required; journal input is not user authorization.
43
+ 2. Run `dispatch-begin --reservation-id ID --file request.json` **before** `create_thread`.
44
+ Save its complete output to a mode-600 file. It atomically persists a creation marker, packet
45
+ hashes, repository binding and requested model selection, then returns `createAllowed:true`
46
+ and exact `createArgs` including `model` and App field `thinking`.
47
+ 3. Only the process receiving that one permission may make **one** `create_thread(createArgs)`
48
+ call. A second begin, even after restart or timeout, returns `createAllowed:false` and no
49
+ create arguments. Do not reissue the external call after a lost/ambiguous response. The marker
50
+ prepended to the packet is routing provenance, not parent history.
51
+ 4. Save the full App result locally, normalize its successful tool text JSON to
52
+ `{"result":{"clientThreadId":"client-new-thread:...","hostId":"local"}}` or
53
+ `{"result":{"threadId":"actual-uuid","hostId":"local"}}`, and run `dispatch-result`.
54
+ Preserve raw evidence separately. Never parse truncated displayed stdout as the full receipt.
55
+ Invalid JSON cannot change the journal. A pending client ID is never a usable thread ID.
56
+ 5. Use `dispatch-status` to resume. Missing `list_threads` results are not proof of failure.
57
+ If the actual ID is unavailable, identify candidate rollout files from creation-time/worktree
58
+ evidence and run `dispatch-discover --file candidates.json`, where the file is
59
+ `{"sessionFiles":["/absolute/rollout.jsonl"]}`. The helper reads only supplied files, checks
60
+ actual session metadata, exact original dispatched prompt (including the App's routing XML),
61
+ and the Git common directory. It ignores guardian/subagent sessions and unrelated prompts.
62
+ It prints candidate IDs/paths only, never transcripts or reasoning. Use bounded candidate
63
+ lists, not vault searches. Malformed, oversized or partially written files need a later fresh
64
+ read; they never authorize another creation.
65
+ 6. Confirm a correlated candidate using `read_thread`. Save its full response as
66
+ `{"observation": <parsed read_thread JSON>}` and run `dispatch-observe`. It checks actual UUID,
67
+ host, repository/worktree and App project when supplied. One candidate still requires App
68
+ readback; several candidates produce a duplicate conflict and require explicit disposition,
69
+ not arbitrary selection. After confirming one canonical child, inspect every other candidate,
70
+ reconcile any work it performed, and archive only idle duplicates. Record
71
+ `dispatch-resolve-duplicates` with `canonicalThreadId` and `dispositions`, one object per duplicate:
72
+ `{threadId, observation: <read_thread JSON>, archiveResult: {threadId, archived: true}}`.
73
+ Preserve the actual archive tool receipt; never fabricate it. Repeat canonical readback and bind.
74
+ Candidate history is retained and no creation permit is restored. This is a local evidence
75
+ check, not independent App attestation.
76
+ 7. Run ordinary title `readback`/rename until exact match. After any rename, repeat
77
+ `dispatch-observe` with fresh App readback, then `readback` and `bind`. Binding a tracked
78
+ dispatch requires the same actual ID, host and observed title. Rebinding it to another child,
79
+ binding a client ID or sharing one child between reservations is rejected.
80
+ 8. Run `supervision-record --file report.json` with `threadId`, `ownerThreadId`, `state`
81
+ (`active|attention|completed`), `cursor` and `nextAction`. Persist significant wait boundaries;
82
+ only that supervisor waits for this child. The journal stores routing state, not a Workflow
83
+ verdict. Do not put secrets, CREFs or confirmation codes in it. On restart, read the child and
84
+ fresh Core status/next before continuing. Worker reports stay local; the coordinator pulls.
85
+
86
+ A crash between durable begin and actual submission is deliberately ambiguous. There is no
87
+ App idempotency-key API here, so this provides **at most one create permit per reservation**,
88
+ not an exactly-once guarantee. Never clear the marker, abandon it, or expire it by time to retry.
89
+ If no positive creation evidence can be found, report that exact unresolved App operation. A
90
+ permission denial is a separate real gate; do not reroute it through another chat. Fresh user
91
+ approval does not establish that an ambiguous prior creation never happened.
92
+
93
+ ## Model matrix
94
+
95
+ The versioned policy is `scripts/chat-model-policy.mjs`. It expresses a conservative relative
96
+ cost/latency preference, not measured savings or guaranteed account availability:
97
+
98
+ | Work | Preferred model | App thinking | Compatible fallback |
99
+ | --- | --- | --- | --- |
100
+ | Routine mechanical transitions, formatting, retrieval | gpt-5.4-mini | low | gpt-5.6-luna / low |
101
+ | Coordinator supervision; small implementation | gpt-5.6-luna | medium | gpt-5.6-terra / medium |
102
+ | Standard implementation | gpt-5.6-terra | medium | gpt-5.6-sol / medium |
103
+ | Task planning | gpt-5.6-sol | medium | gpt-6-astra / medium |
104
+ | Routine Step review | gpt-5.6-terra | medium | gpt-5.6-sol / medium |
105
+ | Standard Step review, final review, plan/corrective audit | gpt-5.6-sol | high | gpt-6-astra / high |
106
+ | Complex work or high risk, any role | gpt-6-astra | high | gpt-5.6-sol / high |
107
+
108
+ `routine` means a small, well-specified change or mechanical action with an existing check;
109
+ `standard` is ordinary multi-file work; `complex` covers new architecture, unresolved concurrency,
110
+ recovery/provenance or distributed state. Mark `highRisk` for authorization, security-sensitive
111
+ paths, data-loss exposure or irreversible migrations. The coordinator records the concrete
112
+ rationale; classification is a human/agent judgment, not an automatic risk detector. Unknown
113
+ complexity is not routine. Review/audit role floors override a falsely mechanical phase. No
114
+ automatic xhigh/max/ultra, and no escalation merely because a review failed or a tool timed out.
115
+
116
+ The policy chooses only a listed supported pair. If neither preferred nor fallback pair is
117
+ available, stop selection rather than silently inheriting the coordinator or lowering the review
118
+ floor. API docs explain the reasoning/latency tradeoff, while App availability and accepted field
119
+ names come from the live App tool contract:
120
+ https://developers.openai.com/api/docs/guides/latest-model
121
+
122
+ For a phase change in an existing bound chat, call `model-select` with its same `threadId` and
123
+ fresh `modelRequest`; copy the returned `followUpArgs` into `send_message_to_thread` with the
124
+ closed follow-up prompt. For example, planning uses Sol/medium, implementation Terra/medium,
125
+ then mechanical lifecycle work Mini/low. Do not create another Task just to switch model.
126
+ Keep the previous selection unless the phase/risk/scope changes materially. The journal records
127
+ requested settings; tool acceptance/runtime readback, when available, is required to claim the
128
+ actual model used. A model change never changes role, scope, credentials or approval authority.
129
+
130
+ ## Execution context before product writes
131
+
132
+ `dispatch-begin` accepts optional `executionMode: "local" | "worktree"` (default `worktree`).
133
+ Choose local only for an explicit user request to execute in the saved checkout. The observed
134
+ child checkout, not an absolute path copied from the parent's prompt, is the write destination.
135
+ `dispatch-observe` records it and refuses silent movement of a bound child.
136
+
137
+ Before the first write, and after any branch/cwd change, use read-only `dispatch-context-check`
138
+ with a fresh App observation, `writeRoot`, and `expectedBranch` from the current Core Task.
139
+ Require `matched=true`, then refresh Core next and writer authority. Mismatch means reconcile the
140
+ same Worker context; it never permits another create, an indirect write or an automatic handoff.
141
+ A matched context does not authorize external operations. See packaged `docs/change-model.md`.
142
+
143
+ ### Existing legacy bindings
144
+
145
+ `dispatch-context-check` also accepts an already bound legacy entry with no dispatch marker.
146
+ Supply the exact current Task `repositoryRoot` in addition to the fresh actual Worker observation,
147
+ `writeRoot`, and `expectedBranch`. The check verifies the bound thread/host, common Git repository,
148
+ actual checkout/write root and Task branch without changing the registry. It reports
149
+ `contextBinding=legacy-current-observation` and `historicalCheckoutVerified=false`: no historical
150
+ creation marker or checkout provenance is invented. It never enables another create permit.
151
+ This observation does not move a chat, authorize a write or reconcile a tracked dispatch whose
152
+ previous checkout changed; those remain explicit App/context operations followed by fresh checks.
153
+
154
+ ### Explicit App handoff reconciliation
155
+
156
+ An App handoff can return a new destination thread ID while retaining the task history.
157
+ `bind` still rejects replacing a bound child. After the App operation succeeds, use the
158
+ separate `dispatch-handoff-reconcile --reservation-id ... --file ... --project-id ...` route:
159
+
160
+ ```json
161
+ {
162
+ "sourceThreadId": "actual-source-thread-uuid-from-the-handoff-call",
163
+ "sourceHostId": "local",
164
+ "repositoryRoot": "/absolute/repository-from-fresh-Task",
165
+ "expectedBranch": "exact-task-branch",
166
+ "receipt": {
167
+ "operationId": "actual-operation-id",
168
+ "revision": 12,
169
+ "status": "success",
170
+ "destinationThreadId": "actual-destination-thread-uuid",
171
+ "destinationHostId": "local",
172
+ "destinationCwd": "/absolute/destination-checkout",
173
+ "threadTitle": "exact-current-bound-title"
174
+ },
175
+ "observation": { "thread": {
176
+ "id": "actual-destination-thread-uuid",
177
+ "hostId": "local",
178
+ "kind": "codex",
179
+ "cwd": "/absolute/destination-checkout",
180
+ "title": "exact-current-bound-title"
181
+ } }
182
+ }
183
+ ```
184
+
185
+ Copy the complete successful `get_handoff_status` receipt, including any extra returned fields,
186
+ and obtain a fresh destination `read_thread`. Preserve the source `handoff_thread` tool call:
187
+ its source ID is supplied separately because the result need not contain it. Pending, failed,
188
+ cancelled or inconsistent results cannot change the registry. The destination must match the
189
+ bound title, actual Git repository and current Task branch, and cannot belong to another entry.
190
+
191
+ This route changes only the existing reservation's current thread/host and, for tracked dispatch,
192
+ current execution context. An append-only `handoffHistory` retains the receipt, source and prior
193
+ dispatch snapshot; the original creation marker is never fabricated for legacy entries. Existing
194
+ observations and selection history are preserved. A tracked supervisor's old cursor is cleared
195
+ so it must observe the destination again. No create permit, grant, Task claim or lifecycle
196
+ transition is issued. Ordinary `dispatch-observe` still rejects an unexplained checkout change.
197
+ An exact retry of the latest handoff leaves registry bytes unchanged; changed receipts or replay
198
+ of a superseded handoff are rejected. Refresh Core status/next and writer authority after handoff.
199
+
200
+ These caller-supplied App results are coherence evidence, not cryptographic proof of origin or
201
+ external write authority. The coordinator must obtain genuine tool results and independently
202
+ check retained history and the safe writer boundary. The package does not execute a handoff,
203
+ verify arbitrary transcript continuity, or authorize writes merely because reconciliation passes.
204
+ Only destinations readable on the checking host with the same Git common directory are supported.
@@ -56,10 +56,21 @@
56
56
  A provenance recovery recorded after the final context-refresh audit may explain exactly one
57
57
  additional Task revision only when it belongs to that verified Git chain. Any unexplained
58
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.
59
66
  - `milestone progress --id <MS-ID>` is a read-only projection and the sole source for Coordinator
60
67
  progress tables. It preserves cancelled/replacement Tasks as distinct membership rows.
61
68
  - `scripts/chat-registry.mjs` atomically allocates project-monotonic `#NNN`, builds all six title
62
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.
63
74
 
64
75
  ## Handshake
65
76