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
@@ -0,0 +1,327 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { types as utilTypes } from 'node:util';
5
+ import type { TaskState } from '../contracts.js';
6
+ import { WorkflowError } from '../errors.js';
7
+ import { prepareTaskCorrectiveYield, readTaskC1Posture } from '../alpha6/handoff.js';
8
+ import { readCorrectivePlanningAudit } from '../alpha6/failed-step-planning-recovery.js';
9
+ import {
10
+ findCurrentGuardedRemediationPosture,
11
+ deriveCurrentCauseDecision,
12
+ readCorrectiveDecisionEvents,
13
+ readRemediationEvents,
14
+ } from '../alpha6/remediation.js';
15
+ import {
16
+ identifyCorrectiveReplanPosture,
17
+ type CorrectiveReplanPosture,
18
+ } from '../lifecycle/corrective-replan.js';
19
+ import { hashCanonical } from '../lifecycle/fingerprint.js';
20
+ import { deepFreeze } from '../lifecycle/immutable.js';
21
+ import type { FileStateStore } from './store.js';
22
+ import {
23
+ CoreTaskOperationLockManager,
24
+ WriterLockManager,
25
+ type CoreTaskOperationHandle,
26
+ type WriterLeaseHandle,
27
+ } from './lock.js';
28
+ import {
29
+ CorrectiveYieldTaskTransactionStore,
30
+ type CorrectiveYieldTaskTransactionJournal,
31
+ } from './corrective-yield-transaction.js';
32
+
33
+ const TRANSITION = 'task.coordination.corrective-yield' as const;
34
+ const HASH = /^[a-f0-9]{64}$/;
35
+
36
+ export type CorrectiveYieldCrashBoundary =
37
+ | 'after-intent'
38
+ | 'after-applying-phase'
39
+ | 'after-handoff-event'
40
+ | 'after-handoff-phase'
41
+ | 'after-lock-transfer'
42
+ | 'after-lock-phase'
43
+ | 'after-published-phase'
44
+ | 'after-domain-readback'
45
+ | 'after-completed-phase'
46
+ | 'after-lock-release'
47
+ | 'after-terminal-readback';
48
+
49
+ export interface ExecuteCorrectiveYieldInput {
50
+ readonly projectId: string;
51
+ readonly taskId: string;
52
+ readonly expectedTaskRevision: number;
53
+ readonly actor: string;
54
+ readonly writerToken: string;
55
+ readonly reason: string;
56
+ }
57
+
58
+ export interface CorrectiveYieldExecutionResult {
59
+ readonly kind: 'corrective-yield-execution-result';
60
+ readonly disposition: 'yielded' | 'recovered' | 'replayed';
61
+ readonly taskId: string;
62
+ readonly transactionId: string;
63
+ readonly yieldEventHash: string;
64
+ readonly resultSha256: string;
65
+ }
66
+
67
+ export interface CorrectiveYieldExecutor {
68
+ execute(input: ExecuteCorrectiveYieldInput): CorrectiveYieldExecutionResult;
69
+ recover(input: { taskId: string; transactionId: string }): CorrectiveYieldExecutionResult;
70
+ }
71
+
72
+ export function createCorrectiveYieldExecutor(options: {
73
+ store: FileStateStore;
74
+ projectId: string;
75
+ now?: () => Date;
76
+ faultInjector?: (boundary: CorrectiveYieldCrashBoundary) => void;
77
+ }): CorrectiveYieldExecutor {
78
+ const now = options.now ?? (() => new Date());
79
+ const projectRoot = options.store.projectRoot(options.projectId);
80
+ const locksRoot = options.store.lockRoot(options.projectId);
81
+ const writerLocks = new WriterLockManager(locksRoot, now, options.store.root);
82
+ const coreLocks = new CoreTaskOperationLockManager(locksRoot, now, options.store.root);
83
+ const fault = (boundary: CorrectiveYieldCrashBoundary): void => options.faultInjector?.(boundary);
84
+ const transactionStore = (taskId: string) => new CorrectiveYieldTaskTransactionStore({
85
+ taskRoot: options.store.taskRoot(options.projectId, taskId),
86
+ locksRoot,
87
+ trustedRoot: options.store.root,
88
+ now,
89
+ });
90
+
91
+ const recover = (input: { taskId: string; transactionId: string }): CorrectiveYieldExecutionResult => {
92
+ assertExact(input, ['taskId', 'transactionId'], 'Corrective-yield recovery input');
93
+ assertHash(input.transactionId, 'Corrective-yield transaction id');
94
+ const transactions = transactionStore(input.taskId);
95
+ const journal = transactions.read(input.transactionId);
96
+ if (journal.taskId !== input.taskId || journal.projectId !== options.projectId) {
97
+ throw new WorkflowError('STATE_CONFLICT', 'Corrective-yield recovery identity mismatch.');
98
+ }
99
+ const lockFile = path.join(locksRoot, `${journal.taskId}.json`);
100
+ if (journal.phase === 'completed' && !existsSync(lockFile)) {
101
+ return result(journal, transactions.terminalReadback(journal.transactionId), 'replayed');
102
+ }
103
+ if (!existsSync(lockFile) && !transactions.handoffIsPostimage(journal)) {
104
+ throw new WorkflowError('STATE_CONFLICT', 'Corrective-yield writer lease vanished before its handoff effect.');
105
+ }
106
+ const handle = coreLocks.acquireYieldRecovery({
107
+ entityId: journal.taskId,
108
+ operationId: journal.transactionId,
109
+ transitionId: TRANSITION,
110
+ expectedWriterContentSha256: journal.writerLeaseContentSha256,
111
+ expectedWriterTokenSha256: journal.writerLeaseTokenSha256,
112
+ });
113
+ let released = false;
114
+ try {
115
+ const completed = driveCore(transactions, handle, journal.transactionId, fault);
116
+ coreLocks.release(handle);
117
+ released = true;
118
+ fault('after-lock-release');
119
+ const resultSha256 = transactions.terminalReadback(journal.transactionId);
120
+ fault('after-terminal-readback');
121
+ return result(completed, resultSha256, journal.phase === 'completed' ? 'replayed' : 'recovered');
122
+ } finally {
123
+ if (!released) {
124
+ // A failed post-intent operation deliberately retains its Core mutex until explicit stale recovery.
125
+ }
126
+ }
127
+ };
128
+
129
+ const execute = (input: ExecuteCorrectiveYieldInput): CorrectiveYieldExecutionResult => {
130
+ assertExact(input, ['actor', 'expectedTaskRevision', 'projectId', 'reason', 'taskId', 'writerToken'], 'Corrective-yield input');
131
+ if (input.projectId !== options.projectId || !Number.isSafeInteger(input.expectedTaskRevision) || input.expectedTaskRevision < 1
132
+ || typeof input.actor !== 'string' || !input.actor.trim() || input.actor.length > 256
133
+ || typeof input.writerToken !== 'string' || !input.writerToken
134
+ || typeof input.reason !== 'string' || !input.reason.trim() || input.reason.length > 2048) {
135
+ throw new WorkflowError('INVALID_ARGUMENT', 'Corrective-yield input is invalid.');
136
+ }
137
+ const task = options.store.readTask(options.projectId, input.taskId);
138
+ if (task.revision !== input.expectedTaskRevision) throw new WorkflowError('STATE_CONFLICT', 'Corrective-yield Task revision is stale.');
139
+ const posture = requireCorrectiveReplanPosture(options.store, task);
140
+ const claim = readTaskC1Posture(options.store, task);
141
+ if (claim.state !== 'claimed') throw new WorkflowError('TRANSITION_BLOCKED', 'Corrective yield requires an active C1 claim.');
142
+ const writerHandle = writerLocks.prove(task.id, input.writerToken);
143
+ const proof = writerLocks.proofBinding(writerHandle);
144
+ if (proof.owner !== input.actor.trim() || claim.claimant !== input.actor.trim()
145
+ || claim.writerLeaseTokenHash !== proof.tokenSha256) {
146
+ throw new WorkflowError('TRANSITION_BLOCKED', 'Corrective yield requires the exact claimant-owned writer lease.');
147
+ }
148
+ const transactionId = yieldExecutionKey(task, posture, claim.latestEvent.eventHash, input.actor.trim(), proof.tokenSha256, input.reason.trim());
149
+ const prepared = prepareTaskCorrectiveYield(options.store, task, {
150
+ actor: input.actor,
151
+ writerToken: input.writerToken,
152
+ reason: input.reason,
153
+ eventId: `HOF-${transactionId}`,
154
+ }, now());
155
+ const transactions = transactionStore(task.id);
156
+ const stateBytes = readFileSync(path.join(options.store.taskRoot(task.projectId, task.id), 'state.json'));
157
+ let journal = transactions.createIntent(writerHandle, {
158
+ projectId: task.projectId,
159
+ taskId: task.id,
160
+ transactionId,
161
+ taskStateSha256: sha256(stateBytes),
162
+ actor: input.actor.trim(),
163
+ writerLeaseTokenSha256: proof.tokenSha256,
164
+ writerLeaseContentSha256: proof.contentSha256,
165
+ writerLeaseExpiresAt: proof.expiresAt,
166
+ handoffPostimage: prepared.postimage,
167
+ });
168
+ fault('after-intent');
169
+ journal = transactions.advanceWithWriter(writerHandle, transactionId, 'intent', journal.phaseRevision, 'applying', 0);
170
+ fault('after-applying-phase');
171
+ transactions.applyHandoffWithWriter(writerHandle, transactionId);
172
+ fault('after-handoff-event');
173
+ journal = transactions.advanceWithWriter(writerHandle, transactionId, 'applying', journal.phaseRevision, 'applying', 1);
174
+ fault('after-handoff-phase');
175
+ const coreHandle = coreLocks.transferFromWriter(writerHandle, {
176
+ entityId: task.id,
177
+ operationId: transactionId,
178
+ transitionId: TRANSITION,
179
+ });
180
+ fault('after-lock-transfer');
181
+ let released = false;
182
+ try {
183
+ journal = transactions.advanceWithCore(coreHandle, transactionId, 'applying', journal.phaseRevision, 'applying', 2);
184
+ fault('after-lock-phase');
185
+ const completed = driveCore(transactions, coreHandle, transactionId, fault);
186
+ coreLocks.release(coreHandle);
187
+ released = true;
188
+ fault('after-lock-release');
189
+ const resultSha256 = transactions.terminalReadback(transactionId);
190
+ fault('after-terminal-readback');
191
+ return result(completed, resultSha256, 'yielded');
192
+ } finally {
193
+ if (!released) {
194
+ // Preserve the exact operation owner for explicit stale recovery after a post-intent failure.
195
+ }
196
+ }
197
+ };
198
+
199
+ return deepFreeze({ execute, recover });
200
+ }
201
+
202
+ function driveCore(
203
+ transactions: CorrectiveYieldTaskTransactionStore,
204
+ handle: CoreTaskOperationHandle,
205
+ transactionId: string,
206
+ fault: (boundary: CorrectiveYieldCrashBoundary) => void,
207
+ ): CorrectiveYieldTaskTransactionJournal {
208
+ let journal = transactions.read(transactionId);
209
+ if (journal.phase === 'intent') {
210
+ journal = transactions.advanceWithCore(handle, transactionId, 'intent', journal.phaseRevision, 'applying', 0);
211
+ fault('after-applying-phase');
212
+ }
213
+ if (journal.phase === 'applying' && journal.nextTargetOrdinal === 0) {
214
+ transactions.applyHandoffWithCore(handle, transactionId);
215
+ fault('after-handoff-event');
216
+ journal = transactions.advanceWithCore(handle, transactionId, 'applying', journal.phaseRevision, 'applying', 1);
217
+ fault('after-handoff-phase');
218
+ }
219
+ if (journal.phase === 'applying' && journal.nextTargetOrdinal === 1) {
220
+ journal = transactions.advanceWithCore(handle, transactionId, 'applying', journal.phaseRevision, 'applying', 2);
221
+ fault('after-lock-phase');
222
+ }
223
+ if (journal.phase === 'applying' && journal.nextTargetOrdinal === 2) {
224
+ journal = transactions.advanceWithCore(handle, transactionId, 'applying', journal.phaseRevision, 'published-pending-readback', 2);
225
+ fault('after-published-phase');
226
+ }
227
+ if (journal.phase === 'published-pending-readback') {
228
+ const resultSha256 = transactions.domainReadback(handle, transactionId);
229
+ fault('after-domain-readback');
230
+ journal = transactions.advanceWithCore(handle, transactionId, 'published-pending-readback', journal.phaseRevision, 'completed', 2, resultSha256);
231
+ fault('after-completed-phase');
232
+ }
233
+ return journal;
234
+ }
235
+
236
+ type YieldPosture = CorrectiveReplanPosture & { readonly remediationEventHash?: string };
237
+
238
+ function requireCorrectiveReplanPosture(store: FileStateStore, task: TaskState): YieldPosture {
239
+ if (task.steps.some((step) => step.status === 'in_progress')) {
240
+ throw new WorkflowError('TRANSITION_BLOCKED', 'Corrective yield requires no running Step.');
241
+ }
242
+ const audit = readCorrectivePlanningAudit(store, task);
243
+ if (!audit) throw new WorkflowError('TRANSITION_BLOCKED', 'Corrective yield requires the current guarded Plan Risk Audit.');
244
+ const decisions = readCorrectiveDecisionEvents(store, task);
245
+ const classified = findCurrentGuardedRemediationPosture(store, task, audit);
246
+ const posture = classified?.posture === 'replan-required'
247
+ ? classified
248
+ : identifyCorrectiveReplanPosture(task, audit.reviewRequiredStepIds, decisions, readRemediationEvents(store, task));
249
+ if (posture?.posture === 'replan-required' && !posture.correctiveDecision
250
+ && ['ready', 'needs_fix'].includes(task.status)
251
+ && task.steps.find(step => step.id === posture.stepId)?.status === 'failed') {
252
+ const history = readRemediationEvents(store, task).filter(event => event.stepId === posture.stepId);
253
+ if (deriveCurrentCauseDecision(history) === 'root-cause-replan') {
254
+ return { ...posture, remediationEventHash: history.at(-1)!.eventHash };
255
+ }
256
+ }
257
+ if (!posture || posture.posture !== 'replan-required' || !posture.correctiveDecision) {
258
+ throw new WorkflowError('TRANSITION_BLOCKED', 'Corrective yield requires one current replan-required decision.');
259
+ }
260
+ return posture;
261
+ }
262
+
263
+ function yieldExecutionKey(
264
+ task: TaskState,
265
+ posture: YieldPosture,
266
+ claimEventHash: string,
267
+ actor: string,
268
+ writerLeaseTokenSha256: string,
269
+ reason: string,
270
+ ): string {
271
+ return hashCanonical({
272
+ domain: 'codex-workflow/corrective-yield-execution-key/v1',
273
+ transitionId: TRANSITION,
274
+ taskId: task.id,
275
+ taskRevision: task.revision,
276
+ planHash: task.planHash,
277
+ guardedStepId: posture.stepId,
278
+ correctiveDecisionEventId: posture.correctiveDecision?.eventId,
279
+ correctiveDecisionHash: posture.correctiveDecision?.eventHash,
280
+ ...(posture.remediationEventHash ? { remediationEventHash: posture.remediationEventHash } : {}),
281
+ claimEventHash,
282
+ actor,
283
+ writerLeaseTokenSha256,
284
+ reason,
285
+ });
286
+ }
287
+
288
+ function result(
289
+ journal: CorrectiveYieldTaskTransactionJournal,
290
+ resultSha256: string,
291
+ disposition: CorrectiveYieldExecutionResult['disposition'],
292
+ ): CorrectiveYieldExecutionResult {
293
+ return deepFreeze({
294
+ kind: 'corrective-yield-execution-result',
295
+ disposition,
296
+ taskId: journal.taskId,
297
+ transactionId: journal.transactionId,
298
+ yieldEventHash: journal.handoffTarget.resultEventHash,
299
+ resultSha256,
300
+ });
301
+ }
302
+
303
+ function assertExact(value: unknown, keys: string[], label: string): asserts value is Record<string, unknown> {
304
+ if (!value || typeof value !== 'object' || Array.isArray(value) || utilTypes.isProxy(value)
305
+ || Object.getPrototypeOf(value) !== Object.prototype) {
306
+ throw new WorkflowError('INVALID_ARGUMENT', `${label} must be a plain object.`);
307
+ }
308
+ const descriptors = Object.getOwnPropertyDescriptors(value);
309
+ const ownKeys = Reflect.ownKeys(value);
310
+ if (ownKeys.some((key) => typeof key !== 'string')
311
+ || Object.values(descriptors).some((descriptor) => !('value' in descriptor) || descriptor.enumerable !== true)) {
312
+ throw new WorkflowError('INVALID_ARGUMENT', `${label} must contain only enumerable data properties.`);
313
+ }
314
+ const actual = Object.keys(descriptors).sort();
315
+ const expected = [...keys].sort();
316
+ if (actual.length !== expected.length || actual.some((key, index) => key !== expected[index])) {
317
+ throw new WorkflowError('INVALID_ARGUMENT', `${label} has unknown or missing fields.`);
318
+ }
319
+ }
320
+
321
+ function assertHash(value: unknown, label: string): asserts value is string {
322
+ if (typeof value !== 'string' || !HASH.test(value)) throw new WorkflowError('INVALID_ARGUMENT', `${label} must be lowercase SHA-256.`);
323
+ }
324
+
325
+ function sha256(value: Buffer | string): string {
326
+ return createHash('sha256').update(value).digest('hex');
327
+ }