codex-workflow-v2 2.0.0-beta.13.14 → 2.0.0-beta.13.16

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 (125) hide show
  1. package/README.md +17 -0
  2. package/dist/reviewer-runtime-build.json +20 -8
  3. package/dist/src/alpha6/captured-check-evidence.d.ts +49 -0
  4. package/dist/src/alpha6/captured-check-evidence.js +146 -0
  5. package/dist/src/alpha6/captured-check-evidence.js.map +1 -0
  6. package/dist/src/alpha6/corrective-decision-boundary.d.ts +4 -0
  7. package/dist/src/alpha6/corrective-decision-boundary.js +47 -0
  8. package/dist/src/alpha6/corrective-decision-boundary.js.map +1 -0
  9. package/dist/src/alpha6/root-cause-replan-carryover.d.ts +3 -1
  10. package/dist/src/alpha6/root-cause-replan-carryover.js +4 -0
  11. package/dist/src/alpha6/root-cause-replan-carryover.js.map +1 -1
  12. package/dist/src/contracts.d.ts +5 -1
  13. package/dist/src/dependency-provenance.js +10 -0
  14. package/dist/src/dependency-provenance.js.map +1 -1
  15. package/dist/src/graph.js +25 -3
  16. package/dist/src/graph.js.map +1 -1
  17. package/dist/src/version.d.ts +1 -1
  18. package/dist/src/version.js +1 -1
  19. package/dist/src/workflow-blocker-route.d.ts +8 -0
  20. package/dist/src/workflow-blocker-route.js +106 -0
  21. package/dist/src/workflow-blocker-route.js.map +1 -0
  22. package/dist/src/workflow.d.ts +1 -0
  23. package/dist/src/workflow.js +139 -19
  24. package/dist/src/workflow.js.map +1 -1
  25. package/docs/pdf/codex-workflow-v2-architecture-ru.pdf +0 -0
  26. package/docs/pdf/codex-workflow-v2-chat-only-guide-ru.pdf +0 -0
  27. package/docs/pdf/codex-workflow-v2-technical-reference-ru.pdf +0 -0
  28. package/docs/pdf/sources/codex-workflow-v2-architecture-ru.md +1 -1
  29. package/docs/pdf/sources/codex-workflow-v2-chat-only-guide-ru.md +2 -2
  30. package/docs/pdf/sources/codex-workflow-v2-technical-reference-ru.md +2 -2
  31. package/docs/release.md +49 -0
  32. package/package.json +2 -1
  33. package/plugins/codex-workflow-gateway/.codex-plugin/plugin.json +1 -1
  34. package/plugins/codex-workflow-gateway/references/chat-dispatch.md +40 -11
  35. package/plugins/codex-workflow-gateway/references/codebase-memory-routing.md +55 -0
  36. package/plugins/codex-workflow-gateway/scripts/chat-dispatch.mjs +7 -1
  37. package/plugins/codex-workflow-gateway/scripts/chat-model-policy.mjs +10 -8
  38. package/plugins/codex-workflow-gateway/scripts/chat-registry.mjs +23 -5
  39. package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +78 -12
  40. package/src/alpha6/adoption.ts +1105 -0
  41. package/src/alpha6/captured-check-evidence.ts +126 -0
  42. package/src/alpha6/check-support-anchor.ts +128 -0
  43. package/src/alpha6/component-owner.ts +168 -0
  44. package/src/alpha6/corrective-decision-boundary.ts +39 -0
  45. package/src/alpha6/downstream-proof.ts +732 -0
  46. package/src/alpha6/failed-step-planning-recovery.ts +88 -0
  47. package/src/alpha6/handoff.ts +1443 -0
  48. package/src/alpha6/journal.ts +473 -0
  49. package/src/alpha6/literal-test-invocation.ts +84 -0
  50. package/src/alpha6/mechanical-feasibility.ts +488 -0
  51. package/src/alpha6/milestone.ts +2182 -0
  52. package/src/alpha6/npm-check-contract.ts +47 -0
  53. package/src/alpha6/plan-integrity-update.ts +20 -0
  54. package/src/alpha6/plan-integrity.ts +298 -0
  55. package/src/alpha6/plan-risk.ts +1480 -0
  56. package/src/alpha6/preexecution-replan.ts +187 -0
  57. package/src/alpha6/remediation-cause.ts +98 -0
  58. package/src/alpha6/remediation.ts +2965 -0
  59. package/src/alpha6/review.ts +1198 -0
  60. package/src/alpha6/root-cause-replan-carryover.ts +471 -0
  61. package/src/alpha6/store-sidecars.ts +335 -0
  62. package/src/alpha7/autonomy.ts +411 -0
  63. package/src/alpha7/corrective-recovery.ts +1332 -0
  64. package/src/artifacts.ts +130 -0
  65. package/src/beta1/project-transaction.ts +351 -0
  66. package/src/change-explanation.ts +153 -0
  67. package/src/cli-actions.ts +119 -0
  68. package/src/cli.ts +1583 -0
  69. package/src/contracts.ts +1510 -0
  70. package/src/credential-output.ts +89 -0
  71. package/src/credential-transport.ts +215 -0
  72. package/src/delegation.ts +190 -0
  73. package/src/dependency-provenance.ts +538 -0
  74. package/src/diagnostics.ts +93 -0
  75. package/src/domain/completed-step-carryover.ts +76 -0
  76. package/src/domain/discovery.ts +27 -0
  77. package/src/domain/plan-semantics.ts +58 -0
  78. package/src/domain/validation.ts +177 -0
  79. package/src/errors.ts +23 -0
  80. package/src/fs-utils.ts +61 -0
  81. package/src/gateway-handshake.ts +103 -0
  82. package/src/git.ts +158 -0
  83. package/src/graph.ts +342 -0
  84. package/src/historical-step-provenance.ts +136 -0
  85. package/src/index.ts +21 -0
  86. package/src/lifecycle/canonical-hash.ts +28 -0
  87. package/src/lifecycle/catalog.ts +202 -0
  88. package/src/lifecycle/compiler-inspection.ts +29 -0
  89. package/src/lifecycle/core-static-readiness.ts +132 -0
  90. package/src/lifecycle/corrective-replan-authority.ts +136 -0
  91. package/src/lifecycle/corrective-replan-binding-manifest.ts +51 -0
  92. package/src/lifecycle/corrective-replan-credential-core.ts +408 -0
  93. package/src/lifecycle/corrective-replan-credential-schema.ts +54 -0
  94. package/src/lifecycle/corrective-replan-credentials.ts +48 -0
  95. package/src/lifecycle/corrective-replan.ts +843 -0
  96. package/src/lifecycle/evaluator.ts +48 -0
  97. package/src/lifecycle/fingerprint.ts +488 -0
  98. package/src/lifecycle/immutable.ts +8 -0
  99. package/src/lifecycle/implementation-table.ts +118 -0
  100. package/src/lifecycle/index.ts +8 -0
  101. package/src/lifecycle/schema-artifact.ts +263 -0
  102. package/src/lifecycle/semantic-registry.ts +572 -0
  103. package/src/lifecycle/types.ts +838 -0
  104. package/src/memory.ts +273 -0
  105. package/src/migration.ts +161 -0
  106. package/src/navigation-actions.ts +70 -0
  107. package/src/observation.ts +198 -0
  108. package/src/observed-routes.ts +661 -0
  109. package/src/operational-contract.ts +125 -0
  110. package/src/pending-review-update.ts +191 -0
  111. package/src/repository.ts +99 -0
  112. package/src/reviewer.ts +1876 -0
  113. package/src/state/corrective-replan-executor.ts +818 -0
  114. package/src/state/corrective-replan-public-schema.ts +83 -0
  115. package/src/state/corrective-replan-public.ts +908 -0
  116. package/src/state/corrective-replan-transaction.ts +947 -0
  117. package/src/state/corrective-yield-executor.ts +327 -0
  118. package/src/state/corrective-yield-transaction.ts +728 -0
  119. package/src/state/lock.ts +880 -0
  120. package/src/state/store.ts +567 -0
  121. package/src/transition-core.ts +330 -0
  122. package/src/ulid.ts +24 -0
  123. package/src/version.ts +2 -0
  124. package/src/workflow-blocker-route.ts +109 -0
  125. package/src/workflow.ts +11436 -0
@@ -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
+ }