codex-workflow-v2 2.0.0-beta.13.8 → 2.0.0-beta.14

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 (281) hide show
  1. package/README.md +27 -388
  2. package/dist/reviewer-runtime-build.json +96 -32
  3. package/dist/src/alpha6/adoption.d.ts +2 -0
  4. package/dist/src/alpha6/adoption.js +22 -0
  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 +47 -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/failed-step-planning-recovery.d.ts +10 -0
  19. package/dist/src/alpha6/failed-step-planning-recovery.js +93 -0
  20. package/dist/src/alpha6/failed-step-planning-recovery.js.map +1 -0
  21. package/dist/src/alpha6/literal-test-invocation.d.ts +2 -0
  22. package/dist/src/alpha6/literal-test-invocation.js +106 -0
  23. package/dist/src/alpha6/literal-test-invocation.js.map +1 -0
  24. package/dist/src/alpha6/milestone.d.ts +2 -0
  25. package/dist/src/alpha6/milestone.js +10 -1
  26. package/dist/src/alpha6/milestone.js.map +1 -1
  27. package/dist/src/alpha6/navigation-dirty-carryover.d.ts +11 -0
  28. package/dist/src/alpha6/navigation-dirty-carryover.js +130 -0
  29. package/dist/src/alpha6/navigation-dirty-carryover.js.map +1 -0
  30. package/dist/src/alpha6/plan-integrity.js +7 -5
  31. package/dist/src/alpha6/plan-integrity.js.map +1 -1
  32. package/dist/src/alpha6/plan-risk.d.ts +2 -0
  33. package/dist/src/alpha6/plan-risk.js +10 -3
  34. package/dist/src/alpha6/plan-risk.js.map +1 -1
  35. package/dist/src/alpha6/remediation.d.ts +6 -21
  36. package/dist/src/alpha6/remediation.js +161 -476
  37. package/dist/src/alpha6/remediation.js.map +1 -1
  38. package/dist/src/alpha6/root-cause-replan-carryover.d.ts +4 -1
  39. package/dist/src/alpha6/root-cause-replan-carryover.js +29 -5
  40. package/dist/src/alpha6/root-cause-replan-carryover.js.map +1 -1
  41. package/dist/src/beta1/project-transaction.d.ts +3 -1
  42. package/dist/src/beta1/project-transaction.js +6 -2
  43. package/dist/src/beta1/project-transaction.js.map +1 -1
  44. package/dist/src/checks/runner.d.ts +26 -0
  45. package/dist/src/checks/runner.js +223 -0
  46. package/dist/src/checks/runner.js.map +1 -0
  47. package/dist/src/checks/task-sync.d.ts +10 -0
  48. package/dist/src/checks/task-sync.js +41 -0
  49. package/dist/src/checks/task-sync.js.map +1 -0
  50. package/dist/src/checks/worker.d.ts +1 -0
  51. package/dist/src/checks/worker.js +154 -0
  52. package/dist/src/checks/worker.js.map +1 -0
  53. package/dist/src/cli-actions.d.ts +2 -2
  54. package/dist/src/cli-actions.js +3 -15
  55. package/dist/src/cli-actions.js.map +1 -1
  56. package/dist/src/cli.js +14 -98
  57. package/dist/src/cli.js.map +1 -1
  58. package/dist/src/contracts.d.ts +35 -32
  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/gateway-handshake.js +0 -8
  74. package/dist/src/gateway-handshake.js.map +1 -1
  75. package/dist/src/git.d.ts +3 -1
  76. package/dist/src/git.js +41 -14
  77. package/dist/src/git.js.map +1 -1
  78. package/dist/src/graph.js +25 -3
  79. package/dist/src/graph.js.map +1 -1
  80. package/dist/src/index.d.ts +1 -0
  81. package/dist/src/lifecycle/corrective-replan.js +3 -3
  82. package/dist/src/lifecycle/corrective-replan.js.map +1 -1
  83. package/dist/src/navigation-actions.d.ts +9 -0
  84. package/dist/src/navigation-actions.js +72 -0
  85. package/dist/src/navigation-actions.js.map +1 -0
  86. package/dist/src/navigation-update-artifact.d.ts +5 -0
  87. package/dist/src/navigation-update-artifact.js +227 -0
  88. package/dist/src/navigation-update-artifact.js.map +1 -0
  89. package/dist/src/navigation-update.d.ts +39 -0
  90. package/dist/src/navigation-update.js +82 -0
  91. package/dist/src/navigation-update.js.map +1 -0
  92. package/dist/src/observation.js +52 -29
  93. package/dist/src/observation.js.map +1 -1
  94. package/dist/src/observed-routes.js +5 -6
  95. package/dist/src/observed-routes.js.map +1 -1
  96. package/dist/src/pending-review-update.d.ts +0 -13
  97. package/dist/src/pending-review-update.js +1 -6
  98. package/dist/src/pending-review-update.js.map +1 -1
  99. package/dist/src/reviewer.d.ts +1 -1
  100. package/dist/src/reviewer.js +20 -17
  101. package/dist/src/reviewer.js.map +1 -1
  102. package/dist/src/runtime.d.ts +3 -0
  103. package/dist/src/runtime.js +6 -0
  104. package/dist/src/runtime.js.map +1 -0
  105. package/dist/src/state/corrective-replan-executor.d.ts +10 -0
  106. package/dist/src/state/corrective-replan-executor.js +37 -1
  107. package/dist/src/state/corrective-replan-executor.js.map +1 -1
  108. package/dist/src/state/corrective-replan-public-schema.js +15 -2
  109. package/dist/src/state/corrective-replan-public-schema.js.map +1 -1
  110. package/dist/src/state/corrective-replan-public.js +6 -5
  111. package/dist/src/state/corrective-replan-public.js.map +1 -1
  112. package/dist/src/state/corrective-replan-transaction.d.ts +1 -0
  113. package/dist/src/state/corrective-replan-transaction.js +12 -11
  114. package/dist/src/state/corrective-replan-transaction.js.map +1 -1
  115. package/dist/src/state/corrective-yield-executor.js +2 -2
  116. package/dist/src/state/corrective-yield-executor.js.map +1 -1
  117. package/dist/src/state/corrective-yield-transaction.d.ts +1 -0
  118. package/dist/src/state/corrective-yield-transaction.js +11 -10
  119. package/dist/src/state/corrective-yield-transaction.js.map +1 -1
  120. package/dist/src/state/lock.d.ts +4 -0
  121. package/dist/src/state/lock.js +21 -0
  122. package/dist/src/state/lock.js.map +1 -1
  123. package/dist/src/version.d.ts +1 -1
  124. package/dist/src/version.js +1 -1
  125. package/dist/src/version.js.map +1 -1
  126. package/dist/src/workflow-blocker-route.d.ts +8 -0
  127. package/dist/src/workflow-blocker-route.js +106 -0
  128. package/dist/src/workflow-blocker-route.js.map +1 -0
  129. package/dist/src/workflow.d.ts +48 -63
  130. package/dist/src/workflow.js +698 -1470
  131. package/dist/src/workflow.js.map +1 -1
  132. package/docs/autonomy-guardrails.md +26 -304
  133. package/docs/decisions.md +14 -112
  134. package/docs/development-flow.md +35 -238
  135. package/docs/project-memory.md +31 -50
  136. package/docs/release-app-evidence.md +190 -0
  137. package/docs/release.md +95 -363
  138. package/docs/updating-existing-project.md +19 -717
  139. package/package.json +11 -13
  140. package/plugins/codex-workflow-gateway/.codex-plugin/plugin.json +2 -2
  141. package/plugins/codex-workflow-gateway/references/chat-dispatch.md +73 -197
  142. package/plugins/codex-workflow-gateway/references/codebase-memory-routing.md +57 -0
  143. package/plugins/codex-workflow-gateway/references/protocol.md +42 -445
  144. package/plugins/codex-workflow-gateway/scripts/chat-dispatch.mjs +7 -1
  145. package/plugins/codex-workflow-gateway/scripts/chat-model-policy.mjs +10 -8
  146. package/plugins/codex-workflow-gateway/scripts/chat-registry.mjs +23 -5
  147. package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +66 -740
  148. package/references/state-machine.md +4 -4
  149. package/roles/technical-planner.md +1 -1
  150. package/schemas/corrective-decision-event.schema.json +3 -1
  151. package/schemas/project-knowledge-map.schema.json +3 -1
  152. package/schemas/remediation-event.schema.json +10 -1
  153. package/schemas/task.schema.json +46 -2
  154. package/schemas/transition-payloads.schema.json +16 -1
  155. package/src/alpha6/adoption.ts +1123 -0
  156. package/src/alpha6/captured-check-evidence.ts +132 -0
  157. package/src/alpha6/check-support-anchor.ts +128 -0
  158. package/src/alpha6/component-owner.ts +168 -0
  159. package/src/alpha6/corrective-decision-boundary.ts +39 -0
  160. package/src/alpha6/downstream-proof.ts +520 -0
  161. package/src/alpha6/failed-step-planning-recovery.ts +88 -0
  162. package/src/alpha6/handoff.ts +1443 -0
  163. package/src/alpha6/journal.ts +473 -0
  164. package/src/alpha6/literal-test-invocation.ts +84 -0
  165. package/src/alpha6/mechanical-feasibility.ts +488 -0
  166. package/src/alpha6/milestone.ts +2192 -0
  167. package/src/alpha6/navigation-dirty-carryover.ts +154 -0
  168. package/src/alpha6/npm-check-contract.ts +47 -0
  169. package/src/alpha6/plan-integrity.ts +298 -0
  170. package/src/alpha6/plan-risk.ts +1480 -0
  171. package/src/alpha6/preexecution-replan.ts +187 -0
  172. package/src/alpha6/remediation-cause.ts +98 -0
  173. package/src/alpha6/remediation.ts +2438 -0
  174. package/src/alpha6/review.ts +1198 -0
  175. package/src/alpha6/root-cause-replan-carryover.ts +491 -0
  176. package/src/alpha6/store-sidecars.ts +335 -0
  177. package/src/alpha7/autonomy.ts +411 -0
  178. package/src/alpha7/corrective-recovery.ts +1332 -0
  179. package/src/artifacts.ts +130 -0
  180. package/src/beta1/project-transaction.ts +355 -0
  181. package/src/change-explanation.ts +153 -0
  182. package/src/checks/runner.ts +245 -0
  183. package/src/checks/task-sync.ts +41 -0
  184. package/src/checks/worker.ts +149 -0
  185. package/src/cli-actions.ts +107 -0
  186. package/src/cli.ts +1457 -0
  187. package/src/contracts.ts +1494 -0
  188. package/src/credential-output.ts +89 -0
  189. package/src/credential-transport.ts +215 -0
  190. package/src/delegation.ts +190 -0
  191. package/src/dependency-provenance.ts +472 -0
  192. package/src/diagnostics.ts +93 -0
  193. package/src/domain/base-sync-conflict.ts +35 -0
  194. package/src/domain/completed-step-carryover.ts +76 -0
  195. package/src/domain/discovery.ts +27 -0
  196. package/src/domain/plan-semantics.ts +58 -0
  197. package/src/domain/step-start-admission.ts +10 -0
  198. package/src/domain/validation.ts +177 -0
  199. package/src/domain/virgin-registration.ts +46 -0
  200. package/src/errors.ts +24 -0
  201. package/src/fs-utils.ts +61 -0
  202. package/src/gateway-handshake.ts +95 -0
  203. package/src/git.ts +183 -0
  204. package/src/graph.ts +342 -0
  205. package/src/historical-step-provenance.ts +136 -0
  206. package/src/index.ts +23 -0
  207. package/src/lifecycle/canonical-hash.ts +28 -0
  208. package/src/lifecycle/catalog.ts +202 -0
  209. package/src/lifecycle/compiler-inspection.ts +29 -0
  210. package/src/lifecycle/core-static-readiness.ts +132 -0
  211. package/src/lifecycle/corrective-replan-authority.ts +136 -0
  212. package/src/lifecycle/corrective-replan-binding-manifest.ts +51 -0
  213. package/src/lifecycle/corrective-replan-credential-core.ts +408 -0
  214. package/src/lifecycle/corrective-replan-credential-schema.ts +54 -0
  215. package/src/lifecycle/corrective-replan-credentials.ts +48 -0
  216. package/src/lifecycle/corrective-replan.ts +843 -0
  217. package/src/lifecycle/evaluator.ts +48 -0
  218. package/src/lifecycle/fingerprint.ts +488 -0
  219. package/src/lifecycle/immutable.ts +8 -0
  220. package/src/lifecycle/implementation-table.ts +118 -0
  221. package/src/lifecycle/index.ts +8 -0
  222. package/src/lifecycle/schema-artifact.ts +263 -0
  223. package/src/lifecycle/semantic-registry.ts +572 -0
  224. package/src/lifecycle/types.ts +838 -0
  225. package/src/memory.ts +273 -0
  226. package/src/migration.ts +161 -0
  227. package/src/navigation-actions.ts +70 -0
  228. package/src/navigation-update-artifact.ts +198 -0
  229. package/src/navigation-update.ts +121 -0
  230. package/src/observation.ts +225 -0
  231. package/src/observed-routes.ts +660 -0
  232. package/src/operational-contract.ts +125 -0
  233. package/src/pending-review-update.ts +175 -0
  234. package/src/repository.ts +99 -0
  235. package/src/reviewer.ts +1879 -0
  236. package/src/runtime.ts +6 -0
  237. package/src/state/corrective-replan-executor.ts +818 -0
  238. package/src/state/corrective-replan-public-schema.ts +83 -0
  239. package/src/state/corrective-replan-public.ts +908 -0
  240. package/src/state/corrective-replan-transaction.ts +949 -0
  241. package/src/state/corrective-yield-executor.ts +327 -0
  242. package/src/state/corrective-yield-transaction.ts +730 -0
  243. package/src/state/lock.ts +902 -0
  244. package/src/state/store.ts +567 -0
  245. package/src/transition-core.ts +330 -0
  246. package/src/ulid.ts +24 -0
  247. package/src/version.ts +2 -0
  248. package/src/workflow-blocker-route.ts +109 -0
  249. package/src/workflow.ts +10172 -0
  250. package/docs/alpha7.1-implementation-brief.md +0 -268
  251. package/docs/alpha7.2-corrective-context-refresh-brief.md +0 -484
  252. package/docs/alpha7.2.1-remediation-recovery-brief.md +0 -86
  253. package/docs/beta1-stabilization-brief.md +0 -165
  254. package/docs/beta11-plan-integrity-recovery-brief.md +0 -38
  255. package/docs/beta13.2-signal-review-recovery.md +0 -38
  256. package/docs/beta2-initial-assembly-navigation-brief.md +0 -616
  257. package/docs/change-model.md +0 -118
  258. package/docs/delegated-approval.md +0 -254
  259. package/docs/lifecycle/state-machine-stabilization.md +0 -641
  260. package/docs/pdf/README.md +0 -24
  261. package/docs/pdf/codex-workflow-v2-architecture-ru.pdf +0 -0
  262. package/docs/pdf/codex-workflow-v2-chat-only-guide-ru.pdf +0 -0
  263. package/docs/pdf/codex-workflow-v2-technical-reference-ru.pdf +0 -0
  264. package/docs/pdf/requirements.txt +0 -1
  265. package/docs/pdf/sources/codex-workflow-v2-architecture-ru.md +0 -478
  266. package/docs/pdf/sources/codex-workflow-v2-chat-only-guide-ru.md +0 -508
  267. package/docs/pdf/sources/codex-workflow-v2-technical-reference-ru.md +0 -778
  268. package/docs/pending-review-update.md +0 -15
  269. package/docs/problem-briefs/01-pre-implementation-integrity.md +0 -482
  270. package/docs/problem-briefs/02-minimal-step-integrity.md +0 -411
  271. package/docs/problem-briefs/03-minimal-agent-context-integrity.md +0 -358
  272. package/docs/problem-briefs/04-task-dependency-and-structural-replacement-integrity.md +0 -573
  273. package/docs/problem-briefs/BRIEF-TEMPLATE.md +0 -56
  274. package/docs/problem-briefs/README.md +0 -120
  275. package/docs/problem-briefs/evidence/p01-mechanical-feasibility-corpus.md +0 -90
  276. package/docs/problem-briefs/evidence/signal-v4-pre-m3-replay.md +0 -246
  277. package/docs/split-required-recovery.md +0 -47
  278. package/docs/stable-release-defect-register.md +0 -730
  279. package/docs/validation-report.md +0 -182
  280. package/scripts/generate-pdf-docs.py +0 -524
  281. 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
+ }