codex-workflow-v2 2.0.0-beta.12.11 → 2.0.0-beta.12.12
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 +5 -4
- package/dist/src/alpha6/mechanical-feasibility.js +28 -12
- package/dist/src/alpha6/mechanical-feasibility.js.map +1 -1
- package/dist/src/alpha6/npm-check-contract.d.ts +11 -0
- package/dist/src/alpha6/npm-check-contract.js +36 -0
- package/dist/src/alpha6/npm-check-contract.js.map +1 -0
- package/dist/src/alpha6/plan-integrity.js +82 -26
- package/dist/src/alpha6/plan-integrity.js.map +1 -1
- package/dist/src/alpha6/remediation.js +88 -40
- package/dist/src/alpha6/remediation.js.map +1 -1
- package/dist/src/cli.js +25 -0
- package/dist/src/cli.js.map +1 -1
- package/dist/src/contracts.d.ts +37 -3
- package/dist/src/dependency-provenance.d.ts +3 -3
- package/dist/src/dependency-provenance.js +21 -6
- package/dist/src/dependency-provenance.js.map +1 -1
- package/dist/src/lifecycle/corrective-replan.js +1 -1
- package/dist/src/lifecycle/corrective-replan.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 +3 -0
- package/dist/src/workflow.js +222 -12
- package/dist/src/workflow.js.map +1 -1
- 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 +14 -5
- package/docs/pdf/sources/codex-workflow-v2-chat-only-guide-ru.md +17 -7
- package/docs/pdf/sources/codex-workflow-v2-technical-reference-ru.md +34 -10
- package/docs/release.md +3 -2
- package/docs/updating-existing-project.md +25 -0
- package/docs/validation-report.md +117 -96
- package/package.json +1 -1
- package/schemas/corrective-decision-event.schema.json +57 -10
- package/schemas/task.schema.json +23 -0
package/dist/src/workflow.d.ts
CHANGED
|
@@ -250,11 +250,14 @@ export declare class WorkflowService {
|
|
|
250
250
|
recoverHistoricalStepProvenance(repository: string, taskId: string, expectedRevision: number, commitSha: string, actor: string, reason: string): TaskState;
|
|
251
251
|
activeDownstreamProofDependencyRecoveryPreflight(repository: string, taskId: string): DependencyProvenanceRecoveryPreflight;
|
|
252
252
|
downstreamProofReplanUpdatePreflight(repository: string, taskId: string): Record<string, unknown>;
|
|
253
|
+
planIntegrityUpdatePreflight(repository: string, taskId: string): Record<string, unknown>;
|
|
254
|
+
planIntegrityDependencyRecoveryPreflight(repository: string, taskId: string): DependencyProvenanceRecoveryPreflight;
|
|
253
255
|
downstreamProofReplanDependencyRecoveryPreflight(repository: string, taskId: string): DependencyProvenanceRecoveryPreflight;
|
|
254
256
|
recoverDependencyProvenance(repository: string, taskId: string, expectedRevision: number, actor: string, reason: string): TaskState;
|
|
255
257
|
recoverActiveDownstreamProofDependencyProvenance(repository: string, taskId: string, expectedRevision: number, actor: string, reason: string): TaskState;
|
|
256
258
|
recoverDownstreamProofReplanDependencyProvenance(repository: string, taskId: string, expectedRevision: number, actor: string, reason: string): TaskState;
|
|
257
259
|
recoverHistoricalStepDependencyProvenance(repository: string, taskId: string, expectedRevision: number, actor: string, reason: string): TaskState;
|
|
260
|
+
recoverPlanIntegrityDependencyProvenance(repository: string, taskId: string, expectedRevision: number, actor: string, reason: string): TaskState;
|
|
258
261
|
private recoverDependencyProvenanceCandidate;
|
|
259
262
|
milestoneProgress(repository: string, milestoneId: string): MilestoneProgressProjection;
|
|
260
263
|
alpha6StrictReviewRescuePreflight(repository: string): Alpha6StrictReviewRescuePreflight;
|
package/dist/src/workflow.js
CHANGED
|
@@ -3013,8 +3013,6 @@ export class WorkflowService {
|
|
|
3013
3013
|
const task = this.store.readTask(context.identity.projectId, taskId);
|
|
3014
3014
|
assertExpectedRevision(task, expectedRevision);
|
|
3015
3015
|
this.requireExecutionAdoptionPosture(context.identity, taskId);
|
|
3016
|
-
this.assertExecutionAuthorizationFresh(task, context.identity.repositoryRoot);
|
|
3017
|
-
this.assertTaskKnowledgeBinding(context.identity.repositoryRoot, task);
|
|
3018
3016
|
assertTaskBranch(context.identity.repositoryRoot, task);
|
|
3019
3017
|
this.proveOptionalWriterLeaseToken(context, taskId, writerToken);
|
|
3020
3018
|
this.assertTaskMutationAllowedByHandoff(task, actor, writerToken);
|
|
@@ -3046,6 +3044,20 @@ export class WorkflowService {
|
|
|
3046
3044
|
blockers: assessment.blockers,
|
|
3047
3045
|
});
|
|
3048
3046
|
}
|
|
3047
|
+
const remediationEventIds = assessment.evidence.kind === 'missing-npm-script-outside-allowed-writes'
|
|
3048
|
+
? [assessment.evidence.remediationEventId]
|
|
3049
|
+
: assessment.evidence.remediationEvents.map((event) => event.eventId);
|
|
3050
|
+
const compatibility = [...(task.dependencyProvenanceRecoveries ?? [])].reverse().find((record) => record.commitSha === headCommit(context.identity.repositoryRoot)
|
|
3051
|
+
&& record.packageVersion === PACKAGE_VERSION
|
|
3052
|
+
&& task.systemCommits.includes(record.commitSha)
|
|
3053
|
+
&& record.planIntegrity?.stepId === stepId
|
|
3054
|
+
&& record.planIntegrity.planHash === task.planHash
|
|
3055
|
+
&& canonicalJsonStringify(record.planIntegrity.remediationEventIds) === canonicalJsonStringify(remediationEventIds)
|
|
3056
|
+
&& record.planIntegrity.dirtyWorktreeHash === hashDirtyWorktree(context.identity.repositoryRoot, record.planIntegrity.dirtyFiles));
|
|
3057
|
+
if (!compatibility) {
|
|
3058
|
+
this.assertExecutionAuthorizationFresh(task, context.identity.repositoryRoot);
|
|
3059
|
+
this.assertTaskKnowledgeBinding(context.identity.repositoryRoot, task);
|
|
3060
|
+
}
|
|
3049
3061
|
const event = appendPlanIntegrityRecoveryDecision(this.store, task, stepId, defaultPlanIntegrityRecoveryActor(task.id), assessment.evidence, this.now());
|
|
3050
3062
|
return { assessment, event };
|
|
3051
3063
|
}
|
|
@@ -3610,6 +3622,115 @@ export class WorkflowService {
|
|
|
3610
3622
|
blockers,
|
|
3611
3623
|
};
|
|
3612
3624
|
}
|
|
3625
|
+
planIntegrityUpdatePreflight(repository, taskId) {
|
|
3626
|
+
const snapshot = this.observationSnapshot(repository);
|
|
3627
|
+
if (snapshot.observation.kind !== 'assessment') {
|
|
3628
|
+
throw new WorkflowError('TRANSITION_BLOCKED', 'Plan-integrity update preflight requires a coherent observation boundary.', {
|
|
3629
|
+
observation: snapshot.observation,
|
|
3630
|
+
});
|
|
3631
|
+
}
|
|
3632
|
+
const task = snapshot.tasks.find((candidate) => candidate.id === taskId);
|
|
3633
|
+
if (!task)
|
|
3634
|
+
throw new WorkflowError('NOT_FOUND', `Task ${taskId} was not found in this repository.`);
|
|
3635
|
+
const assessments = task.steps
|
|
3636
|
+
.filter((step) => step.status === 'failed')
|
|
3637
|
+
.map((step) => assessPlanIntegrityRecovery(this.store, snapshot.identity.repositoryRoot, task, step.id))
|
|
3638
|
+
.filter((assessment) => assessment.applicable);
|
|
3639
|
+
const assessment = assessments.length === 1 ? assessments[0] : null;
|
|
3640
|
+
const versions = inspectWorkflowVersions(snapshot.identity.repositoryRoot, [task.baseBranch]);
|
|
3641
|
+
const sourceVersion = '2.0.0-beta.12.11';
|
|
3642
|
+
const versionSurfaces = {
|
|
3643
|
+
declared: versions.declared,
|
|
3644
|
+
locked: versions.locked,
|
|
3645
|
+
installed: versions.installed,
|
|
3646
|
+
currentBranch: versions.currentBranch,
|
|
3647
|
+
baseBranch: versions.milestoneBases.find((base) => base.branch === task.baseBranch)?.version ?? null,
|
|
3648
|
+
};
|
|
3649
|
+
const blockers = [
|
|
3650
|
+
...(assessments.length > 1 ? ['Exactly one failed Step may expose a Plan-integrity conflict.'] : []),
|
|
3651
|
+
...(assessment?.blockers ?? ['No eligible Plan-integrity conflict was found.']),
|
|
3652
|
+
...(String(PACKAGE_VERSION) === sourceVersion ? ['Recovery runner must be newer than the beta.12.11 source package.'] : []),
|
|
3653
|
+
...Object.entries(versionSurfaces)
|
|
3654
|
+
.filter(([, version]) => version !== sourceVersion)
|
|
3655
|
+
.map(([surface]) => `${surface} Workflow version must equal the stranded source ${sourceVersion}.`),
|
|
3656
|
+
...(snapshot.leases.length > 0 ? ['No active or stale Task writer lease may exist.'] : []),
|
|
3657
|
+
...observationPreflightBlockers(snapshot.observation),
|
|
3658
|
+
];
|
|
3659
|
+
return {
|
|
3660
|
+
readOnly: true,
|
|
3661
|
+
eligible: Boolean(assessment?.eligible) && blockers.length === 0,
|
|
3662
|
+
action: assessment?.eligible && blockers.length === 0 ? 'update plan-integrity-transport' : null,
|
|
3663
|
+
projectId: task.projectId,
|
|
3664
|
+
taskId: task.id,
|
|
3665
|
+
taskRevision: task.revision,
|
|
3666
|
+
stepId: assessment?.stepId ?? null,
|
|
3667
|
+
sourceVersion,
|
|
3668
|
+
targetVersion: PACKAGE_VERSION,
|
|
3669
|
+
taskBranch: task.taskBranch,
|
|
3670
|
+
baseBranch: task.baseBranch,
|
|
3671
|
+
dirtyFiles: assessment?.evidence?.changedFiles ?? [],
|
|
3672
|
+
conflictHash: assessment?.evidence?.conflictHash ?? null,
|
|
3673
|
+
requiredTransport: [
|
|
3674
|
+
'Commit only package.json and package-lock.json on the active Milestone base.',
|
|
3675
|
+
'Fast-forward or apply only that dependency commit to the Task branch while preserving all product bytes.',
|
|
3676
|
+
'Install the exact target package, then follow fresh next to Plan-integrity dependency registration.',
|
|
3677
|
+
],
|
|
3678
|
+
blockers,
|
|
3679
|
+
};
|
|
3680
|
+
}
|
|
3681
|
+
planIntegrityDependencyRecoveryPreflight(repository, taskId) {
|
|
3682
|
+
const snapshot = this.observationSnapshot(repository);
|
|
3683
|
+
if (snapshot.observation.kind !== 'assessment') {
|
|
3684
|
+
throw new WorkflowError('TRANSITION_BLOCKED', 'Plan-integrity dependency recovery requires a coherent observation boundary.', {
|
|
3685
|
+
observation: snapshot.observation,
|
|
3686
|
+
});
|
|
3687
|
+
}
|
|
3688
|
+
const task = snapshot.tasks.find((candidate) => candidate.id === taskId);
|
|
3689
|
+
if (!task)
|
|
3690
|
+
throw new WorkflowError('NOT_FOUND', `Task ${taskId} was not found in this repository.`);
|
|
3691
|
+
const assessmentBlockers = [];
|
|
3692
|
+
const assessments = task.steps
|
|
3693
|
+
.filter((step) => step.status === 'failed')
|
|
3694
|
+
.flatMap((step) => {
|
|
3695
|
+
try {
|
|
3696
|
+
return [assessPlanIntegrityRecovery(this.store, snapshot.identity.repositoryRoot, task, step.id)];
|
|
3697
|
+
}
|
|
3698
|
+
catch (error) {
|
|
3699
|
+
if (error instanceof WorkflowError && error.code === 'STATE_CORRUPT') {
|
|
3700
|
+
assessmentBlockers.push(`Plan-integrity compatibility cannot be assessed until the existing remediation history is repaired: ${error.message}`);
|
|
3701
|
+
return [];
|
|
3702
|
+
}
|
|
3703
|
+
throw error;
|
|
3704
|
+
}
|
|
3705
|
+
})
|
|
3706
|
+
.filter((assessment) => assessment.applicable && assessment.eligible && assessment.evidence);
|
|
3707
|
+
const assessment = assessments.length === 1 ? assessments[0] : null;
|
|
3708
|
+
if (!assessment?.evidence || !task.planHash) {
|
|
3709
|
+
const ordinary = this.inspectDependencyProvenanceCandidate(snapshot, task);
|
|
3710
|
+
return {
|
|
3711
|
+
...ordinary,
|
|
3712
|
+
eligible: false,
|
|
3713
|
+
action: null,
|
|
3714
|
+
planIntegrity: null,
|
|
3715
|
+
blockers: [...new Set([
|
|
3716
|
+
...ordinary.blockers,
|
|
3717
|
+
...assessmentBlockers,
|
|
3718
|
+
'The dependency candidate must preserve one exact eligible Plan-integrity conflict.',
|
|
3719
|
+
])],
|
|
3720
|
+
};
|
|
3721
|
+
}
|
|
3722
|
+
const compatibility = {
|
|
3723
|
+
stepId: assessment.stepId,
|
|
3724
|
+
planHash: task.planHash,
|
|
3725
|
+
conflictHash: assessment.evidence.conflictHash,
|
|
3726
|
+
dirtyFiles: [...assessment.evidence.changedFiles],
|
|
3727
|
+
dirtyWorktreeHash: hashDirtyWorktree(snapshot.identity.repositoryRoot, assessment.evidence.changedFiles),
|
|
3728
|
+
remediationEventIds: assessment.evidence.kind === 'missing-npm-script-outside-allowed-writes'
|
|
3729
|
+
? [assessment.evidence.remediationEventId]
|
|
3730
|
+
: assessment.evidence.remediationEvents.map((event) => event.eventId),
|
|
3731
|
+
};
|
|
3732
|
+
return this.inspectDependencyProvenanceCandidate(snapshot, task, null, null, null, compatibility);
|
|
3733
|
+
}
|
|
3613
3734
|
downstreamProofReplanDependencyRecoveryPreflight(repository, taskId) {
|
|
3614
3735
|
const snapshot = this.observationSnapshot(repository);
|
|
3615
3736
|
if (snapshot.observation.kind !== 'assessment') {
|
|
@@ -3664,6 +3785,9 @@ export class WorkflowService {
|
|
|
3664
3785
|
recoverHistoricalStepDependencyProvenance(repository, taskId, expectedRevision, actor, reason) {
|
|
3665
3786
|
return this.recoverDependencyProvenanceCandidate(repository, taskId, expectedRevision, actor, reason, 'historical-step');
|
|
3666
3787
|
}
|
|
3788
|
+
recoverPlanIntegrityDependencyProvenance(repository, taskId, expectedRevision, actor, reason) {
|
|
3789
|
+
return this.recoverDependencyProvenanceCandidate(repository, taskId, expectedRevision, actor, reason, 'plan-integrity');
|
|
3790
|
+
}
|
|
3667
3791
|
recoverDependencyProvenanceCandidate(repository, taskId, expectedRevision, actor, reason, recoveryMode) {
|
|
3668
3792
|
const normalizedActor = actor.trim();
|
|
3669
3793
|
const normalizedReason = reason.trim();
|
|
@@ -3680,7 +3804,9 @@ export class WorkflowService {
|
|
|
3680
3804
|
? Boolean(record.downstreamProofReplan)
|
|
3681
3805
|
: recoveryMode === 'historical-step'
|
|
3682
3806
|
? Boolean(record.historicalStepProvenance)
|
|
3683
|
-
:
|
|
3807
|
+
: recoveryMode === 'plan-integrity'
|
|
3808
|
+
? Boolean(record.planIntegrity)
|
|
3809
|
+
: Boolean(record.activeDownstreamProof) === recoveryMode));
|
|
3684
3810
|
if (prior && current.systemCommits.includes(currentHead))
|
|
3685
3811
|
return current;
|
|
3686
3812
|
assertExpectedRevision(current, expectedRevision);
|
|
@@ -3692,17 +3818,22 @@ export class WorkflowService {
|
|
|
3692
3818
|
? this.downstreamProofReplanDependencyRecoveryPreflight(repository, taskId)
|
|
3693
3819
|
: recoveryMode === 'historical-step'
|
|
3694
3820
|
? this.historicalStepDependencyRecoveryPreflight(repository, taskId)
|
|
3695
|
-
: recoveryMode
|
|
3696
|
-
? this.
|
|
3697
|
-
:
|
|
3821
|
+
: recoveryMode === 'plan-integrity'
|
|
3822
|
+
? this.planIntegrityDependencyRecoveryPreflight(repository, taskId)
|
|
3823
|
+
: recoveryMode
|
|
3824
|
+
? this.activeDownstreamProofDependencyRecoveryPreflight(repository, taskId)
|
|
3825
|
+
: this.inspectDependencyProvenanceCandidate(snapshot, task);
|
|
3698
3826
|
if (!preflight.eligible || !preflight.commitSha || !preflight.parentCommitSha) {
|
|
3699
3827
|
throw new WorkflowError('GIT_PRECONDITION_FAILED', 'The bounded dependency provenance recovery preflight failed.', {
|
|
3700
3828
|
taskId,
|
|
3701
3829
|
blockers: preflight.blockers,
|
|
3702
3830
|
});
|
|
3703
3831
|
}
|
|
3704
|
-
|
|
3832
|
+
const now = this.now();
|
|
3833
|
+
const nextTask = {
|
|
3705
3834
|
...task,
|
|
3835
|
+
revision: task.revision + 1,
|
|
3836
|
+
updatedAt: now.toISOString(),
|
|
3706
3837
|
systemCommits: [...task.systemCommits, preflight.commitSha],
|
|
3707
3838
|
dependencyProvenanceRecoveries: [
|
|
3708
3839
|
...(task.dependencyProvenanceRecoveries ?? []),
|
|
@@ -3714,7 +3845,7 @@ export class WorkflowService {
|
|
|
3714
3845
|
files: ['package-lock.json', 'package.json'],
|
|
3715
3846
|
actor: normalizedActor,
|
|
3716
3847
|
reason: normalizedReason,
|
|
3717
|
-
recordedAt:
|
|
3848
|
+
recordedAt: now.toISOString(),
|
|
3718
3849
|
retainedHistoricalCommits: preflight.retainedHistoricalCommits,
|
|
3719
3850
|
...(preflight.activeDownstreamProof
|
|
3720
3851
|
? { activeDownstreamProof: preflight.activeDownstreamProof }
|
|
@@ -3725,9 +3856,68 @@ export class WorkflowService {
|
|
|
3725
3856
|
...(preflight.historicalStepProvenance
|
|
3726
3857
|
? { historicalStepProvenance: preflight.historicalStepProvenance }
|
|
3727
3858
|
: {}),
|
|
3859
|
+
...(preflight.planIntegrity
|
|
3860
|
+
? { planIntegrity: preflight.planIntegrity }
|
|
3861
|
+
: {}),
|
|
3728
3862
|
},
|
|
3729
3863
|
],
|
|
3730
|
-
}
|
|
3864
|
+
};
|
|
3865
|
+
if (recoveryMode !== 'plan-integrity' || !preflight.planIntegrity) {
|
|
3866
|
+
return context.store.writeTask({ ...nextTask, revision: task.revision }, expectedRevision);
|
|
3867
|
+
}
|
|
3868
|
+
const currentKnowledgeMap = this.store.readKnowledgeMap(task.projectId);
|
|
3869
|
+
const scannedKnowledgeMap = scanProjectKnowledge(context.identity.repositoryRoot, task.projectId, now);
|
|
3870
|
+
const inspectedKnowledgeMap = inspectKnowledgeMap(currentKnowledgeMap, scannedKnowledgeMap);
|
|
3871
|
+
let refreshedKnowledgeMap = null;
|
|
3872
|
+
if (inspectedKnowledgeMap.status !== 'active' || !inspectedKnowledgeMap.approval) {
|
|
3873
|
+
const knowledgeRefresh = inspectDependencyKnowledgeRefresh(context.identity.repositoryRoot, task.baseBranch, currentKnowledgeMap, inspectedKnowledgeMap, preflight.planIntegrity.dirtyFiles);
|
|
3874
|
+
if (!knowledgeRefresh.eligible) {
|
|
3875
|
+
throw new WorkflowError('TRANSITION_BLOCKED', 'Plan-integrity dependency recovery cannot bypass unrelated Project Knowledge drift.', {
|
|
3876
|
+
taskId,
|
|
3877
|
+
dependencyKnowledgeRefresh: knowledgeRefresh,
|
|
3878
|
+
});
|
|
3879
|
+
}
|
|
3880
|
+
const reconciled = reconcileKnowledgeMap(currentKnowledgeMap, scannedKnowledgeMap);
|
|
3881
|
+
const approved = applyKnowledgeSelections(reconciled, [], normalizedActor, now);
|
|
3882
|
+
if (!approved.approval) {
|
|
3883
|
+
throw new WorkflowError('STATE_CORRUPT', 'Plan-integrity dependency Knowledge refresh produced no approval evidence.');
|
|
3884
|
+
}
|
|
3885
|
+
refreshedKnowledgeMap = {
|
|
3886
|
+
...approved,
|
|
3887
|
+
revision: currentKnowledgeMap.revision + 2,
|
|
3888
|
+
createdAt: currentKnowledgeMap.createdAt,
|
|
3889
|
+
updatedAt: now.toISOString(),
|
|
3890
|
+
approval: { ...approved.approval, authorizationMode: 'corrective-derived' },
|
|
3891
|
+
};
|
|
3892
|
+
}
|
|
3893
|
+
const projectRoot = this.store.projectRoot(task.projectId);
|
|
3894
|
+
const relative = (absolute) => path.relative(projectRoot, absolute).split(path.sep).join('/');
|
|
3895
|
+
applyProjectTransaction({
|
|
3896
|
+
projectRoot,
|
|
3897
|
+
projectId: task.projectId,
|
|
3898
|
+
transactionId: `tx-${createEntityId('TASK', now.getTime()).toLowerCase()}`,
|
|
3899
|
+
kind: 'plan-integrity-dependency-recovery',
|
|
3900
|
+
now,
|
|
3901
|
+
targets: [
|
|
3902
|
+
...(refreshedKnowledgeMap
|
|
3903
|
+
? [{ path: relative(path.join(projectRoot, 'knowledge-map.json')), content: `${JSON.stringify(refreshedKnowledgeMap, null, 2)}\n` }]
|
|
3904
|
+
: []),
|
|
3905
|
+
{
|
|
3906
|
+
path: relative(path.join(this.store.taskRoot(task.projectId, task.id), 'state.json')),
|
|
3907
|
+
content: `${JSON.stringify(nextTask, null, 2)}\n`,
|
|
3908
|
+
},
|
|
3909
|
+
],
|
|
3910
|
+
validate: () => {
|
|
3911
|
+
const saved = this.store.readTask(task.projectId, task.id);
|
|
3912
|
+
if (saved.revision !== nextTask.revision || saved.systemCommits.at(-1) !== preflight.commitSha) {
|
|
3913
|
+
throw new WorkflowError('STATE_CORRUPT', 'Plan-integrity dependency recovery Task readback failed.', { taskId });
|
|
3914
|
+
}
|
|
3915
|
+
if (refreshedKnowledgeMap && this.store.readKnowledgeMap(task.projectId).revision !== refreshedKnowledgeMap.revision) {
|
|
3916
|
+
throw new WorkflowError('STATE_CORRUPT', 'Plan-integrity dependency Knowledge refresh readback failed.', { taskId });
|
|
3917
|
+
}
|
|
3918
|
+
},
|
|
3919
|
+
});
|
|
3920
|
+
return this.store.readTask(task.projectId, task.id);
|
|
3731
3921
|
}
|
|
3732
3922
|
milestoneProgress(repository, milestoneId) {
|
|
3733
3923
|
const snapshot = this.observationSnapshot(repository);
|
|
@@ -4171,6 +4361,22 @@ export class WorkflowService {
|
|
|
4171
4361
|
},
|
|
4172
4362
|
});
|
|
4173
4363
|
}
|
|
4364
|
+
const planIntegrityDependencyRecovery = this.planIntegrityDependencyRecoveryPreflight(repositoryRoot, activeTask.id);
|
|
4365
|
+
if (planIntegrityDependencyRecovery.eligible) {
|
|
4366
|
+
return withAdoption({
|
|
4367
|
+
scope: 'task',
|
|
4368
|
+
id: activeTask.id,
|
|
4369
|
+
status: activeTask.status,
|
|
4370
|
+
action: 'update plan-integrity-dependency-recover',
|
|
4371
|
+
revision: activeTask.revision,
|
|
4372
|
+
dependencyProvenanceRecovery: planIntegrityDependencyRecovery,
|
|
4373
|
+
compatibilityBoundary: {
|
|
4374
|
+
preservesWorktree: true,
|
|
4375
|
+
prerequisite: 'A newer package preflight approved the exact failed Step, remediation history, and dirty allowlist before dependency-only transport.',
|
|
4376
|
+
continuation: 'Register this dependency commit, then follow fresh next to Plan-integrity recovery and corrective replan.',
|
|
4377
|
+
},
|
|
4378
|
+
});
|
|
4379
|
+
}
|
|
4174
4380
|
const dependencyRecovery = this.dependencyProvenanceRecoveryPreflight(repositoryRoot, activeTask.id);
|
|
4175
4381
|
if (dependencyRecovery.eligible) {
|
|
4176
4382
|
return withAdoption({
|
|
@@ -4473,6 +4679,8 @@ export class WorkflowService {
|
|
|
4473
4679
|
|| taskNext?.action === 'task remediation-mode-recover'
|
|
4474
4680
|
|| taskNext?.action === 'task plan-integrity-recover'
|
|
4475
4681
|
|| taskNext?.blockedAction === 'task plan-integrity-recover'
|
|
4682
|
+
|| taskNext?.action === 'task corrective-yield'
|
|
4683
|
+
|| String(taskNext?.action ?? '').startsWith('task corrective-replan')
|
|
4476
4684
|
|| hardStop
|
|
4477
4685
|
|| terminalCorrectiveDecision === 'split-required'
|
|
4478
4686
|
|| terminalCorrectiveDecision === 'stop-escalate') {
|
|
@@ -5124,7 +5332,9 @@ export class WorkflowService {
|
|
|
5124
5332
|
stepId: planIntegrityAssessment.stepId,
|
|
5125
5333
|
planIntegrityRecovery: {
|
|
5126
5334
|
state: 'eligible',
|
|
5127
|
-
reasonCode: '
|
|
5335
|
+
reasonCode: planIntegrityAssessment.evidence?.kind === 'missing-npm-script-outside-allowed-writes'
|
|
5336
|
+
? 'MISSING_NPM_SCRIPT_OUTSIDE_ALLOWED_WRITES'
|
|
5337
|
+
: 'NON_EXECUTABLE_NPM_CHECK_OUTSIDE_ALLOWED_WRITES',
|
|
5128
5338
|
expectedRevision: task.revision,
|
|
5129
5339
|
requiredActor,
|
|
5130
5340
|
evidence: planIntegrityAssessment.evidence,
|
|
@@ -5813,7 +6023,7 @@ export class WorkflowService {
|
|
|
5813
6023
|
},
|
|
5814
6024
|
};
|
|
5815
6025
|
}
|
|
5816
|
-
inspectDependencyProvenanceCandidate(snapshot, task, activeDownstreamProof = null, downstreamProofReplan = null, historicalStepProvenance = null) {
|
|
6026
|
+
inspectDependencyProvenanceCandidate(snapshot, task, activeDownstreamProof = null, downstreamProofReplan = null, historicalStepProvenance = null, planIntegrity = null) {
|
|
5817
6027
|
const versions = inspectWorkflowVersions(snapshot.identity.repositoryRoot, [task.baseBranch]);
|
|
5818
6028
|
const now = this.now().getTime();
|
|
5819
6029
|
return inspectDependencyProvenanceRecovery(snapshot.identity.repositoryRoot, task, {
|
|
@@ -5833,7 +6043,7 @@ export class WorkflowService {
|
|
|
5833
6043
|
currentBranch: versions.currentBranch,
|
|
5834
6044
|
baseBranch: versions.milestoneBases.find((base) => base.branch === task.baseBranch)?.version ?? null,
|
|
5835
6045
|
},
|
|
5836
|
-
}, activeDownstreamProof, downstreamProofReplan, historicalStepProvenance);
|
|
6046
|
+
}, activeDownstreamProof, downstreamProofReplan, historicalStepProvenance, planIntegrity);
|
|
5837
6047
|
}
|
|
5838
6048
|
inspectHistoricalStepProvenanceCandidate(snapshot, task, options = {}) {
|
|
5839
6049
|
const now = this.now().getTime();
|