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,187 @@
1
+ import type { AuthorizationEvent, PlanRiskAuditEvent, SidecarEventRecord, TaskState } from '../contracts.js';
2
+ import { WorkflowError } from '../errors.js';
3
+ import type { FileStateStore } from '../state/store.js';
4
+ import { createUlid } from '../ulid.js';
5
+ import {
6
+ assertHash64,
7
+ canonicalJsonStringify,
8
+ prepareSidecarAppend,
9
+ sha256Hex,
10
+ } from './store-sidecars.js';
11
+
12
+ const SIDECAR = 'preexecution-replans.jsonl';
13
+
14
+ export interface PreExecutionReplanEvent extends SidecarEventRecord {
15
+ taskId: string;
16
+ sourceTaskRevision: number;
17
+ resultTaskRevision: number;
18
+ briefHash: string;
19
+ sourcePlanHash: string;
20
+ knowledgeMapRevision: number;
21
+ knowledgeMapHash: string;
22
+ sourcePlanRiskAuditEventId: string;
23
+ sourcePlanRiskAuditEventHash: string;
24
+ obstructionPlanRiskAuditEventId: string;
25
+ obstructionPlanRiskAuditEventHash: string;
26
+ sourceExecutionAuthorizationHash: string;
27
+ sourceHeadCommit: string;
28
+ completedStepIds: string[];
29
+ completedStepsHash: string;
30
+ actor: string;
31
+ reason: string;
32
+ recordedAt: string;
33
+ }
34
+
35
+ export function preExecutionReplanSidecar(): string {
36
+ return SIDECAR;
37
+ }
38
+
39
+ export function hashExecutionAuthorization(authorization: AuthorizationEvent): string {
40
+ return sha256Hex(canonicalJsonStringify(authorization));
41
+ }
42
+
43
+ export function hashCompletedSteps(task: TaskState): string {
44
+ return sha256Hex(canonicalJsonStringify(
45
+ task.steps.filter((step) => step.status === 'completed'),
46
+ ));
47
+ }
48
+
49
+ export function preparePreExecutionReplanEvent(
50
+ store: FileStateStore,
51
+ task: TaskState,
52
+ input: {
53
+ sourceAudit: PlanRiskAuditEvent;
54
+ obstructionAudit: PlanRiskAuditEvent;
55
+ authorization: AuthorizationEvent;
56
+ sourceHeadCommit: string;
57
+ actor: string;
58
+ reason: string;
59
+ },
60
+ now: Date,
61
+ ): { event: PreExecutionReplanEvent; postimage: string } {
62
+ const actor = input.actor.trim();
63
+ const reason = input.reason.trim();
64
+ if (!actor) throw new WorkflowError('INVALID_ARGUMENT', 'Pre-execution replan actor is required.');
65
+ if (!reason) throw new WorkflowError('INVALID_ARGUMENT', 'Pre-execution replan reason is required.');
66
+ if (reason.length > 2048) throw new WorkflowError('INVALID_ARGUMENT', 'Pre-execution replan reason is too long.');
67
+ if (!task.planHash || task.knowledgeMapRevision === null || !task.knowledgeMapHash) {
68
+ throw new WorkflowError('STATE_CORRUPT', 'Pre-execution replan requires complete current Plan and Knowledge bindings.');
69
+ }
70
+ const existing = readPreExecutionReplanEvents(store, task);
71
+ const completedStepIds = task.steps.filter((step) => step.status === 'completed').map((step) => step.id);
72
+ const prepared = prepareSidecarAppend<PreExecutionReplanEvent>(existing, {
73
+ eventId: `PER-${createUlid(now.getTime())}`,
74
+ taskId: task.id,
75
+ sourceTaskRevision: task.revision,
76
+ resultTaskRevision: task.revision + 1,
77
+ briefHash: task.briefHash,
78
+ sourcePlanHash: task.planHash,
79
+ knowledgeMapRevision: task.knowledgeMapRevision,
80
+ knowledgeMapHash: task.knowledgeMapHash,
81
+ sourcePlanRiskAuditEventId: input.sourceAudit.eventId,
82
+ sourcePlanRiskAuditEventHash: input.sourceAudit.eventHash,
83
+ obstructionPlanRiskAuditEventId: input.obstructionAudit.eventId,
84
+ obstructionPlanRiskAuditEventHash: input.obstructionAudit.eventHash,
85
+ sourceExecutionAuthorizationHash: hashExecutionAuthorization(input.authorization),
86
+ sourceHeadCommit: input.sourceHeadCommit,
87
+ completedStepIds,
88
+ completedStepsHash: hashCompletedSteps(task),
89
+ actor,
90
+ reason,
91
+ recordedAt: now.toISOString(),
92
+ }, {
93
+ validateEvent: validateStoredPreExecutionReplanEvent,
94
+ });
95
+ return { event: prepared.event, postimage: prepared.content };
96
+ }
97
+
98
+ export function readPreExecutionReplanEvents(
99
+ store: FileStateStore,
100
+ task: TaskState,
101
+ ): PreExecutionReplanEvent[] {
102
+ return store.readSidecarEvents<PreExecutionReplanEvent>(
103
+ store.taskRoot(task.projectId, task.id),
104
+ SIDECAR,
105
+ { validateEvent: validateStoredPreExecutionReplanEvent },
106
+ );
107
+ }
108
+
109
+ export function readCurrentPreExecutionReplan(
110
+ store: FileStateStore,
111
+ task: TaskState,
112
+ ): PreExecutionReplanEvent | null {
113
+ const event = readPreExecutionReplanEvents(store, task).at(-1) ?? null;
114
+ if (!event || event.sourcePlanHash !== task.planHash || task.status === 'cancelled') return null;
115
+ if (task.revision < event.resultTaskRevision) {
116
+ throw new WorkflowError('STATE_CORRUPT', 'Pre-execution replan marker is newer than its Task state.', {
117
+ taskId: task.id,
118
+ eventId: event.eventId,
119
+ });
120
+ }
121
+ if (event.taskId !== task.id || event.briefHash !== task.briefHash
122
+ || event.knowledgeMapRevision !== task.knowledgeMapRevision
123
+ || event.knowledgeMapHash !== task.knowledgeMapHash) {
124
+ throw new WorkflowError('STATE_CORRUPT', 'Current pre-execution replan marker does not match Task authority.', {
125
+ taskId: task.id,
126
+ eventId: event.eventId,
127
+ });
128
+ }
129
+ if (event.completedStepsHash !== hashCompletedSteps(task)
130
+ || canonicalJsonStringify(event.completedStepIds)
131
+ !== canonicalJsonStringify(task.steps.filter((step) => step.status === 'completed').map((step) => step.id))) {
132
+ throw new WorkflowError('STATE_CORRUPT', 'Completed Step authority changed after pre-execution replan recording.', {
133
+ taskId: task.id,
134
+ eventId: event.eventId,
135
+ });
136
+ }
137
+ return event;
138
+ }
139
+
140
+ function validateStoredPreExecutionReplanEvent(
141
+ event: PreExecutionReplanEvent,
142
+ context: { file: string; line: number; eventId: string },
143
+ ): void {
144
+ const expectedKeys = [
145
+ 'actor', 'briefHash', 'completedStepIds', 'completedStepsHash', 'eventHash', 'eventId',
146
+ 'knowledgeMapHash', 'knowledgeMapRevision', 'obstructionPlanRiskAuditEventHash',
147
+ 'obstructionPlanRiskAuditEventId', 'previousEventHash', 'reason', 'recordedAt',
148
+ 'resultTaskRevision', 'sourceExecutionAuthorizationHash', 'sourceHeadCommit', 'sourcePlanHash',
149
+ 'sourcePlanRiskAuditEventHash', 'sourcePlanRiskAuditEventId', 'sourceTaskRevision', 'taskId',
150
+ ].sort();
151
+ if (!event || typeof event !== 'object' || Array.isArray(event)
152
+ || canonicalJsonStringify(Object.keys(event).sort()) !== canonicalJsonStringify(expectedKeys)) {
153
+ throw new WorkflowError('STATE_CORRUPT', 'Pre-execution replan event has an invalid shape.', context);
154
+ }
155
+ if (!/^PER-[0-9A-HJKMNP-TV-Z]{26}$/.test(event.eventId)
156
+ || !/^TASK-[0-9A-HJKMNP-TV-Z]{26}$/.test(event.taskId)
157
+ || !/^PRA-[0-9A-HJKMNP-TV-Z]{26}$/.test(event.sourcePlanRiskAuditEventId)
158
+ || !/^PRA-[0-9A-HJKMNP-TV-Z]{26}$/.test(event.obstructionPlanRiskAuditEventId)) {
159
+ throw new WorkflowError('STATE_CORRUPT', 'Pre-execution replan event identity binding is invalid.', context);
160
+ }
161
+ if (!Number.isSafeInteger(event.sourceTaskRevision) || event.sourceTaskRevision < 1
162
+ || event.resultTaskRevision !== event.sourceTaskRevision + 1
163
+ || !Number.isSafeInteger(event.knowledgeMapRevision) || event.knowledgeMapRevision < 1) {
164
+ throw new WorkflowError('STATE_CORRUPT', 'Pre-execution replan event revision binding is invalid.', context);
165
+ }
166
+ for (const [label, value] of [
167
+ ['briefHash', event.briefHash], ['sourcePlanHash', event.sourcePlanHash],
168
+ ['knowledgeMapHash', event.knowledgeMapHash],
169
+ ['sourcePlanRiskAuditEventHash', event.sourcePlanRiskAuditEventHash],
170
+ ['obstructionPlanRiskAuditEventHash', event.obstructionPlanRiskAuditEventHash],
171
+ ['sourceExecutionAuthorizationHash', event.sourceExecutionAuthorizationHash],
172
+ ['completedStepsHash', event.completedStepsHash],
173
+ ] as const) assertHash64(value, `Pre-execution replan ${label}`);
174
+ if (!/^[a-f0-9]{40}$/.test(event.sourceHeadCommit)) {
175
+ throw new WorkflowError('STATE_CORRUPT', 'Pre-execution replan source HEAD is invalid.', context);
176
+ }
177
+ if (!Array.isArray(event.completedStepIds)
178
+ || event.completedStepIds.some((stepId) => typeof stepId !== 'string' || !stepId.trim())
179
+ || new Set(event.completedStepIds).size !== event.completedStepIds.length) {
180
+ throw new WorkflowError('STATE_CORRUPT', 'Pre-execution replan completed Step ids are invalid.', context);
181
+ }
182
+ if (typeof event.actor !== 'string' || !event.actor.trim()
183
+ || typeof event.reason !== 'string' || !event.reason.trim() || event.reason.length > 2048
184
+ || typeof event.recordedAt !== 'string' || !Number.isFinite(Date.parse(event.recordedAt))) {
185
+ throw new WorkflowError('STATE_CORRUPT', 'Pre-execution replan provenance is invalid.', context);
186
+ }
187
+ }
@@ -0,0 +1,98 @@
1
+ import { createHash } from 'node:crypto';
2
+ import path from 'node:path';
3
+ import type { RemediationCauseBinding } from '../contracts.js';
4
+ import type { CheckResult } from '../git.js';
5
+ import { canonicalJsonStringify } from './store-sidecars.js';
6
+
7
+ const ANSI_ESCAPE = /\u001b\[[0-9;]*m/g;
8
+ const ISO_TIMESTAMP = /\b\d{4}-\d{2}-\d{2}[T ][0-9:.+-]+Z?\b/g;
9
+ const TEMP_PATH = /\/(?:private\/)?(?:tmp|var\/folders)\/[^\s:'"`]+/g;
10
+ const HEX_ID = /\b[a-f0-9]{40,64}\b/g;
11
+ const SOURCE_LOCATION = /:(?:\d+)(?::\d+)?\b/g;
12
+ const DIAGNOSTIC_CODE = /\b(?:[A-Z][A-Z0-9_]{2,}|TS\d{3,5}|ERR_[A-Z0-9_]+)\b/g;
13
+ const REPOSITORY_PATH = /(?:^|[\s('"`])([A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)+\.(?:cjs|js|json|mjs|sql|ts|tsx))(?=[:\s)'"`]|$)/g;
14
+
15
+ export interface NormalizedMechanicalFailure {
16
+ command: string;
17
+ exitCode: number;
18
+ diagnosticCodes: string[];
19
+ diagnosticShape: string[];
20
+ diagnosticPaths: string[];
21
+ causeFingerprint: string;
22
+ }
23
+
24
+ export function normalizeMechanicalFailures(
25
+ checks: readonly CheckResult[],
26
+ repositoryRoot: string,
27
+ ): NormalizedMechanicalFailure[] {
28
+ return checks.filter((check) => !check.passed).map((check) => {
29
+ const normalizedOutput = normalizeOutput(check.output, repositoryRoot);
30
+ const diagnosticCodes = [...new Set(normalizedOutput.match(DIAGNOSTIC_CODE) ?? [])].sort().slice(0, 16);
31
+ const diagnosticShape = [...new Set(normalizedOutput.split('\n')
32
+ .map((line) => line.trim().replace(/\s+/g, ' '))
33
+ .filter(Boolean)
34
+ .slice(0, 4)
35
+ .map((line) => line.slice(0, 240)))];
36
+ const diagnosticPaths = extractRepositoryPaths(check.output, repositoryRoot);
37
+ const causeMaterial = {
38
+ domain: 'codex-workflow/mechanical-remediation-cause/v1',
39
+ command: normalizeCommand(check.command),
40
+ exitCode: check.exitCode,
41
+ diagnosticCodes,
42
+ diagnosticShape,
43
+ };
44
+ return {
45
+ command: causeMaterial.command,
46
+ exitCode: causeMaterial.exitCode,
47
+ diagnosticCodes,
48
+ diagnosticShape,
49
+ diagnosticPaths,
50
+ causeFingerprint: createHash('sha256').update(canonicalJsonStringify(causeMaterial)).digest('hex'),
51
+ };
52
+ });
53
+ }
54
+
55
+ export function mechanicalCauseBindings(
56
+ failures: readonly NormalizedMechanicalFailure[],
57
+ ): RemediationCauseBinding[] {
58
+ return failures.map((failure) => ({
59
+ authority: 'mechanical',
60
+ causeId: `mechanical:${failure.causeFingerprint}`,
61
+ causeFingerprint: failure.causeFingerprint,
62
+ planConflict: false,
63
+ }));
64
+ }
65
+
66
+ export function reviewerCauseFingerprint(causeId: string): string {
67
+ return createHash('sha256').update(canonicalJsonStringify({
68
+ domain: 'codex-workflow/external-reviewer-cause/v1',
69
+ causeId: causeId.trim(),
70
+ })).digest('hex');
71
+ }
72
+
73
+ function normalizeOutput(output: string, repositoryRoot: string): string {
74
+ const normalizedRoot = path.resolve(repositoryRoot).replaceAll('\\', '/');
75
+ return output
76
+ .replace(ANSI_ESCAPE, '')
77
+ .replaceAll('\\', '/')
78
+ .replaceAll(normalizedRoot, '<repo>')
79
+ .replace(TEMP_PATH, '<tmp>')
80
+ .replace(ISO_TIMESTAMP, '<time>')
81
+ .replace(HEX_ID, '<hash>')
82
+ .replace(SOURCE_LOCATION, ':<loc>');
83
+ }
84
+
85
+ function normalizeCommand(command: string): string {
86
+ return command.trim().replace(/\s+/g, ' ');
87
+ }
88
+
89
+ function extractRepositoryPaths(output: string, repositoryRoot: string): string[] {
90
+ const normalizedRoot = path.resolve(repositoryRoot).replaceAll('\\', '/');
91
+ const normalized = output.replaceAll('\\', '/').replaceAll(`${normalizedRoot}/`, '');
92
+ const result = new Set<string>();
93
+ for (const match of normalized.matchAll(REPOSITORY_PATH)) {
94
+ const candidate = match[1]!;
95
+ if (!candidate.startsWith('../') && !path.posix.isAbsolute(candidate)) result.add(candidate);
96
+ }
97
+ return [...result].sort();
98
+ }