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.
- package/README.md +27 -388
- package/dist/reviewer-runtime-build.json +89 -29
- package/dist/src/alpha6/adoption.d.ts +2 -0
- package/dist/src/alpha6/adoption.js +22 -0
- package/dist/src/alpha6/adoption.js.map +1 -1
- package/dist/src/alpha6/captured-check-evidence.d.ts +51 -0
- package/dist/src/alpha6/captured-check-evidence.js +152 -0
- package/dist/src/alpha6/captured-check-evidence.js.map +1 -0
- package/dist/src/alpha6/component-owner.d.ts +15 -1
- package/dist/src/alpha6/component-owner.js +44 -2
- package/dist/src/alpha6/component-owner.js.map +1 -1
- package/dist/src/alpha6/corrective-decision-boundary.d.ts +4 -0
- package/dist/src/alpha6/corrective-decision-boundary.js +47 -0
- package/dist/src/alpha6/corrective-decision-boundary.js.map +1 -0
- package/dist/src/alpha6/downstream-proof.d.ts +1 -25
- package/dist/src/alpha6/downstream-proof.js +0 -171
- package/dist/src/alpha6/downstream-proof.js.map +1 -1
- package/dist/src/alpha6/literal-test-invocation.d.ts +2 -0
- package/dist/src/alpha6/literal-test-invocation.js +106 -0
- package/dist/src/alpha6/literal-test-invocation.js.map +1 -0
- package/dist/src/alpha6/milestone.d.ts +2 -0
- package/dist/src/alpha6/milestone.js +10 -1
- package/dist/src/alpha6/milestone.js.map +1 -1
- package/dist/src/alpha6/navigation-dirty-carryover.d.ts +11 -0
- package/dist/src/alpha6/navigation-dirty-carryover.js +130 -0
- package/dist/src/alpha6/navigation-dirty-carryover.js.map +1 -0
- package/dist/src/alpha6/plan-integrity.js +7 -5
- package/dist/src/alpha6/plan-integrity.js.map +1 -1
- package/dist/src/alpha6/remediation.d.ts +6 -21
- package/dist/src/alpha6/remediation.js +161 -476
- package/dist/src/alpha6/remediation.js.map +1 -1
- package/dist/src/alpha6/root-cause-replan-carryover.d.ts +4 -1
- package/dist/src/alpha6/root-cause-replan-carryover.js +29 -5
- package/dist/src/alpha6/root-cause-replan-carryover.js.map +1 -1
- package/dist/src/beta1/project-transaction.d.ts +3 -1
- package/dist/src/beta1/project-transaction.js +6 -2
- package/dist/src/beta1/project-transaction.js.map +1 -1
- package/dist/src/checks/runner.d.ts +26 -0
- package/dist/src/checks/runner.js +223 -0
- package/dist/src/checks/runner.js.map +1 -0
- package/dist/src/checks/task-sync.d.ts +10 -0
- package/dist/src/checks/task-sync.js +41 -0
- package/dist/src/checks/task-sync.js.map +1 -0
- package/dist/src/checks/worker.d.ts +1 -0
- package/dist/src/checks/worker.js +154 -0
- package/dist/src/checks/worker.js.map +1 -0
- package/dist/src/cli-actions.d.ts +2 -2
- package/dist/src/cli-actions.js +3 -15
- package/dist/src/cli-actions.js.map +1 -1
- package/dist/src/cli.js +14 -98
- package/dist/src/cli.js.map +1 -1
- package/dist/src/contracts.d.ts +35 -32
- package/dist/src/dependency-provenance.d.ts +2 -2
- package/dist/src/dependency-provenance.js +12 -69
- package/dist/src/dependency-provenance.js.map +1 -1
- package/dist/src/domain/base-sync-conflict.d.ts +13 -0
- package/dist/src/domain/base-sync-conflict.js +32 -0
- package/dist/src/domain/base-sync-conflict.js.map +1 -0
- package/dist/src/domain/step-start-admission.d.ts +4 -0
- package/dist/src/domain/step-start-admission.js +9 -0
- package/dist/src/domain/step-start-admission.js.map +1 -0
- package/dist/src/domain/virgin-registration.d.ts +3 -0
- package/dist/src/domain/virgin-registration.js +65 -0
- package/dist/src/domain/virgin-registration.js.map +1 -0
- package/dist/src/errors.d.ts +1 -1
- package/dist/src/errors.js.map +1 -1
- package/dist/src/gateway-handshake.js +0 -8
- package/dist/src/gateway-handshake.js.map +1 -1
- package/dist/src/git.d.ts +3 -1
- package/dist/src/git.js +41 -14
- package/dist/src/git.js.map +1 -1
- package/dist/src/graph.js +25 -3
- package/dist/src/graph.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/navigation-actions.d.ts +9 -0
- package/dist/src/navigation-actions.js +72 -0
- package/dist/src/navigation-actions.js.map +1 -0
- package/dist/src/navigation-update-artifact.d.ts +5 -0
- package/dist/src/navigation-update-artifact.js +227 -0
- package/dist/src/navigation-update-artifact.js.map +1 -0
- package/dist/src/navigation-update.d.ts +39 -0
- package/dist/src/navigation-update.js +82 -0
- package/dist/src/navigation-update.js.map +1 -0
- package/dist/src/observation.js +52 -29
- package/dist/src/observation.js.map +1 -1
- package/dist/src/observed-routes.js +5 -6
- package/dist/src/observed-routes.js.map +1 -1
- package/dist/src/pending-review-update.d.ts +0 -13
- package/dist/src/pending-review-update.js +1 -6
- package/dist/src/pending-review-update.js.map +1 -1
- package/dist/src/reviewer.d.ts +1 -1
- package/dist/src/reviewer.js +20 -17
- package/dist/src/reviewer.js.map +1 -1
- package/dist/src/runtime.d.ts +3 -0
- package/dist/src/runtime.js +6 -0
- package/dist/src/runtime.js.map +1 -0
- package/dist/src/state/corrective-replan-executor.d.ts +10 -0
- package/dist/src/state/corrective-replan-executor.js +37 -1
- package/dist/src/state/corrective-replan-executor.js.map +1 -1
- package/dist/src/state/corrective-replan-public-schema.js +15 -2
- package/dist/src/state/corrective-replan-public-schema.js.map +1 -1
- package/dist/src/state/corrective-replan-public.js +1 -1
- package/dist/src/state/corrective-replan-public.js.map +1 -1
- package/dist/src/state/corrective-replan-transaction.d.ts +1 -0
- package/dist/src/state/corrective-replan-transaction.js +12 -11
- package/dist/src/state/corrective-replan-transaction.js.map +1 -1
- package/dist/src/state/corrective-yield-transaction.d.ts +1 -0
- package/dist/src/state/corrective-yield-transaction.js +11 -10
- package/dist/src/state/corrective-yield-transaction.js.map +1 -1
- package/dist/src/state/lock.d.ts +4 -0
- package/dist/src/state/lock.js +21 -0
- package/dist/src/state/lock.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/dist/src/workflow-blocker-route.d.ts +8 -0
- package/dist/src/workflow-blocker-route.js +106 -0
- package/dist/src/workflow-blocker-route.js.map +1 -0
- package/dist/src/workflow.d.ts +48 -63
- package/dist/src/workflow.js +666 -1460
- package/dist/src/workflow.js.map +1 -1
- package/docs/autonomy-guardrails.md +26 -304
- package/docs/decisions.md +14 -112
- package/docs/development-flow.md +35 -238
- package/docs/project-memory.md +31 -50
- package/docs/release-app-evidence.md +190 -0
- package/docs/release.md +95 -388
- package/docs/updating-existing-project.md +19 -717
- package/package.json +11 -13
- package/plugins/codex-workflow-gateway/.codex-plugin/plugin.json +2 -2
- package/plugins/codex-workflow-gateway/references/chat-dispatch.md +73 -197
- package/plugins/codex-workflow-gateway/references/codebase-memory-routing.md +57 -0
- package/plugins/codex-workflow-gateway/references/protocol.md +42 -445
- package/plugins/codex-workflow-gateway/scripts/chat-dispatch.mjs +7 -1
- package/plugins/codex-workflow-gateway/scripts/chat-model-policy.mjs +10 -8
- package/plugins/codex-workflow-gateway/scripts/chat-registry.mjs +23 -5
- package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +66 -757
- package/references/state-machine.md +4 -4
- package/roles/technical-planner.md +1 -1
- package/schemas/corrective-decision-event.schema.json +3 -1
- package/schemas/project-knowledge-map.schema.json +3 -1
- package/schemas/remediation-event.schema.json +10 -1
- package/schemas/task.schema.json +46 -2
- package/schemas/transition-payloads.schema.json +16 -1
- package/src/alpha6/adoption.ts +1123 -0
- package/src/alpha6/captured-check-evidence.ts +132 -0
- package/src/alpha6/check-support-anchor.ts +128 -0
- package/src/alpha6/component-owner.ts +168 -0
- package/src/alpha6/corrective-decision-boundary.ts +39 -0
- package/src/alpha6/downstream-proof.ts +520 -0
- package/src/alpha6/failed-step-planning-recovery.ts +88 -0
- package/src/alpha6/handoff.ts +1443 -0
- package/src/alpha6/journal.ts +473 -0
- package/src/alpha6/literal-test-invocation.ts +84 -0
- package/src/alpha6/mechanical-feasibility.ts +488 -0
- package/src/alpha6/milestone.ts +2192 -0
- package/src/alpha6/navigation-dirty-carryover.ts +154 -0
- package/src/alpha6/npm-check-contract.ts +47 -0
- package/src/alpha6/plan-integrity.ts +298 -0
- package/src/alpha6/plan-risk.ts +1480 -0
- package/src/alpha6/preexecution-replan.ts +187 -0
- package/src/alpha6/remediation-cause.ts +98 -0
- package/src/alpha6/remediation.ts +2438 -0
- package/src/alpha6/review.ts +1198 -0
- package/src/alpha6/root-cause-replan-carryover.ts +491 -0
- package/src/alpha6/store-sidecars.ts +335 -0
- package/src/alpha7/autonomy.ts +411 -0
- package/src/alpha7/corrective-recovery.ts +1332 -0
- package/src/artifacts.ts +130 -0
- package/src/beta1/project-transaction.ts +355 -0
- package/src/change-explanation.ts +153 -0
- package/src/checks/runner.ts +245 -0
- package/src/checks/task-sync.ts +41 -0
- package/src/checks/worker.ts +149 -0
- package/src/cli-actions.ts +107 -0
- package/src/cli.ts +1457 -0
- package/src/contracts.ts +1494 -0
- package/src/credential-output.ts +89 -0
- package/src/credential-transport.ts +215 -0
- package/src/delegation.ts +190 -0
- package/src/dependency-provenance.ts +472 -0
- package/src/diagnostics.ts +93 -0
- package/src/domain/base-sync-conflict.ts +35 -0
- package/src/domain/completed-step-carryover.ts +76 -0
- package/src/domain/discovery.ts +27 -0
- package/src/domain/plan-semantics.ts +58 -0
- package/src/domain/step-start-admission.ts +10 -0
- package/src/domain/validation.ts +177 -0
- package/src/domain/virgin-registration.ts +46 -0
- package/src/errors.ts +24 -0
- package/src/fs-utils.ts +61 -0
- package/src/gateway-handshake.ts +95 -0
- package/src/git.ts +183 -0
- package/src/graph.ts +342 -0
- package/src/historical-step-provenance.ts +136 -0
- package/src/index.ts +23 -0
- package/src/lifecycle/canonical-hash.ts +28 -0
- package/src/lifecycle/catalog.ts +202 -0
- package/src/lifecycle/compiler-inspection.ts +29 -0
- package/src/lifecycle/core-static-readiness.ts +132 -0
- package/src/lifecycle/corrective-replan-authority.ts +136 -0
- package/src/lifecycle/corrective-replan-binding-manifest.ts +51 -0
- package/src/lifecycle/corrective-replan-credential-core.ts +408 -0
- package/src/lifecycle/corrective-replan-credential-schema.ts +54 -0
- package/src/lifecycle/corrective-replan-credentials.ts +48 -0
- package/src/lifecycle/corrective-replan.ts +843 -0
- package/src/lifecycle/evaluator.ts +48 -0
- package/src/lifecycle/fingerprint.ts +488 -0
- package/src/lifecycle/immutable.ts +8 -0
- package/src/lifecycle/implementation-table.ts +118 -0
- package/src/lifecycle/index.ts +8 -0
- package/src/lifecycle/schema-artifact.ts +263 -0
- package/src/lifecycle/semantic-registry.ts +572 -0
- package/src/lifecycle/types.ts +838 -0
- package/src/memory.ts +273 -0
- package/src/migration.ts +161 -0
- package/src/navigation-actions.ts +70 -0
- package/src/navigation-update-artifact.ts +198 -0
- package/src/navigation-update.ts +121 -0
- package/src/observation.ts +225 -0
- package/src/observed-routes.ts +660 -0
- package/src/operational-contract.ts +125 -0
- package/src/pending-review-update.ts +175 -0
- package/src/repository.ts +99 -0
- package/src/reviewer.ts +1879 -0
- package/src/runtime.ts +6 -0
- package/src/state/corrective-replan-executor.ts +818 -0
- package/src/state/corrective-replan-public-schema.ts +83 -0
- package/src/state/corrective-replan-public.ts +908 -0
- package/src/state/corrective-replan-transaction.ts +949 -0
- package/src/state/corrective-yield-executor.ts +327 -0
- package/src/state/corrective-yield-transaction.ts +730 -0
- package/src/state/lock.ts +902 -0
- package/src/state/store.ts +567 -0
- package/src/transition-core.ts +330 -0
- package/src/ulid.ts +24 -0
- package/src/version.ts +2 -0
- package/src/workflow-blocker-route.ts +109 -0
- package/src/workflow.ts +10172 -0
- package/docs/alpha7.1-implementation-brief.md +0 -268
- package/docs/alpha7.2-corrective-context-refresh-brief.md +0 -484
- package/docs/alpha7.2.1-remediation-recovery-brief.md +0 -86
- package/docs/beta1-stabilization-brief.md +0 -165
- package/docs/beta11-plan-integrity-recovery-brief.md +0 -38
- package/docs/beta13.2-signal-review-recovery.md +0 -38
- package/docs/beta2-initial-assembly-navigation-brief.md +0 -616
- package/docs/change-model.md +0 -118
- package/docs/delegated-approval.md +0 -254
- package/docs/lifecycle/state-machine-stabilization.md +0 -641
- package/docs/pdf/README.md +0 -24
- package/docs/pdf/codex-workflow-v2-architecture-ru.pdf +0 -0
- package/docs/pdf/codex-workflow-v2-chat-only-guide-ru.pdf +0 -0
- package/docs/pdf/codex-workflow-v2-technical-reference-ru.pdf +0 -0
- package/docs/pdf/requirements.txt +0 -1
- package/docs/pdf/sources/codex-workflow-v2-architecture-ru.md +0 -478
- package/docs/pdf/sources/codex-workflow-v2-chat-only-guide-ru.md +0 -506
- package/docs/pdf/sources/codex-workflow-v2-technical-reference-ru.md +0 -778
- package/docs/pending-review-update.md +0 -15
- package/docs/problem-briefs/01-pre-implementation-integrity.md +0 -482
- package/docs/problem-briefs/02-minimal-step-integrity.md +0 -411
- package/docs/problem-briefs/03-minimal-agent-context-integrity.md +0 -358
- package/docs/problem-briefs/04-task-dependency-and-structural-replacement-integrity.md +0 -573
- package/docs/problem-briefs/BRIEF-TEMPLATE.md +0 -56
- package/docs/problem-briefs/README.md +0 -120
- package/docs/problem-briefs/evidence/p01-mechanical-feasibility-corpus.md +0 -90
- package/docs/problem-briefs/evidence/signal-v4-pre-m3-replay.md +0 -246
- package/docs/split-required-recovery.md +0 -47
- package/docs/stable-release-defect-register.md +0 -730
- package/docs/validation-report.md +0 -182
- package/scripts/generate-pdf-docs.py +0 -524
- package/scripts/run-pdf-docs.mjs +0 -62
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { lstatSync, readFileSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { WorkflowError } from '../errors.js';
|
|
4
|
+
import { canonicalJsonStringify, sha256Hex } from './store-sidecars.js';
|
|
5
|
+
const KIND = 'captured-checks/v1';
|
|
6
|
+
const HASH = /^[a-f0-9]{64}$/;
|
|
7
|
+
function corrupt() {
|
|
8
|
+
// Never include captured output or parsing errors in public diagnostics.
|
|
9
|
+
throw new WorkflowError('STATE_CORRUPT', 'Captured check evidence is missing, unsafe, or does not match its binding.');
|
|
10
|
+
}
|
|
11
|
+
function inspect(file) {
|
|
12
|
+
try {
|
|
13
|
+
return lstatSync(file);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
if (error.code === 'ENOENT')
|
|
17
|
+
return null;
|
|
18
|
+
return corrupt();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function artifactFile(store, task, checksHash) {
|
|
22
|
+
if (!HASH.test(checksHash))
|
|
23
|
+
corrupt();
|
|
24
|
+
const root = store.taskRoot(task.projectId, task.id);
|
|
25
|
+
const directory = path.join(root, 'check-results');
|
|
26
|
+
for (const item of [root, directory]) {
|
|
27
|
+
const stat = inspect(item);
|
|
28
|
+
if (stat && (!stat.isDirectory() || stat.isSymbolicLink() || (stat.mode & 0o077) !== 0))
|
|
29
|
+
corrupt();
|
|
30
|
+
}
|
|
31
|
+
return path.join(directory, `${checksHash}.json`);
|
|
32
|
+
}
|
|
33
|
+
function readBytes(file, maxBytes) {
|
|
34
|
+
const stat = inspect(file);
|
|
35
|
+
if (!stat)
|
|
36
|
+
return null;
|
|
37
|
+
if (!stat.isFile() || stat.isSymbolicLink() || (stat.mode & 0o077) !== 0 || stat.size > maxBytes)
|
|
38
|
+
corrupt();
|
|
39
|
+
try {
|
|
40
|
+
return readFileSync(file, 'utf8');
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return corrupt();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function validateChecks(value) {
|
|
47
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
48
|
+
corrupt();
|
|
49
|
+
for (const item of value) {
|
|
50
|
+
if (!item || typeof item !== 'object' || Array.isArray(item)
|
|
51
|
+
|| Object.keys(item).sort().join(',') !== 'command,exitCode,output,passed'
|
|
52
|
+
|| typeof item.command !== 'string' || typeof item.output !== 'string' || item.output.length > 12_000
|
|
53
|
+
|| typeof item.passed !== 'boolean' || !Number.isInteger(item.exitCode)
|
|
54
|
+
|| item.passed !== (item.exitCode === 0))
|
|
55
|
+
corrupt();
|
|
56
|
+
}
|
|
57
|
+
if (!value.some(item => !item.passed))
|
|
58
|
+
corrupt();
|
|
59
|
+
}
|
|
60
|
+
/** Prepare one target for the existing failed-Step transaction. Performs no writes. */
|
|
61
|
+
export function prepareCapturedCheckEvidence(store, task, checks) {
|
|
62
|
+
validateChecks(checks);
|
|
63
|
+
const canonical = canonicalJsonStringify(checks);
|
|
64
|
+
const checksHash = sha256Hex(canonical);
|
|
65
|
+
const content = `${canonical}\n`;
|
|
66
|
+
const file = artifactFile(store, task, checksHash);
|
|
67
|
+
const previous = readBytes(file, Buffer.byteLength(content));
|
|
68
|
+
if (previous !== null && previous !== content)
|
|
69
|
+
corrupt();
|
|
70
|
+
return {
|
|
71
|
+
checksHash,
|
|
72
|
+
reference: { kind: KIND, artifactHash: sha256Hex(content) },
|
|
73
|
+
target: previous === null
|
|
74
|
+
? { path: path.relative(store.projectRoot(task.projectId), file).split(path.sep).join('/'), content }
|
|
75
|
+
: null,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/** Exact readback for the transaction; captured bytes never escape in its return value. */
|
|
79
|
+
export function assertCapturedCheckEvidence(store, task, pause, expected) {
|
|
80
|
+
const checks = readVerifiedChecks(store, task, pause, expected.map(check => check.command));
|
|
81
|
+
if (!checks || canonicalJsonStringify(checks) !== canonicalJsonStringify(expected))
|
|
82
|
+
corrupt();
|
|
83
|
+
}
|
|
84
|
+
function readVerifiedChecks(store, task, pause, commands) {
|
|
85
|
+
if (pause.checksEvidence === undefined)
|
|
86
|
+
return null;
|
|
87
|
+
const ref = pause.checksEvidence;
|
|
88
|
+
if (!ref || Object.keys(ref).sort().join(',') !== 'artifactHash,kind'
|
|
89
|
+
|| ref.kind !== KIND || !HASH.test(ref.artifactHash))
|
|
90
|
+
corrupt();
|
|
91
|
+
// JSON escaping can expand each captured character to six bytes.
|
|
92
|
+
const maxBytes = commands.reduce((size, command) => size + command.length * 6 + 12_000 * 6 + 256, 2);
|
|
93
|
+
const content = readBytes(artifactFile(store, task, pause.checksHash), maxBytes);
|
|
94
|
+
if (content === null || sha256Hex(content) !== ref.artifactHash)
|
|
95
|
+
corrupt();
|
|
96
|
+
let value;
|
|
97
|
+
try {
|
|
98
|
+
value = JSON.parse(content);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return corrupt();
|
|
102
|
+
}
|
|
103
|
+
validateChecks(value);
|
|
104
|
+
const canonical = canonicalJsonStringify(value);
|
|
105
|
+
if (content !== `${canonical}\n` || sha256Hex(canonical) !== pause.checksHash
|
|
106
|
+
|| JSON.stringify(value.map(check => check.command)) !== JSON.stringify(commands))
|
|
107
|
+
corrupt();
|
|
108
|
+
return value;
|
|
109
|
+
}
|
|
110
|
+
/** Verify native saved check evidence for admission without deriving authority from display diagnostics. */
|
|
111
|
+
export function assertCurrentCapturedCheckEvidence(store, task, stepId) {
|
|
112
|
+
const step = task.steps.find(candidate => candidate.id === stepId);
|
|
113
|
+
if (!step?.failurePause || !readVerifiedChecks(store, task, step.failurePause, step.checks))
|
|
114
|
+
corrupt();
|
|
115
|
+
}
|
|
116
|
+
/** Best-effort diagnostic display only. Never used in cause bindings, scope, or navigation. */
|
|
117
|
+
export function capturedCheckExcerpt(output, sensitiveValues = []) {
|
|
118
|
+
let text = output.replace(/\u001b\[[0-9;]*m/g, '');
|
|
119
|
+
for (const value of sensitiveValues.filter(Boolean))
|
|
120
|
+
text = text.replaceAll(value, '[REDACTED]');
|
|
121
|
+
const lines = text.split(/\r?\n/).map(line => line.trim()).filter(Boolean);
|
|
122
|
+
const errors = lines.filter(line => /\b(?:error|failed|failure|exception|assertion|fatal|panic)\b|\bTS\d{3,5}\b/i.test(line));
|
|
123
|
+
return (errors.length ? errors : lines).slice(-8).map(line => {
|
|
124
|
+
// Prefer hiding the whole secret-bearing line over preserving surrounding error text.
|
|
125
|
+
if (/\b(?:authorization|bearer|password|passwd|secret|token|api[_-]?key|private[_-]?key)\b|-----BEGIN .*PRIVATE KEY/i.test(line)) {
|
|
126
|
+
return '[REDACTED sensitive diagnostic line]';
|
|
127
|
+
}
|
|
128
|
+
return line
|
|
129
|
+
.replace(/\b[A-Za-z][A-Za-z0-9+.-]*:\/\/[^\s]+/g, '[REDACTED_URL]')
|
|
130
|
+
.replace(/\b(?:CREF|DGT|WLT|CLAIM)-[^\s]+/g, '[REDACTED]')
|
|
131
|
+
.replace(/[A-Za-z0-9_+/=-]{40,}/g, '[REDACTED_VALUE]')
|
|
132
|
+
.slice(0, 240);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
/** Read-only inspection of a current saved failure; no raw logs enter Task/status JSON. */
|
|
136
|
+
export function readCapturedCheckDiagnostics(store, task, stepId) {
|
|
137
|
+
const step = task.steps.find(candidate => candidate.id === stepId);
|
|
138
|
+
if (!step?.failurePause)
|
|
139
|
+
return { state: 'unavailable', reason: 'no-current-failure' };
|
|
140
|
+
const checks = readVerifiedChecks(store, task, step.failurePause, step.checks);
|
|
141
|
+
if (!checks)
|
|
142
|
+
return { state: 'unavailable', reason: 'legacy-not-captured' };
|
|
143
|
+
return {
|
|
144
|
+
state: 'verified',
|
|
145
|
+
checksHash: step.failurePause.checksHash,
|
|
146
|
+
artifactHash: step.failurePause.checksEvidence.artifactHash,
|
|
147
|
+
authority: 'diagnostic-only',
|
|
148
|
+
capture: 'bounded-output-tail-last-12000-characters',
|
|
149
|
+
failures: checks.flatMap((check, index) => check.passed ? [] : [{ index, exitCode: check.exitCode, excerpt: capturedCheckExcerpt(check.output) }]),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=captured-check-evidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"captured-check-evidence.js","sourceRoot":"","sources":["../../../src/alpha6/captured-check-evidence.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,9 +9,16 @@ export interface FailedCheckComponentOwnerConflict {
|
|
|
9
9
|
diagnosticPath: string;
|
|
10
10
|
componentRoot: string;
|
|
11
11
|
causeFingerprint: string;
|
|
12
|
+
testInvocation?: {
|
|
13
|
+
kind: 'literal-vitest-catalog';
|
|
14
|
+
runnerHash: string;
|
|
15
|
+
argv: string[];
|
|
16
|
+
migrationOutputs: string[];
|
|
17
|
+
catalogNames: string[];
|
|
18
|
+
};
|
|
12
19
|
}
|
|
13
20
|
export declare function inspectFailedCheckComponentOwners(input: {
|
|
14
|
-
step: Pick<PlanStepInput, 'checks' | 'allowedWrites' | 'forbiddenScope'> & {
|
|
21
|
+
step: Pick<PlanStepInput, 'checks' | 'allowedWrites' | 'forbiddenScope'> & Partial<Pick<PlanStepInput, 'expectedOutputs'>> & {
|
|
15
22
|
failurePause?: StepFailurePause | null;
|
|
16
23
|
};
|
|
17
24
|
scripts: ReadonlyMap<string, string>;
|
|
@@ -19,6 +26,7 @@ export declare function inspectFailedCheckComponentOwners(input: {
|
|
|
19
26
|
content: string | null;
|
|
20
27
|
hash: string | null;
|
|
21
28
|
};
|
|
29
|
+
isTracked?: (relativePath: string) => boolean;
|
|
22
30
|
}): FailedCheckComponentOwnerConflict[];
|
|
23
31
|
export declare function semanticBoundaryHash(task: {
|
|
24
32
|
planObjective: string | null;
|
|
@@ -26,3 +34,9 @@ export declare function semanticBoundaryHash(task: {
|
|
|
26
34
|
acceptance: string[];
|
|
27
35
|
risks: string[];
|
|
28
36
|
}): string;
|
|
37
|
+
/** Stored invocation evidence is structurally distinct from an import chain. The
|
|
38
|
+
* containing conflict hash binds it; fresh recovery rederives it from tracked bytes. */
|
|
39
|
+
export declare function validLiteralTestInvocationEvidence(conflict: {
|
|
40
|
+
ownerPath: string;
|
|
41
|
+
testInvocation?: FailedCheckComponentOwnerConflict['testInvocation'];
|
|
42
|
+
}): boolean;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { pathAllowed } from '../domain/validation.js';
|
|
4
|
+
import { literalMigrationCatalogNames, literalVitestInvocations } from './literal-test-invocation.js';
|
|
4
5
|
import { parseNpmRunCheck } from './npm-check-contract.js';
|
|
5
6
|
const RUNNER = /(?:^|[;&|]\s*|\s)(?:node|tsx)\s+([A-Za-z0-9._/-]+\.(?:cjs|js|mjs|ts|tsx))(?=\s|$)/g;
|
|
6
7
|
const IMPORT = /(?:\bfrom\s*|\bimport\s*)['"](\.[^'"]+)['"]/g;
|
|
@@ -17,7 +18,25 @@ export function inspectFailedCheckComponentOwners(input) {
|
|
|
17
18
|
for (const runnerPath of extractRunnerPaths(scriptCommand)) {
|
|
18
19
|
const graph = buildImportGraph(runnerPath, input.readFile);
|
|
19
20
|
for (const diagnosticPath of failure.diagnosticPaths) {
|
|
20
|
-
|
|
21
|
+
let node = graph.get(diagnosticPath);
|
|
22
|
+
let testInvocation;
|
|
23
|
+
if (!node && /^(?:node|tsx) [A-Za-z0-9._/-]+\.(?:cjs|js|mjs|ts|tsx)$/.test(scriptCommand.trim())
|
|
24
|
+
&& input.isTracked?.(runnerPath) && input.isTracked(diagnosticPath)
|
|
25
|
+
&& !pathAllowed(diagnosticPath, input.step.forbiddenScope)) {
|
|
26
|
+
const runner = input.readFile(runnerPath), spec = input.readFile(diagnosticPath);
|
|
27
|
+
const argv = runner.content && literalVitestInvocations(runner.content).find(args => args.slice(2).includes(diagnosticPath));
|
|
28
|
+
const catalogNames = literalMigrationCatalogNames(spec.content ?? '');
|
|
29
|
+
const migrationOutputs = (input.step.expectedOutputs ?? []).map(value => value.startsWith('path:') ? value.slice(5) : value)
|
|
30
|
+
.filter(value => /^[A-Za-z0-9._/-]+$/.test(value) && !value.split('/').some(part => part === '..' || part === '.')
|
|
31
|
+
&& /^[0-9]{4}_[a-z0-9_]+\.sql$/.test(path.posix.basename(value))
|
|
32
|
+
&& componentBoundary(value) === componentBoundary(diagnosticPath)
|
|
33
|
+
&& pathAllowed(value, input.step.allowedWrites)
|
|
34
|
+
&& !catalogNames.includes(path.posix.basename(value))).sort();
|
|
35
|
+
if (argv && runner.hash && spec.hash && catalogNames.length && migrationOutputs.length) {
|
|
36
|
+
testInvocation = { kind: 'literal-vitest-catalog', runnerHash: runner.hash, argv, migrationOutputs, catalogNames };
|
|
37
|
+
node = { hash: spec.hash, chain: [runnerPath] };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
21
40
|
if (!node || pathAllowed(diagnosticPath, input.step.allowedWrites))
|
|
22
41
|
continue;
|
|
23
42
|
const componentRoot = componentBoundary(diagnosticPath);
|
|
@@ -33,11 +52,16 @@ export function inspectFailedCheckComponentOwners(input) {
|
|
|
33
52
|
diagnosticPath,
|
|
34
53
|
componentRoot,
|
|
35
54
|
causeFingerprint: failure.causeFingerprint,
|
|
55
|
+
...(testInvocation ? { testInvocation } : {}),
|
|
36
56
|
});
|
|
37
57
|
}
|
|
38
58
|
}
|
|
39
59
|
}
|
|
40
|
-
|
|
60
|
+
// A diagnostic list may include passing suites. Only a unique missing-catalog
|
|
61
|
+
// anchor for this failed command qualifies; ambiguity grants no new scope.
|
|
62
|
+
const unambiguous = conflicts.filter(conflict => !conflict.testInvocation
|
|
63
|
+
|| conflicts.filter(other => other.command === conflict.command && other.testInvocation).length === 1);
|
|
64
|
+
return unambiguous.sort((left, right) => left.command.localeCompare(right.command)
|
|
41
65
|
|| left.ownerPath.localeCompare(right.ownerPath));
|
|
42
66
|
}
|
|
43
67
|
function buildImportGraph(runnerPath, readFile) {
|
|
@@ -92,4 +116,22 @@ export function semanticBoundaryHash(task) {
|
|
|
92
116
|
});
|
|
93
117
|
return createHash('sha256').update(material).digest('hex');
|
|
94
118
|
}
|
|
119
|
+
/** Stored invocation evidence is structurally distinct from an import chain. The
|
|
120
|
+
* containing conflict hash binds it; fresh recovery rederives it from tracked bytes. */
|
|
121
|
+
export function validLiteralTestInvocationEvidence(conflict) {
|
|
122
|
+
const proof = conflict.testInvocation;
|
|
123
|
+
if (!proof || proof.kind !== 'literal-vitest-catalog' || !/^[a-f0-9]{64}$/.test(proof.runnerHash))
|
|
124
|
+
return false;
|
|
125
|
+
const paths = proof.argv.slice(2).filter(arg => !arg.startsWith('--'));
|
|
126
|
+
return proof.argv[0] === 'vitest' && proof.argv[1] === 'run'
|
|
127
|
+
&& paths.includes(conflict.ownerPath)
|
|
128
|
+
&& paths.every(value => /^(?:[A-Za-z0-9_-]+\/)*[A-Za-z0-9_.-]+\.(?:spec|test)\.[cm]?[jt]sx?$/.test(value))
|
|
129
|
+
&& proof.argv.slice(2 + paths.length).every(arg => /^--maxWorkers=[1-9][0-9]*$/.test(arg))
|
|
130
|
+
&& proof.argv.length - paths.length <= 3
|
|
131
|
+
&& proof.catalogNames.length > 0 && proof.catalogNames.every(value => /^[0-9]{4}_[a-z0-9_]+\.sql$/.test(value))
|
|
132
|
+
&& proof.migrationOutputs.length > 0 && proof.migrationOutputs.every(value => /^[A-Za-z0-9._/-]+$/.test(value) && !value.split('/').some(part => part === '..' || part === '.')
|
|
133
|
+
&& /^[0-9]{4}_[a-z0-9_]+\.sql$/.test(path.posix.basename(value))
|
|
134
|
+
&& componentBoundary(value) === componentBoundary(conflict.ownerPath)
|
|
135
|
+
&& !proof.catalogNames.includes(path.posix.basename(value)));
|
|
136
|
+
}
|
|
95
137
|
//# sourceMappingURL=component-owner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-owner.js","sourceRoot":"","sources":["../../../src/alpha6/component-owner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,MAAM,MAAM,GAAG,oFAAoF,CAAC;AACpG,MAAM,MAAM,GAAG,8CAA8C,CAAC;
|
|
1
|
+
{"version":3,"file":"component-owner.js","sourceRoot":"","sources":["../../../src/alpha6/component-owner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { TaskState } from '../contracts.js';
|
|
2
|
+
import type { FileStateStore } from '../state/store.js';
|
|
3
|
+
/** Checkout eligibility only: never an audit, writer credential, or permission to widen scope. */
|
|
4
|
+
export declare function correctiveDecisionCheckoutEligible(store: FileStateStore, repository: string, task: TaskState, stepId: string): boolean;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { lstatSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { pathAllowed } from '../domain/validation.js';
|
|
4
|
+
import { validateTaskHistory } from '../git.js';
|
|
5
|
+
import { changedFiles, currentBranch, headCommit } from '../repository.js';
|
|
6
|
+
import { hashDirtyWorktree } from './downstream-proof.js';
|
|
7
|
+
import { effectiveStepAllowedWrites, readRemediationEvents } from './remediation.js';
|
|
8
|
+
/** Checkout eligibility only: never an audit, writer credential, or permission to widen scope. */
|
|
9
|
+
export function correctiveDecisionCheckoutEligible(store, repository, task, stepId) {
|
|
10
|
+
if (!task.taskBranch || currentBranch(repository) !== task.taskBranch)
|
|
11
|
+
return false;
|
|
12
|
+
// Includes completed Step commits and recorded system/history commits. A new
|
|
13
|
+
// unrecorded HEAD must not become a corrective audit's implicit baseline.
|
|
14
|
+
validateTaskHistory(repository, task);
|
|
15
|
+
const dirty = changedFiles(repository).sort();
|
|
16
|
+
if (dirty.length === 0)
|
|
17
|
+
return true;
|
|
18
|
+
if (task.workspaceOwner !== 'local' || task.steps.some(step => step.status === 'in_progress'))
|
|
19
|
+
return false;
|
|
20
|
+
const step = task.steps.find(candidate => candidate.id === stepId);
|
|
21
|
+
const pause = step?.failurePause;
|
|
22
|
+
if (step?.status !== 'failed' || !pause)
|
|
23
|
+
return false;
|
|
24
|
+
const terminal = readRemediationEvents(store, task).filter(event => event.stepId === stepId).at(-1);
|
|
25
|
+
if (!terminal || terminal.failureKind !== 'checks-failed'
|
|
26
|
+
|| terminal.failureEvidence.completionCommit !== headCommit(repository)
|
|
27
|
+
|| terminal.failureEvidence.checksHash !== pause.checksHash
|
|
28
|
+
|| terminal.failureEvidence.dirtyWorktreeHash !== pause.dirtyWorktreeHash
|
|
29
|
+
|| JSON.stringify(dirty) !== JSON.stringify([...pause.dirtyFiles].sort()))
|
|
30
|
+
return false;
|
|
31
|
+
const allowedWrites = effectiveStepAllowedWrites(store, task, stepId);
|
|
32
|
+
for (const file of dirty) {
|
|
33
|
+
if (!pathAllowed(file, allowedWrites) || pathAllowed(file, step.forbiddenScope))
|
|
34
|
+
return false;
|
|
35
|
+
// Do not admit symlinks (including dangling links) or directory substitutions.
|
|
36
|
+
try {
|
|
37
|
+
if (!lstatSync(path.join(repository, file)).isFile())
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
if (error.code !== 'ENOENT')
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return hashDirtyWorktree(repository, dirty) === pause.dirtyWorktreeHash;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=corrective-decision-boundary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"corrective-decision-boundary.js","sourceRoot":"","sources":["../../../src/alpha6/corrective-decision-boundary.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DownstreamProofInvalidationEvent,
|
|
1
|
+
import type { DownstreamProofInvalidationEvent, DownstreamProofReplanRecoveryEvent, TaskState } from '../contracts.js';
|
|
2
2
|
import type { FileStateStore } from '../state/store.js';
|
|
3
3
|
export interface DownstreamProofInvalidatedStep {
|
|
4
4
|
stepId: string;
|
|
@@ -20,19 +20,6 @@ export interface PreparedDownstreamProofInvalidation {
|
|
|
20
20
|
event: DownstreamProofInvalidationEvent;
|
|
21
21
|
postimage: string;
|
|
22
22
|
}
|
|
23
|
-
export interface DownstreamProofReplanRecoveryAssessment {
|
|
24
|
-
applicable: boolean;
|
|
25
|
-
eligible: boolean;
|
|
26
|
-
invalidation: DownstreamProofInvalidationEvent | null;
|
|
27
|
-
rebind: TaskState['knowledgeRebinds'][number] | null;
|
|
28
|
-
compatibility: DownstreamProofReplanCompatibility | null;
|
|
29
|
-
dependencyRecoveryCommit: string | null;
|
|
30
|
-
blockers: string[];
|
|
31
|
-
}
|
|
32
|
-
export interface PreparedDownstreamProofReplanRecovery {
|
|
33
|
-
event: DownstreamProofReplanRecoveryEvent;
|
|
34
|
-
postimage: string;
|
|
35
|
-
}
|
|
36
23
|
export interface DownstreamProofCarryoverAssessment {
|
|
37
24
|
applicable: boolean;
|
|
38
25
|
eligible: boolean;
|
|
@@ -52,17 +39,6 @@ export declare function prepareDownstreamProofInvalidation(store: FileStateStore
|
|
|
52
39
|
}, now: Date): PreparedDownstreamProofInvalidation;
|
|
53
40
|
export declare function readDownstreamProofInvalidations(store: FileStateStore, task: TaskState): DownstreamProofInvalidationEvent[];
|
|
54
41
|
export declare function downstreamProofInvalidationSidecar(): string;
|
|
55
|
-
export declare function assessDownstreamProofReplanRecovery(store: FileStateStore, repositoryRoot: string, task: TaskState, options?: {
|
|
56
|
-
historyBoundary?: string;
|
|
57
|
-
preservedHeadCommit?: string;
|
|
58
|
-
currentPlanRiskAuditExists?: boolean;
|
|
59
|
-
}): DownstreamProofReplanRecoveryAssessment;
|
|
60
|
-
export declare function prepareDownstreamProofReplanRecovery(store: FileStateStore, resultTask: TaskState, assessment: DownstreamProofReplanRecoveryAssessment, input: {
|
|
61
|
-
previousTaskRevision: number;
|
|
62
|
-
actor: string;
|
|
63
|
-
reason: string;
|
|
64
|
-
}, now: Date): PreparedDownstreamProofReplanRecovery;
|
|
65
42
|
export declare function readDownstreamProofReplanRecoveries(store: FileStateStore, task: TaskState): DownstreamProofReplanRecoveryEvent[];
|
|
66
|
-
export declare function downstreamProofReplanRecoverySidecar(): string;
|
|
67
43
|
export declare function assessDownstreamProofCarryover(store: FileStateStore, repositoryRoot: string, task: TaskState, stepId: string): DownstreamProofCarryoverAssessment;
|
|
68
44
|
export declare function hashDirtyWorktree(repositoryRoot: string, dirtyFiles: readonly string[]): string;
|
|
@@ -146,169 +146,9 @@ export function readDownstreamProofInvalidations(store, task) {
|
|
|
146
146
|
export function downstreamProofInvalidationSidecar() {
|
|
147
147
|
return SIDECAR;
|
|
148
148
|
}
|
|
149
|
-
export function assessDownstreamProofReplanRecovery(store, repositoryRoot, task, options = {}) {
|
|
150
|
-
const invalidations = readDownstreamProofInvalidations(store, task);
|
|
151
|
-
const recoveries = readDownstreamProofReplanRecoveries(store, task);
|
|
152
|
-
const invalidation = invalidations.at(-1) ?? null;
|
|
153
|
-
const rebind = task.knowledgeRebinds.at(-1) ?? null;
|
|
154
|
-
if (invalidation && recoveries.some((event) => event.invalidationEventId === invalidation.eventId
|
|
155
|
-
&& event.resultTaskRevision <= task.revision)) {
|
|
156
|
-
return emptyReplanAssessment();
|
|
157
|
-
}
|
|
158
|
-
if (!invalidation || !rebind
|
|
159
|
-
|| rebind.previousPlanHash !== invalidation.planHash
|
|
160
|
-
|| rebind.reboundPlanHash !== task.planHash
|
|
161
|
-
|| Date.parse(rebind.recordedAt) <= Date.parse(invalidation.recordedAt)) {
|
|
162
|
-
return emptyReplanAssessment();
|
|
163
|
-
}
|
|
164
|
-
const blockers = [];
|
|
165
|
-
const dirtyFiles = changedFiles(repositoryRoot).sort();
|
|
166
|
-
let dirtyWorktreeHash = null;
|
|
167
|
-
try {
|
|
168
|
-
dirtyWorktreeHash = hashDirtyWorktree(repositoryRoot, dirtyFiles);
|
|
169
|
-
}
|
|
170
|
-
catch (error) {
|
|
171
|
-
blockers.push(error instanceof Error ? error.message : String(error));
|
|
172
|
-
}
|
|
173
|
-
const sourceBinding = [...(task.dependencyProvenanceRecoveries ?? [])]
|
|
174
|
-
.reverse()
|
|
175
|
-
.map((record) => record.activeDownstreamProof)
|
|
176
|
-
.find((binding) => binding
|
|
177
|
-
&& binding.planHash === invalidation.planHash
|
|
178
|
-
&& binding.activeStepId === invalidation.activeStepId
|
|
179
|
-
&& JSON.stringify([...binding.dirtyFiles].sort()) === JSON.stringify(invalidation.dirtyFiles)
|
|
180
|
-
&& JSON.stringify([...binding.invalidatedStepIds].sort())
|
|
181
|
-
=== JSON.stringify(invalidation.invalidatedSteps.map((step) => step.stepId).sort()))
|
|
182
|
-
?? null;
|
|
183
|
-
if (!sourceBinding) {
|
|
184
|
-
blockers.push('No dependency provenance record preserves the exact active downstream-proof dirty-set binding.');
|
|
185
|
-
}
|
|
186
|
-
else if (dirtyWorktreeHash !== sourceBinding.dirtyWorktreeHash) {
|
|
187
|
-
blockers.push('Dirty file content changed after the downstream-proof invalidation boundary.');
|
|
188
|
-
}
|
|
189
|
-
if (JSON.stringify(dirtyFiles) !== JSON.stringify(invalidation.dirtyFiles)) {
|
|
190
|
-
blockers.push('Dirty files changed after the downstream-proof invalidation boundary.');
|
|
191
|
-
}
|
|
192
|
-
const registeredCompatibility = [...(task.dependencyProvenanceRecoveries ?? [])]
|
|
193
|
-
.reverse()
|
|
194
|
-
.find((record) => record.downstreamProofReplan?.invalidationEventId === invalidation.eventId
|
|
195
|
-
&& record.downstreamProofReplan.reboundPlanHash === task.planHash) ?? null;
|
|
196
|
-
const sourceHead = options.preservedHeadCommit
|
|
197
|
-
?? registeredCompatibility?.parentCommitSha
|
|
198
|
-
?? headCommit(repositoryRoot);
|
|
199
|
-
if (sourceHead !== invalidation.preservedHeadCommit) {
|
|
200
|
-
blockers.push('The recovery history boundary no longer matches the downstream-proof preserved HEAD.');
|
|
201
|
-
}
|
|
202
|
-
if (task.workspaceOwner !== 'local')
|
|
203
|
-
blockers.push('Recovery requires the recorded local Task workspace.');
|
|
204
|
-
if (!task.taskBranch || currentBranch(repositoryRoot) !== task.taskBranch) {
|
|
205
|
-
blockers.push('Current branch must equal the recorded Task branch.');
|
|
206
|
-
}
|
|
207
|
-
if (task.status !== 'awaiting_execution_authorization') {
|
|
208
|
-
blockers.push('The legacy stranded Task must still be awaiting execution authorization.');
|
|
209
|
-
}
|
|
210
|
-
if (!task.planHash || task.planHash !== rebind.reboundPlanHash) {
|
|
211
|
-
blockers.push('The current Plan must be the exact mechanically rebound legacy Plan.');
|
|
212
|
-
}
|
|
213
|
-
if (task.knowledgeMapRevision !== rebind.toKnowledgeMapRevision
|
|
214
|
-
|| task.knowledgeMapHash !== rebind.toKnowledgeMapHash) {
|
|
215
|
-
blockers.push('The current Project Knowledge binding must match the legacy rebind record.');
|
|
216
|
-
}
|
|
217
|
-
for (const invalidated of invalidation.invalidatedSteps) {
|
|
218
|
-
const step = task.steps.find((candidate) => candidate.id === invalidated.stepId);
|
|
219
|
-
if (!step || step.status !== 'planned' || step.evidence !== null
|
|
220
|
-
|| !(task.invalidatedStepCommits ?? []).includes(invalidated.evidenceCommit)) {
|
|
221
|
-
blockers.push(`Invalidated predecessor ${invalidated.stepId} no longer has the preserved planned/no-evidence posture.`);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
const activeStep = task.steps.find((step) => step.id === invalidation.activeStepId);
|
|
225
|
-
if (!activeStep || activeStep.status !== 'blocked' || activeStep.evidence !== null) {
|
|
226
|
-
blockers.push(`Former proof Step ${invalidation.activeStepId} no longer has the preserved blocked/no-evidence posture.`);
|
|
227
|
-
}
|
|
228
|
-
if (task.authorizations.some((authorization) => authorization.kind === 'execution'
|
|
229
|
-
&& authorization.decision === 'approved'
|
|
230
|
-
&& authorization.planHash === task.planHash)) {
|
|
231
|
-
blockers.push('The rebound Plan has already received execution authorization.');
|
|
232
|
-
}
|
|
233
|
-
if (options.currentPlanRiskAuditExists) {
|
|
234
|
-
blockers.push('The rebound Plan already has a recorded current Plan Risk Audit.');
|
|
235
|
-
}
|
|
236
|
-
const expectedRevision = invalidation.resultTaskRevision + (registeredCompatibility ? 2 : 1);
|
|
237
|
-
if (task.revision !== expectedRevision) {
|
|
238
|
-
blockers.push('Task revision contains changes beyond the exact invalidation, accidental rebind, and optional dependency registration sequence.');
|
|
239
|
-
}
|
|
240
|
-
if (registeredCompatibility) {
|
|
241
|
-
if (registeredCompatibility.commitSha !== headCommit(repositoryRoot)
|
|
242
|
-
|| registeredCompatibility.downstreamProofReplan?.dirtyWorktreeHash !== dirtyWorktreeHash) {
|
|
243
|
-
blockers.push('The registered dependency compatibility record does not bind the current HEAD and dirty worktree.');
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
else if (!options.historyBoundary && headCommit(repositoryRoot) !== invalidation.preservedHeadCommit) {
|
|
247
|
-
blockers.push('Unregistered Git history exists after the downstream-proof invalidation boundary.');
|
|
248
|
-
}
|
|
249
|
-
try {
|
|
250
|
-
validateTaskHistory(repositoryRoot, task, options.historyBoundary);
|
|
251
|
-
}
|
|
252
|
-
catch (error) {
|
|
253
|
-
blockers.push(error instanceof Error ? error.message : String(error));
|
|
254
|
-
}
|
|
255
|
-
const compatibility = sourceBinding && dirtyWorktreeHash
|
|
256
|
-
? {
|
|
257
|
-
invalidationEventId: invalidation.eventId,
|
|
258
|
-
activeStepId: invalidation.activeStepId,
|
|
259
|
-
sourcePlanHash: invalidation.planHash,
|
|
260
|
-
reboundPlanHash: rebind.reboundPlanHash,
|
|
261
|
-
knowledgeRebindRecordedAt: rebind.recordedAt,
|
|
262
|
-
dirtyFiles: [...invalidation.dirtyFiles],
|
|
263
|
-
dirtyWorktreeHash,
|
|
264
|
-
invalidatedStepIds: invalidation.invalidatedSteps.map((step) => step.stepId).sort(),
|
|
265
|
-
}
|
|
266
|
-
: null;
|
|
267
|
-
return {
|
|
268
|
-
applicable: true,
|
|
269
|
-
eligible: blockers.length === 0 && compatibility !== null,
|
|
270
|
-
invalidation,
|
|
271
|
-
rebind,
|
|
272
|
-
compatibility,
|
|
273
|
-
dependencyRecoveryCommit: registeredCompatibility?.commitSha ?? null,
|
|
274
|
-
blockers,
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
export function prepareDownstreamProofReplanRecovery(store, resultTask, assessment, input, now) {
|
|
278
|
-
if (!assessment.eligible || !assessment.invalidation || !assessment.rebind || !assessment.compatibility) {
|
|
279
|
-
throw new WorkflowError('TRANSITION_BLOCKED', 'Downstream-proof replan compatibility assessment is not eligible.');
|
|
280
|
-
}
|
|
281
|
-
const actor = normalizeRequired(input.actor, 'Recovery actor');
|
|
282
|
-
const reason = normalizeRequired(input.reason, 'Recovery reason');
|
|
283
|
-
const events = readDownstreamProofReplanRecoveries(store, resultTask);
|
|
284
|
-
const prepared = prepareSidecarAppend(events, {
|
|
285
|
-
eventId: `DPR-${createUlid(now.getTime())}`,
|
|
286
|
-
recordedAt: now.toISOString(),
|
|
287
|
-
taskId: resultTask.id,
|
|
288
|
-
previousTaskRevision: input.previousTaskRevision,
|
|
289
|
-
resultTaskRevision: resultTask.revision,
|
|
290
|
-
invalidationEventId: assessment.invalidation.eventId,
|
|
291
|
-
invalidationPlanHash: assessment.invalidation.planHash,
|
|
292
|
-
reboundPlanHash: assessment.rebind.reboundPlanHash,
|
|
293
|
-
knowledgeRebindRecordedAt: assessment.rebind.recordedAt,
|
|
294
|
-
dirtyFiles: [...assessment.compatibility.dirtyFiles],
|
|
295
|
-
dirtyWorktreeHash: assessment.compatibility.dirtyWorktreeHash,
|
|
296
|
-
preservedHeadCommit: headCommit(resultTask.repositoryRoot),
|
|
297
|
-
dependencyRecoveryCommit: assessment.dependencyRecoveryCommit,
|
|
298
|
-
actor,
|
|
299
|
-
reason,
|
|
300
|
-
packageVersion: PACKAGE_VERSION,
|
|
301
|
-
}, {
|
|
302
|
-
validateEvent: (event) => validateReplanRecoveryEvent(event, resultTask),
|
|
303
|
-
});
|
|
304
|
-
return { event: prepared.event, postimage: prepared.content };
|
|
305
|
-
}
|
|
306
149
|
export function readDownstreamProofReplanRecoveries(store, task) {
|
|
307
150
|
return store.readSidecarEvents(store.taskRoot(task.projectId, task.id), REPLAN_RECOVERY_SIDECAR, { validateEvent: (event) => validateReplanRecoveryEvent(event, task) });
|
|
308
151
|
}
|
|
309
|
-
export function downstreamProofReplanRecoverySidecar() {
|
|
310
|
-
return REPLAN_RECOVERY_SIDECAR;
|
|
311
|
-
}
|
|
312
152
|
export function assessDownstreamProofCarryover(store, repositoryRoot, task, stepId) {
|
|
313
153
|
const invalidation = readDownstreamProofInvalidations(store, task).at(-1) ?? null;
|
|
314
154
|
if (!invalidation || !task.planHash || task.planHash === invalidation.planHash) {
|
|
@@ -383,17 +223,6 @@ export function assessDownstreamProofCarryover(store, repositoryRoot, task, step
|
|
|
383
223
|
blockers,
|
|
384
224
|
};
|
|
385
225
|
}
|
|
386
|
-
function emptyReplanAssessment() {
|
|
387
|
-
return {
|
|
388
|
-
applicable: false,
|
|
389
|
-
eligible: false,
|
|
390
|
-
invalidation: null,
|
|
391
|
-
rebind: null,
|
|
392
|
-
compatibility: null,
|
|
393
|
-
dependencyRecoveryCommit: null,
|
|
394
|
-
blockers: [],
|
|
395
|
-
};
|
|
396
|
-
}
|
|
397
226
|
function emptyAssessment() {
|
|
398
227
|
return {
|
|
399
228
|
applicable: false,
|