codex-workflow-v2 2.0.0-beta.12.4 → 2.0.0-beta.12.6
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 +31 -4
- package/dist/src/alpha6/downstream-proof.d.ts +34 -0
- package/dist/src/alpha6/downstream-proof.js +296 -0
- package/dist/src/alpha6/downstream-proof.js.map +1 -0
- package/dist/src/cli.js +32 -1
- package/dist/src/cli.js.map +1 -1
- package/dist/src/contracts.d.ts +34 -1
- package/dist/src/dependency-provenance.d.ts +8 -1
- package/dist/src/dependency-provenance.js +36 -5
- package/dist/src/dependency-provenance.js.map +1 -1
- package/dist/src/git.d.ts +1 -1
- package/dist/src/git.js +5 -2
- package/dist/src/git.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/workflow.d.ts +8 -0
- package/dist/src/workflow.js +224 -8
- package/dist/src/workflow.js.map +1 -1
- package/docs/autonomy-guardrails.md +16 -0
- package/docs/development-flow.md +19 -0
- 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/sources/codex-workflow-v2-architecture-ru.md +27 -6
- package/docs/pdf/sources/codex-workflow-v2-chat-only-guide-ru.md +28 -8
- package/docs/pdf/sources/codex-workflow-v2-technical-reference-ru.md +42 -14
- package/docs/release.md +11 -1
- package/docs/updating-existing-project.md +37 -2
- package/docs/validation-report.md +95 -82
- package/package.json +1 -1
- package/plugins/codex-workflow-gateway/.codex-plugin/plugin.json +1 -1
- package/plugins/codex-workflow-gateway/references/protocol.md +27 -1
- package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +43 -1
- package/schemas/downstream-proof-invalidation-event.schema.json +70 -0
- package/schemas/task.schema.json +27 -0
- package/scripts/generate-pdf-docs.py +13 -2
package/README.md
CHANGED
|
@@ -24,6 +24,8 @@ automation do not import anything from the parent V1 project.
|
|
|
24
24
|
- read-only update preflight for clean checkout, running-Step, and writer-lease blockers;
|
|
25
25
|
- beta.10 bounded recovery for one exact dependency-only HEAD, including retained product commits
|
|
26
26
|
proven by intact passed strict-review and reviewer-attestation chains;
|
|
27
|
+
- beta.12.6 active-downstream-proof update bridge: one exact dependency-only Task HEAD can be
|
|
28
|
+
registered while the already-classified proof work remains dirty and its Step remains active;
|
|
27
29
|
- bounded first-failure Plan-integrity recovery for legacy/in-flight contradictions that could not
|
|
28
30
|
be rejected by the current pre-authorization feasibility gate;
|
|
29
31
|
- read-only Milestone progress projection with stable membership ordinals and replacement links;
|
|
@@ -43,7 +45,7 @@ cross-machine synchronization are not part of its contract.
|
|
|
43
45
|
Node.js 22 or newer is required. Consumers pin the exact package version:
|
|
44
46
|
|
|
45
47
|
```bash
|
|
46
|
-
npm install --save-dev --save-exact codex-workflow-v2@2.0.0-beta.12.
|
|
48
|
+
npm install --save-dev --save-exact codex-workflow-v2@2.0.0-beta.12.6
|
|
47
49
|
npx codex-workflow gateway handshake --repo .
|
|
48
50
|
npx codex-workflow doctor --repo .
|
|
49
51
|
```
|
|
@@ -187,7 +189,7 @@ sidecars:
|
|
|
187
189
|
`corrective-replan-executions.jsonl`, `step-review-events.jsonl`,
|
|
188
190
|
`reviewer-attestations.jsonl`, `remediation-events.jsonl`,
|
|
189
191
|
`corrective-decisions.jsonl`, `corrective-decision-recoveries.jsonl`,
|
|
190
|
-
`remediation-mode-recoveries.jsonl`, `handoffs.jsonl`
|
|
192
|
+
`remediation-mode-recoveries.jsonl`, `downstream-proof-invalidations.jsonl`, `handoffs.jsonl`
|
|
191
193
|
- milestone: `scope-change-events.jsonl`, `autonomy-contract-events.jsonl`
|
|
192
194
|
|
|
193
195
|
Milestone scope-change recovery also uses Milestone-local `.transactions/` journal files.
|
|
@@ -214,6 +216,31 @@ definition, Git HEAD, manifest hash, and complete dirty-file set. The recovery r
|
|
|
214
216
|
journaled corrective-replan path. It does not edit the Plan, run a second failing attempt, widen
|
|
215
217
|
`allowedWrites`, or modify the worktree.
|
|
216
218
|
|
|
219
|
+
When an active downstream proof exposes a required change in files owned by a completed transitive
|
|
220
|
+
predecessor Step, fresh `next` advertises `task downstream-proof-recover` instead of the impossible
|
|
221
|
+
`task step-complete`. The lease-bound transaction preserves worktree and HEAD, invalidates only the
|
|
222
|
+
affected predecessor completion evidence, retains its commits as historical `invalidatedStepCommits`, yields
|
|
223
|
+
C1, and returns the same Task to ordinary planning. A fresh replacement Plan, Plan Risk Audit, and
|
|
224
|
+
execution authorization are required. Unrelated dirty files, non-predecessor ownership, unregistered
|
|
225
|
+
history, or damaged invalidation evidence fail closed.
|
|
226
|
+
|
|
227
|
+
If that exact condition is already present on an older package and therefore blocks the ordinary
|
|
228
|
+
clean-checkout update, beta.12.6 provides a bounded compatibility bridge. Update the active
|
|
229
|
+
Milestone base and Task branch with separate commits that each change only `package.json` and
|
|
230
|
+
`package-lock.json`, install the exact package, and continue only when fresh `next` advertises
|
|
231
|
+
`update downstream-proof-dependency-recover`. Its read-only preflight validates the candidate at
|
|
232
|
+
`HEAD`, the previously recorded Task history at `HEAD^`, aligned runtime/declared/locked/installed/
|
|
233
|
+
base versions, absence of leases and transactions, the exact active Step, predecessor ownership,
|
|
234
|
+
and a SHA-256 binding of every dirty product file. Recovery registers only that dependency commit,
|
|
235
|
+
does not touch product bytes or end the Step, and makes the existing `task downstream-proof-recover`
|
|
236
|
+
route reachable. Unknown history, an unrelated dirty path, a non-dependency candidate, stale base,
|
|
237
|
+
or changed authority remains a hard stop.
|
|
238
|
+
|
|
239
|
+
Docker socket `EPERM`/permission errors observed inside a sandbox are access-boundary evidence, not
|
|
240
|
+
daemon-failure evidence. The gateway repeats the exact read-only probe or Plan check once with
|
|
241
|
+
sandbox escalation without consuming a remediation/infra retry. Docker Desktop restart or image
|
|
242
|
+
mutation requires separate authority and an escalated probe that actually proves daemon failure.
|
|
243
|
+
|
|
217
244
|
For a terminal split, follow the [canonical replacement stop procedure](docs/split-required-recovery.md).
|
|
218
245
|
P04-A intentionally disables structural replacement; P04-B/P05 must define the topology-preserving
|
|
219
246
|
transaction before the route can be used.
|
|
@@ -302,11 +329,11 @@ alpha regressions that must not recur are tracked in the
|
|
|
302
329
|
- [Chat-only development guide](docs/pdf/codex-workflow-v2-chat-only-guide-ru.pdf)
|
|
303
330
|
- [Deep technical reference](docs/pdf/codex-workflow-v2-technical-reference-ru.pdf)
|
|
304
331
|
|
|
305
|
-
These beta.12.
|
|
332
|
+
These beta.12.6 documents cover delegated Discovery, Milestone Autonomy Contract issuance,
|
|
306
333
|
dependency-aware Task routing, C1 credential handling, external-sealed reviews, bounded
|
|
307
334
|
Plan-integrity recovery, Task-local dependency provenance recovery, the human-confirmed legacy
|
|
308
335
|
attempt-four stop override (including append-only multi-rebind, dependency-only HEAD continuation,
|
|
309
|
-
|
|
336
|
+
evidence-accounted post-audit recovery revisions), the active-downstream-proof update bridge, and the P04-A
|
|
310
337
|
structural-replacement stop boundary. Their reviewable
|
|
311
338
|
sources live in [`docs/pdf/sources`](docs/pdf/sources), and `npm run docs:pdf:check` proves the
|
|
312
339
|
tracked binaries were generated from the current source and package version. The PDFs remain
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { DownstreamProofInvalidationEvent, TaskState } from '../contracts.js';
|
|
2
|
+
import type { FileStateStore } from '../state/store.js';
|
|
3
|
+
export interface DownstreamProofInvalidatedStep {
|
|
4
|
+
stepId: string;
|
|
5
|
+
evidenceCommit: string;
|
|
6
|
+
triggerFiles: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface DownstreamProofRecoveryAssessment {
|
|
9
|
+
applicable: boolean;
|
|
10
|
+
eligible: boolean;
|
|
11
|
+
activeStepId: string | null;
|
|
12
|
+
dirtyFiles: string[];
|
|
13
|
+
outsideActiveStepFiles: string[];
|
|
14
|
+
invalidatedSteps: DownstreamProofInvalidatedStep[];
|
|
15
|
+
preservedHeadCommit: string | null;
|
|
16
|
+
dirtyWorktreeHash: string | null;
|
|
17
|
+
blockers: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface PreparedDownstreamProofInvalidation {
|
|
20
|
+
event: DownstreamProofInvalidationEvent;
|
|
21
|
+
postimage: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function assessDownstreamProofRecovery(store: FileStateStore, repositoryRoot: string, task: TaskState, options?: {
|
|
24
|
+
historyBoundary?: string;
|
|
25
|
+
preservedHeadCommit?: string;
|
|
26
|
+
}): DownstreamProofRecoveryAssessment;
|
|
27
|
+
export declare function prepareDownstreamProofInvalidation(store: FileStateStore, resultTask: TaskState, assessment: DownstreamProofRecoveryAssessment, input: {
|
|
28
|
+
previousTaskRevision: number;
|
|
29
|
+
actor: string;
|
|
30
|
+
reason: string;
|
|
31
|
+
}, now: Date): PreparedDownstreamProofInvalidation;
|
|
32
|
+
export declare function readDownstreamProofInvalidations(store: FileStateStore, task: TaskState): DownstreamProofInvalidationEvent[];
|
|
33
|
+
export declare function downstreamProofInvalidationSidecar(): string;
|
|
34
|
+
export declare function hashDirtyWorktree(repositoryRoot: string, dirtyFiles: readonly string[]): string;
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { existsSync, lstatSync, readFileSync, readlinkSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { WorkflowError } from '../errors.js';
|
|
5
|
+
import { pathAllowed } from '../domain/validation.js';
|
|
6
|
+
import { changedFiles, currentBranch, headCommit, } from '../repository.js';
|
|
7
|
+
import { validateTaskHistory } from '../git.js';
|
|
8
|
+
import { createUlid } from '../ulid.js';
|
|
9
|
+
import { PACKAGE_VERSION } from '../version.js';
|
|
10
|
+
import { prepareSidecarAppend } from './store-sidecars.js';
|
|
11
|
+
const SIDECAR = 'downstream-proof-invalidations.jsonl';
|
|
12
|
+
const HASH_64 = /^[a-f0-9]{64}$/;
|
|
13
|
+
const GIT_HASH = /^[a-f0-9]{40}$/;
|
|
14
|
+
const EVENT_ID = /^DPI-[0-9A-HJKMNP-TV-Z]{26}$/;
|
|
15
|
+
export function assessDownstreamProofRecovery(store, repositoryRoot, task, options = {}) {
|
|
16
|
+
readDownstreamProofInvalidations(store, task);
|
|
17
|
+
const activeStep = task.steps.find((step) => step.status === 'in_progress') ?? null;
|
|
18
|
+
if (task.status !== 'in_progress' || !activeStep)
|
|
19
|
+
return emptyAssessment();
|
|
20
|
+
const dirtyFiles = changedFiles(repositoryRoot).sort();
|
|
21
|
+
let dirtyWorktreeHash = null;
|
|
22
|
+
try {
|
|
23
|
+
dirtyWorktreeHash = hashDirtyWorktree(repositoryRoot, dirtyFiles);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
return {
|
|
27
|
+
...emptyAssessment(),
|
|
28
|
+
applicable: true,
|
|
29
|
+
activeStepId: activeStep.id,
|
|
30
|
+
dirtyFiles,
|
|
31
|
+
blockers: [error instanceof Error ? error.message : String(error)],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const outsideActiveStepFiles = dirtyFiles.filter((file) => !pathAllowed(file, activeStep.allowedWrites));
|
|
35
|
+
if (outsideActiveStepFiles.length === 0) {
|
|
36
|
+
return {
|
|
37
|
+
...emptyAssessment(),
|
|
38
|
+
activeStepId: activeStep.id,
|
|
39
|
+
dirtyFiles,
|
|
40
|
+
dirtyWorktreeHash,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const blockers = [];
|
|
44
|
+
if (task.workspaceOwner !== 'local') {
|
|
45
|
+
blockers.push('Recovery requires a local Task workspace because the dirty file set is repository-local evidence.');
|
|
46
|
+
}
|
|
47
|
+
if (!task.taskBranch || currentBranch(repositoryRoot) !== task.taskBranch) {
|
|
48
|
+
blockers.push(`Current branch must equal the recorded Task branch ${task.taskBranch ?? '<missing>'}.`);
|
|
49
|
+
}
|
|
50
|
+
if (!task.planHash)
|
|
51
|
+
blockers.push('Task has no current Plan hash.');
|
|
52
|
+
if (activeStep.evidence !== null) {
|
|
53
|
+
blockers.push(`Active Step ${activeStep.id} already has completion evidence and must use strict-review recovery.`);
|
|
54
|
+
}
|
|
55
|
+
const predecessorIds = transitivePredecessors(task, activeStep.id, blockers);
|
|
56
|
+
const seedIds = new Set();
|
|
57
|
+
for (const file of outsideActiveStepFiles) {
|
|
58
|
+
const owners = task.steps.filter((step) => step.status === 'completed'
|
|
59
|
+
&& predecessorIds.has(step.id)
|
|
60
|
+
&& pathAllowed(file, step.allowedWrites));
|
|
61
|
+
if (owners.length === 0) {
|
|
62
|
+
blockers.push(`${file} is outside ${activeStep.id} and is not owned by a completed transitive predecessor.`);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
for (const owner of owners)
|
|
66
|
+
seedIds.add(owner.id);
|
|
67
|
+
}
|
|
68
|
+
const invalidatedIds = completedDependentClosure(task, seedIds, predecessorIds);
|
|
69
|
+
const invalidatedSteps = task.steps
|
|
70
|
+
.filter((step) => invalidatedIds.has(step.id))
|
|
71
|
+
.map((step) => {
|
|
72
|
+
if (!step.evidence) {
|
|
73
|
+
blockers.push(`Completed predecessor ${step.id} has no completion evidence.`);
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
stepId: step.id,
|
|
77
|
+
evidenceCommit: step.evidence?.commitSha ?? '',
|
|
78
|
+
triggerFiles: outsideActiveStepFiles.filter((file) => pathAllowed(file, step.allowedWrites)),
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
if (invalidatedSteps.length === 0)
|
|
82
|
+
blockers.push('No completed predecessor completion authority can be invalidated.');
|
|
83
|
+
try {
|
|
84
|
+
validateTaskHistory(repositoryRoot, task, options.historyBoundary);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
blockers.push(error instanceof Error ? error.message : String(error));
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
applicable: true,
|
|
91
|
+
eligible: blockers.length === 0,
|
|
92
|
+
activeStepId: activeStep.id,
|
|
93
|
+
dirtyFiles,
|
|
94
|
+
outsideActiveStepFiles,
|
|
95
|
+
invalidatedSteps,
|
|
96
|
+
preservedHeadCommit: options.preservedHeadCommit ?? headCommit(repositoryRoot),
|
|
97
|
+
dirtyWorktreeHash,
|
|
98
|
+
blockers,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
export function prepareDownstreamProofInvalidation(store, resultTask, assessment, input, now) {
|
|
102
|
+
if (!assessment.applicable || !assessment.eligible || !assessment.activeStepId || !assessment.preservedHeadCommit) {
|
|
103
|
+
throw new WorkflowError('TRANSITION_BLOCKED', 'Downstream proof recovery assessment is not eligible.', {
|
|
104
|
+
blockers: assessment.blockers,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
const actor = normalizeRequired(input.actor, 'Recovery actor');
|
|
108
|
+
const reason = normalizeRequired(input.reason, 'Recovery reason');
|
|
109
|
+
if (!resultTask.planHash)
|
|
110
|
+
throw new WorkflowError('STATE_CORRUPT', 'Recovered Task has no Plan hash.');
|
|
111
|
+
if (resultTask.revision !== input.previousTaskRevision + 1) {
|
|
112
|
+
throw new WorkflowError('STATE_CONFLICT', 'Recovered Task revision does not advance exactly once.');
|
|
113
|
+
}
|
|
114
|
+
const events = readDownstreamProofInvalidations(store, resultTask);
|
|
115
|
+
const prepared = prepareSidecarAppend(events, {
|
|
116
|
+
eventId: `DPI-${createUlid(now.getTime())}`,
|
|
117
|
+
recordedAt: now.toISOString(),
|
|
118
|
+
taskId: resultTask.id,
|
|
119
|
+
previousTaskRevision: input.previousTaskRevision,
|
|
120
|
+
resultTaskRevision: resultTask.revision,
|
|
121
|
+
planHash: resultTask.planHash,
|
|
122
|
+
activeStepId: assessment.activeStepId,
|
|
123
|
+
invalidatedSteps: assessment.invalidatedSteps.map((step) => ({
|
|
124
|
+
stepId: step.stepId,
|
|
125
|
+
evidenceCommit: step.evidenceCommit,
|
|
126
|
+
triggerFiles: [...step.triggerFiles],
|
|
127
|
+
})),
|
|
128
|
+
dirtyFiles: [...assessment.dirtyFiles],
|
|
129
|
+
preservedHeadCommit: assessment.preservedHeadCommit,
|
|
130
|
+
actor,
|
|
131
|
+
reason,
|
|
132
|
+
packageVersion: PACKAGE_VERSION,
|
|
133
|
+
}, {
|
|
134
|
+
validateEvent: (event) => validateInvalidationEvent(event, resultTask),
|
|
135
|
+
});
|
|
136
|
+
return { event: prepared.event, postimage: prepared.content };
|
|
137
|
+
}
|
|
138
|
+
export function readDownstreamProofInvalidations(store, task) {
|
|
139
|
+
return store.readSidecarEvents(store.taskRoot(task.projectId, task.id), SIDECAR, { validateEvent: (event) => validateInvalidationEvent(event, task) });
|
|
140
|
+
}
|
|
141
|
+
export function downstreamProofInvalidationSidecar() {
|
|
142
|
+
return SIDECAR;
|
|
143
|
+
}
|
|
144
|
+
function emptyAssessment() {
|
|
145
|
+
return {
|
|
146
|
+
applicable: false,
|
|
147
|
+
eligible: false,
|
|
148
|
+
activeStepId: null,
|
|
149
|
+
dirtyFiles: [],
|
|
150
|
+
outsideActiveStepFiles: [],
|
|
151
|
+
invalidatedSteps: [],
|
|
152
|
+
preservedHeadCommit: null,
|
|
153
|
+
dirtyWorktreeHash: null,
|
|
154
|
+
blockers: [],
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
export function hashDirtyWorktree(repositoryRoot, dirtyFiles) {
|
|
158
|
+
const hash = createHash('sha256');
|
|
159
|
+
for (const file of [...dirtyFiles].sort()) {
|
|
160
|
+
const absolute = path.resolve(repositoryRoot, file);
|
|
161
|
+
const relative = path.relative(repositoryRoot, absolute);
|
|
162
|
+
if (!relative || relative.startsWith('..') || path.isAbsolute(relative)) {
|
|
163
|
+
throw new WorkflowError('GIT_PRECONDITION_FAILED', `Dirty path escapes the repository boundary: ${file}`);
|
|
164
|
+
}
|
|
165
|
+
hash.update(`path\0${file}\0`);
|
|
166
|
+
if (!existsSync(absolute)) {
|
|
167
|
+
hash.update('deleted\0');
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const stat = lstatSync(absolute);
|
|
171
|
+
if (stat.isSymbolicLink()) {
|
|
172
|
+
hash.update(`symlink\0${readlinkSync(absolute)}\0`);
|
|
173
|
+
}
|
|
174
|
+
else if (stat.isFile()) {
|
|
175
|
+
hash.update('file\0');
|
|
176
|
+
hash.update(readFileSync(absolute));
|
|
177
|
+
hash.update('\0');
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
throw new WorkflowError('GIT_PRECONDITION_FAILED', `Dirty path is not a regular file or symlink: ${file}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return hash.digest('hex');
|
|
184
|
+
}
|
|
185
|
+
function transitivePredecessors(task, stepId, blockers) {
|
|
186
|
+
const byId = new Map(task.steps.map((step) => [step.id, step]));
|
|
187
|
+
const result = new Set();
|
|
188
|
+
const visiting = new Set();
|
|
189
|
+
const visit = (candidateId) => {
|
|
190
|
+
if (result.has(candidateId))
|
|
191
|
+
return;
|
|
192
|
+
if (visiting.has(candidateId)) {
|
|
193
|
+
blockers.push(`Step dependency cycle reaches ${candidateId}.`);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const candidate = byId.get(candidateId);
|
|
197
|
+
if (!candidate) {
|
|
198
|
+
blockers.push(`Step dependency references missing Step ${candidateId}.`);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
visiting.add(candidateId);
|
|
202
|
+
for (const dependency of candidate.dependencies) {
|
|
203
|
+
visit(dependency);
|
|
204
|
+
result.add(dependency);
|
|
205
|
+
}
|
|
206
|
+
visiting.delete(candidateId);
|
|
207
|
+
};
|
|
208
|
+
visit(stepId);
|
|
209
|
+
result.delete(stepId);
|
|
210
|
+
return result;
|
|
211
|
+
}
|
|
212
|
+
function completedDependentClosure(task, seedIds, predecessorIds) {
|
|
213
|
+
const result = new Set(seedIds);
|
|
214
|
+
let changed = true;
|
|
215
|
+
while (changed) {
|
|
216
|
+
changed = false;
|
|
217
|
+
for (const step of task.steps) {
|
|
218
|
+
if (step.status !== 'completed' || !predecessorIds.has(step.id) || result.has(step.id))
|
|
219
|
+
continue;
|
|
220
|
+
if (step.dependencies.some((dependency) => result.has(dependency))) {
|
|
221
|
+
result.add(step.id);
|
|
222
|
+
changed = true;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return result;
|
|
227
|
+
}
|
|
228
|
+
function validateInvalidationEvent(event, task) {
|
|
229
|
+
const expectedKeys = [
|
|
230
|
+
'activeStepId', 'actor', 'dirtyFiles', 'eventHash', 'eventId', 'invalidatedSteps', 'packageVersion',
|
|
231
|
+
'planHash', 'preservedHeadCommit', 'previousEventHash', 'previousTaskRevision', 'reason', 'recordedAt',
|
|
232
|
+
'resultTaskRevision', 'taskId',
|
|
233
|
+
];
|
|
234
|
+
if (!event || typeof event !== 'object' || Array.isArray(event)
|
|
235
|
+
|| JSON.stringify(Object.keys(event).sort()) !== JSON.stringify(expectedKeys.sort())) {
|
|
236
|
+
throw new WorkflowError('STATE_CORRUPT', 'Downstream proof invalidation event contains unexpected fields.');
|
|
237
|
+
}
|
|
238
|
+
if (typeof event.eventId !== 'string' || !EVENT_ID.test(event.eventId)) {
|
|
239
|
+
throw new WorkflowError('STATE_CORRUPT', 'Downstream proof invalidation eventId is invalid.');
|
|
240
|
+
}
|
|
241
|
+
if (event.taskId !== task.id)
|
|
242
|
+
throw new WorkflowError('STATE_CORRUPT', 'Downstream proof invalidation Task identity mismatch.');
|
|
243
|
+
if (!Number.isInteger(event.previousTaskRevision) || event.previousTaskRevision < 1
|
|
244
|
+
|| event.resultTaskRevision !== event.previousTaskRevision + 1
|
|
245
|
+
|| event.resultTaskRevision > task.revision) {
|
|
246
|
+
throw new WorkflowError('STATE_CORRUPT', 'Downstream proof invalidation revision binding is invalid.');
|
|
247
|
+
}
|
|
248
|
+
if (typeof event.planHash !== 'string' || !HASH_64.test(event.planHash)) {
|
|
249
|
+
throw new WorkflowError('STATE_CORRUPT', 'Downstream proof invalidation planHash is invalid.');
|
|
250
|
+
}
|
|
251
|
+
if (typeof event.preservedHeadCommit !== 'string' || !GIT_HASH.test(event.preservedHeadCommit)) {
|
|
252
|
+
throw new WorkflowError('STATE_CORRUPT', 'Downstream proof invalidation preservedHeadCommit is invalid.');
|
|
253
|
+
}
|
|
254
|
+
for (const [value, label] of [
|
|
255
|
+
[event.activeStepId, 'activeStepId'],
|
|
256
|
+
[event.actor, 'actor'],
|
|
257
|
+
[event.reason, 'reason'],
|
|
258
|
+
[event.packageVersion, 'packageVersion'],
|
|
259
|
+
]) {
|
|
260
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
261
|
+
throw new WorkflowError('STATE_CORRUPT', `Downstream proof invalidation ${label} is required.`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (!Array.isArray(event.dirtyFiles) || event.dirtyFiles.length === 0
|
|
265
|
+
|| event.dirtyFiles.some((file) => typeof file !== 'string' || !file.trim())
|
|
266
|
+
|| new Set(event.dirtyFiles).size !== event.dirtyFiles.length
|
|
267
|
+
|| JSON.stringify(event.dirtyFiles) !== JSON.stringify([...event.dirtyFiles].sort())) {
|
|
268
|
+
throw new WorkflowError('STATE_CORRUPT', 'Downstream proof invalidation dirtyFiles are invalid.');
|
|
269
|
+
}
|
|
270
|
+
if (!Array.isArray(event.invalidatedSteps) || event.invalidatedSteps.length === 0) {
|
|
271
|
+
throw new WorkflowError('STATE_CORRUPT', 'Downstream proof invalidation must identify invalidated Steps.');
|
|
272
|
+
}
|
|
273
|
+
const stepIds = new Set();
|
|
274
|
+
for (const step of event.invalidatedSteps) {
|
|
275
|
+
if (!step || typeof step !== 'object' || Array.isArray(step)
|
|
276
|
+
|| JSON.stringify(Object.keys(step).sort()) !== JSON.stringify(['evidenceCommit', 'stepId', 'triggerFiles'])) {
|
|
277
|
+
throw new WorkflowError('STATE_CORRUPT', 'Downstream proof invalidated Step contains unexpected fields.');
|
|
278
|
+
}
|
|
279
|
+
if (typeof step.stepId !== 'string' || !step.stepId.trim() || stepIds.has(step.stepId)
|
|
280
|
+
|| typeof step.evidenceCommit !== 'string' || !GIT_HASH.test(step.evidenceCommit)
|
|
281
|
+
|| !(task.invalidatedStepCommits ?? []).includes(step.evidenceCommit)
|
|
282
|
+
|| !Array.isArray(step.triggerFiles)
|
|
283
|
+
|| new Set(step.triggerFiles).size !== step.triggerFiles.length
|
|
284
|
+
|| step.triggerFiles.some((file) => typeof file !== 'string' || !event.dirtyFiles.includes(file))) {
|
|
285
|
+
throw new WorkflowError('STATE_CORRUPT', 'Downstream proof invalidated Step evidence is invalid.');
|
|
286
|
+
}
|
|
287
|
+
stepIds.add(step.stepId);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
function normalizeRequired(value, label) {
|
|
291
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
292
|
+
throw new WorkflowError('INVALID_ARGUMENT', `${label} is required.`);
|
|
293
|
+
}
|
|
294
|
+
return value.trim();
|
|
295
|
+
}
|
|
296
|
+
//# sourceMappingURL=downstream-proof.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"downstream-proof.js","sourceRoot":"","sources":["../../../src/alpha6/downstream-proof.ts"],"names":[],"mappings":"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"}
|
package/dist/src/cli.js
CHANGED
|
@@ -15,7 +15,14 @@ import { PACKAGE_NAME, PACKAGE_VERSION } from './version.js';
|
|
|
15
15
|
import { PROTOCOL_VERSION, STATE_SCHEMA_VERSION } from './contracts.js';
|
|
16
16
|
const CLI_ACTIONS = {
|
|
17
17
|
gateway: ['handshake'],
|
|
18
|
-
update: [
|
|
18
|
+
update: [
|
|
19
|
+
'preflight',
|
|
20
|
+
'rescue-preflight',
|
|
21
|
+
'dependency-provenance-preflight',
|
|
22
|
+
'dependency-provenance-recover',
|
|
23
|
+
'downstream-proof-dependency-preflight',
|
|
24
|
+
'downstream-proof-dependency-recover',
|
|
25
|
+
],
|
|
19
26
|
delegation: ['prepare', 'grant', 'list', 'show', 'revoke'],
|
|
20
27
|
'project-memory': ['scan', 'show', 'status', 'approve', 'reconcile'],
|
|
21
28
|
state: ['migrate', 'adoption-prepare', 'adoption-apply'],
|
|
@@ -43,6 +50,7 @@ const CLI_ACTIONS = {
|
|
|
43
50
|
'corrective-decision-recover',
|
|
44
51
|
'remediation-mode-recover',
|
|
45
52
|
'plan-integrity-recover',
|
|
53
|
+
'downstream-proof-recover',
|
|
46
54
|
'stop-override-prepare',
|
|
47
55
|
'stop-override-apply',
|
|
48
56
|
'corrective-decision',
|
|
@@ -92,6 +100,14 @@ const CLI_HELP_SPECS = {
|
|
|
92
100
|
requiredOptions: ['--id', '--expected-revision', '--actor', '--reason'],
|
|
93
101
|
optionalOptions: ['--repo', '--json'],
|
|
94
102
|
},
|
|
103
|
+
'update downstream-proof-dependency-preflight': {
|
|
104
|
+
requiredOptions: ['--id'],
|
|
105
|
+
optionalOptions: ['--repo', '--json'],
|
|
106
|
+
},
|
|
107
|
+
'update downstream-proof-dependency-recover': {
|
|
108
|
+
requiredOptions: ['--id', '--expected-revision', '--actor', '--reason'],
|
|
109
|
+
optionalOptions: ['--repo', '--json'],
|
|
110
|
+
},
|
|
95
111
|
'milestone progress': {
|
|
96
112
|
requiredOptions: ['--id'],
|
|
97
113
|
optionalOptions: ['--repo', '--json'],
|
|
@@ -128,6 +144,10 @@ const CLI_HELP_SPECS = {
|
|
|
128
144
|
requiredOptions: ['--id', '--step', '--expected-revision', '--actor'],
|
|
129
145
|
optionalOptions: ['--writer-token', '--repo', '--json'],
|
|
130
146
|
},
|
|
147
|
+
'task downstream-proof-recover': {
|
|
148
|
+
requiredOptions: ['--id', '--expected-revision', '--actor', '--writer-token', '--reason'],
|
|
149
|
+
optionalOptions: ['--repo', '--json'],
|
|
150
|
+
},
|
|
131
151
|
'task stop-override-prepare': {
|
|
132
152
|
requiredOptions: ['--id', '--step', '--expected-revision', '--actor', '--reason'],
|
|
133
153
|
optionalOptions: ['--repo', '--json'],
|
|
@@ -382,6 +402,8 @@ function workflowCapabilities() {
|
|
|
382
402
|
'retained-reviewed-history-recovery-v1',
|
|
383
403
|
'milestone-progress-projection-v1',
|
|
384
404
|
'bounded-plan-integrity-recovery-v1',
|
|
405
|
+
'downstream-proof-predecessor-recovery-v1',
|
|
406
|
+
'active-downstream-proof-dependency-recovery-v1',
|
|
385
407
|
'task-mechanical-feasibility-v1',
|
|
386
408
|
'strict-reviewer-v1',
|
|
387
409
|
'legacy-snapshot-v1',
|
|
@@ -468,6 +490,12 @@ async function dispatch(args) {
|
|
|
468
490
|
if (noun === 'update' && action === 'dependency-provenance-recover') {
|
|
469
491
|
return workflow.recoverDependencyProvenance(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'reason'));
|
|
470
492
|
}
|
|
493
|
+
if (noun === 'update' && action === 'downstream-proof-dependency-preflight') {
|
|
494
|
+
return workflow.activeDownstreamProofDependencyRecoveryPreflight(repo, required(args, 'id'));
|
|
495
|
+
}
|
|
496
|
+
if (noun === 'update' && action === 'downstream-proof-dependency-recover') {
|
|
497
|
+
return workflow.recoverActiveDownstreamProofDependencyProvenance(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'reason'));
|
|
498
|
+
}
|
|
471
499
|
if (noun === 'delegation' && action === 'prepare') {
|
|
472
500
|
return workflow.prepareDelegation(repo, jsonFile(args));
|
|
473
501
|
}
|
|
@@ -709,6 +737,9 @@ async function dispatch(args) {
|
|
|
709
737
|
if (noun === 'task' && action === 'plan-integrity-recover') {
|
|
710
738
|
return workflow.recoverPlanIntegrity(repo, required(args, 'id'), required(args, 'step'), revision(args), required(args, 'actor'), option(args, 'writer-token') ?? null);
|
|
711
739
|
}
|
|
740
|
+
if (noun === 'task' && action === 'downstream-proof-recover') {
|
|
741
|
+
return workflow.recoverDownstreamProof(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'writer-token'), required(args, 'reason'));
|
|
742
|
+
}
|
|
712
743
|
if (noun === 'task' && action === 'stop-override-prepare') {
|
|
713
744
|
return workflow.prepareTaskStopOverride(repo, required(args, 'id'), required(args, 'step'), revision(args), required(args, 'actor'), required(args, 'reason'));
|
|
714
745
|
}
|