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