codex-workflow-v2 2.0.0-beta.12 → 2.0.0-beta.12.2
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 -3
- package/dist/src/alpha6/remediation.d.ts +8 -3
- package/dist/src/alpha6/remediation.js +374 -9
- package/dist/src/alpha6/remediation.js.map +1 -1
- package/dist/src/alpha7/corrective-recovery.d.ts +8 -1
- package/dist/src/alpha7/corrective-recovery.js +144 -26
- package/dist/src/alpha7/corrective-recovery.js.map +1 -1
- package/dist/src/cli.js +19 -0
- package/dist/src/cli.js.map +1 -1
- package/dist/src/contracts.d.ts +42 -0
- package/dist/src/dependency-provenance.js +5 -3
- package/dist/src/dependency-provenance.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.d.ts +5 -1
- package/dist/src/workflow.js +158 -19
- package/dist/src/workflow.js.map +1 -1
- package/docs/autonomy-guardrails.md +35 -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 +23 -5
- package/docs/pdf/sources/codex-workflow-v2-chat-only-guide-ru.md +17 -8
- package/docs/pdf/sources/codex-workflow-v2-technical-reference-ru.md +32 -14
- package/docs/release.md +9 -1
- package/docs/updating-existing-project.md +38 -0
- package/docs/validation-report.md +84 -80
- package/package.json +1 -1
- package/plugins/codex-workflow-gateway/.codex-plugin/plugin.json +1 -1
- package/plugins/codex-workflow-gateway/references/protocol.md +21 -1
- package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +24 -0
- package/schemas/stop-escalate-override-event.schema.json +45 -0
package/dist/src/workflow.js
CHANGED
|
@@ -13,14 +13,14 @@ import { inspectLocalDependency, inspectWorkflowVersions } from './diagnostics.j
|
|
|
13
13
|
import { appendTaskClaim, appendTaskHandback, appendTaskHandoff, appendTaskWriterCredentialReplacement, assertTaskClaimAllowed, assertTaskMutationAllowedByC1, defaultTaskWorkerActor, readTaskC1Posture, } from './alpha6/handoff.js';
|
|
14
14
|
import { applyAdoptionPosture, assertAdoptionBaselinePreserved, buildAdoptionPreparation, initializeProjectRegistrationAdoption, readCurrentAdoptionPosture, } from './alpha6/adoption.js';
|
|
15
15
|
import { appendCurrentPlanRiskAudit, appendReboundPlanRiskAudit, readCurrentPlanRiskAudit, validatePlanRiskAuditCandidate, } from './alpha6/plan-risk.js';
|
|
16
|
-
import { appendCorrectiveDecisionEvent, appendPlanIntegrityRecoveryDecision, appendRemediationEvent, appendRemediationModeRecovery, assertCorrectiveAuditorIndependence, assertGuardedRemediationAttemptAllowed, defaultCorrectiveAuditorActor, findCurrentGuardedRemediationPosture, findRemediationModeRecoveryCandidate, findFailedGuardedStepRequiringCorrectiveDecision, readGuardedRemediationPostureForStep, readCorrectiveDecisionEvents, readRemediationEvents, } from './alpha6/remediation.js';
|
|
16
|
+
import { appendCorrectiveDecisionEvent, appendPlanIntegrityRecoveryDecision, appendRemediationEvent, appendRemediationModeRecovery, appendStopEscalateOverride, assertCorrectiveAuditorIndependence, assertGuardedRemediationAttemptAllowed, defaultCorrectiveAuditorActor, findCurrentGuardedRemediationPosture, findRemediationModeRecoveryCandidate, findFailedGuardedStepRequiringCorrectiveDecision, readGuardedRemediationPostureForStep, readCorrectiveDecisionEvents, readRemediationEvents, prepareStopEscalateOverride, stopEscalateOverrideDecisionEventIds, } from './alpha6/remediation.js';
|
|
17
17
|
import { assessPlanIntegrityRecovery, defaultPlanIntegrityRecoveryActor, } from './alpha6/plan-integrity.js';
|
|
18
18
|
import { assertMechanicalFeasibilityFresh, evaluateMechanicalFeasibility, hashMechanicalFeasibilityEvidence, } from './alpha6/mechanical-feasibility.js';
|
|
19
19
|
import { assessMilestoneInitialAssembly, applyInitialMilestonePlanTransaction, applyMilestoneScopeChangeTransaction, assertMilestoneDependenciesDeclared, assertMilestoneTaskRunnable, assessMilestoneTaskDependencies, assertMilestoneMembershipIntegrity, assertMilestoneScopeChangeStatusAllowed, inspectMilestoneWithIntegrity, normalizeMilestonePlan, prepareMilestoneScopeChangeCandidate, prepareMilestoneScopeChangeBundle, readMilestoneForScopeChange, readMilestoneWithIntegrity, } from './alpha6/milestone.js';
|
|
20
20
|
import { applyProjectTransaction, recoverProjectTransactions, runRollbackProjectTransaction, } from './beta1/project-transaction.js';
|
|
21
21
|
import { buildCurrentStrictStepReviewCycle, countUnverifiedStrictStepReviews, ensurePendingStrictStepReview, isStepReviewRequired, latestFailedStepReviewRouting, latestPassedVerifiedStepReviewEvent, recordStrictStepReview, verifiedHistoricalStepReviewCommits, } from './alpha6/review.js';
|
|
22
22
|
import { applyMilestoneAutonomyContract, assertAutonomousPlanEvolution, prepareMilestoneAutonomyContract, readMilestoneAutonomyEvents, requireActiveMilestoneAutonomy, } from './alpha7/autonomy.js';
|
|
23
|
-
import { appendCorrectiveDecisionRecovery, readValidatedCorrectiveDecisionRecoveryForNavigation, requireCorrectiveDecisionRecoveryForRun, } from './alpha7/corrective-recovery.js';
|
|
23
|
+
import { appendCorrectiveDecisionRecovery, readValidatedCorrectiveDecisionRecoveryForNavigation, readValidatedStopOverrideContextRebindIfApplicable, requireCorrectiveDecisionRecoveryForRun, } from './alpha7/corrective-recovery.js';
|
|
24
24
|
import { applyKnowledgeSelections, hashKnowledgeMap, inspectKnowledgeMap, normalizeRelativePath, reconcileKnowledgeMap, scanProjectKnowledge, selectKnowledgeSources, } from './memory.js';
|
|
25
25
|
import { canonicalJsonStringify, sha256Hex } from './alpha6/store-sidecars.js';
|
|
26
26
|
import { ensureDirectory } from './fs-utils.js';
|
|
@@ -110,6 +110,31 @@ export class WorkflowService {
|
|
|
110
110
|
repaired: true,
|
|
111
111
|
};
|
|
112
112
|
}
|
|
113
|
+
prepareTaskStopOverride(repository, taskId, stepId, expectedRevision, actor, reason) {
|
|
114
|
+
const snapshot = this.observationSnapshot(repository);
|
|
115
|
+
if (snapshot.observation.kind !== 'assessment') {
|
|
116
|
+
throw new WorkflowError('TRANSITION_BLOCKED', 'Stop override requires a coherent observation boundary.', {
|
|
117
|
+
observation: snapshot.observation,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
const task = snapshot.tasks.find((candidate) => candidate.id === taskId) ?? null;
|
|
121
|
+
if (!task)
|
|
122
|
+
throw new WorkflowError('NOT_FOUND', `Task ${taskId} was not found in this repository.`);
|
|
123
|
+
this.assertStopOverrideRepositoryBoundary(snapshot.identity, task);
|
|
124
|
+
return prepareStopEscalateOverride(this.store, task, stepId, expectedRevision, actor, reason, headCommit(snapshot.identity.repositoryRoot));
|
|
125
|
+
}
|
|
126
|
+
applyTaskStopOverride(repository, taskId, stepId, expectedRevision, actor, reason, confirmationCode) {
|
|
127
|
+
const snapshot = this.observationSnapshot(repository);
|
|
128
|
+
if (snapshot.observation.kind !== 'assessment') {
|
|
129
|
+
throw new WorkflowError('TRANSITION_BLOCKED', 'Stop override requires a coherent observation boundary.', {
|
|
130
|
+
observation: snapshot.observation,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
const context = this.#mutationContext(repository);
|
|
134
|
+
const task = context.store.readTask(context.identity.projectId, taskId);
|
|
135
|
+
this.assertStopOverrideRepositoryBoundary(context.identity, task, context.locks.list());
|
|
136
|
+
return appendStopEscalateOverride(context.store, task, stepId, expectedRevision, actor, reason, headCommit(context.identity.repositoryRoot), confirmationCode, this.now());
|
|
137
|
+
}
|
|
113
138
|
prepareCorrectiveReplan(repository, taskId, candidate) {
|
|
114
139
|
return this.correctiveReplanController(repository).prepare({ taskId, candidate });
|
|
115
140
|
}
|
|
@@ -1038,7 +1063,9 @@ export class WorkflowService {
|
|
|
1038
1063
|
const passedBoundary = latestPassedVerifiedStepReviewEvent(this.store, task, event.stepId);
|
|
1039
1064
|
return !passedBoundary || passedBoundary.recordedAt <= event.recordedAt;
|
|
1040
1065
|
});
|
|
1041
|
-
const
|
|
1066
|
+
const overriddenStopDecisionEventIds = stopEscalateOverrideDecisionEventIds(this.store, task);
|
|
1067
|
+
const currentHardBlockingDecisions = currentPlanCorrectiveDecisions.filter((event) => event.decision === 'split-required'
|
|
1068
|
+
|| (event.decision === 'stop-escalate' && !overriddenStopDecisionEventIds.has(event.eventId)));
|
|
1042
1069
|
const currentPlanRiskAudit = task.status === 'needs_fix' || currentReplanDecisions.length > 0
|
|
1043
1070
|
? readCurrentPlanRiskAudit(this.store, task)
|
|
1044
1071
|
: null;
|
|
@@ -1758,8 +1785,11 @@ export class WorkflowService {
|
|
|
1758
1785
|
throw new WorkflowError('TRANSITION_BLOCKED', `Task ${taskId} cannot run a Step while ${task.status}.`);
|
|
1759
1786
|
}
|
|
1760
1787
|
this.assertExecutionAuthorizationFresh(task, context.identity.repositoryRoot);
|
|
1788
|
+
const overriddenStopDecisionEventIds = stopEscalateOverrideDecisionEventIds(this.store, task);
|
|
1761
1789
|
const currentPlanBlockingDecisions = readCorrectiveDecisionEvents(this.store, task)
|
|
1762
|
-
.filter((event) => event.planHash === task.planHash
|
|
1790
|
+
.filter((event) => event.planHash === task.planHash
|
|
1791
|
+
&& event.decision !== 'continue-fix'
|
|
1792
|
+
&& !(event.decision === 'stop-escalate' && overriddenStopDecisionEventIds.has(event.eventId)));
|
|
1763
1793
|
if (currentPlanBlockingDecisions.length > 0) {
|
|
1764
1794
|
throw new WorkflowError('TRANSITION_BLOCKED', `Task ${taskId} cannot run any Step while the current Plan has active blocking corrective decisions.`, {
|
|
1765
1795
|
taskId,
|
|
@@ -1797,7 +1827,10 @@ export class WorkflowService {
|
|
|
1797
1827
|
const recovery = staleDecision?.decision === 'continue-fix'
|
|
1798
1828
|
? requireCorrectiveDecisionRecoveryForRun(this.store, task, stepId, actor, writerToken)
|
|
1799
1829
|
: null;
|
|
1800
|
-
const
|
|
1830
|
+
const stopOverrideContextRebind = staleDecision?.decision === 'stop-escalate'
|
|
1831
|
+
? readValidatedStopOverrideContextRebindIfApplicable(this.store, task, stepId)
|
|
1832
|
+
: null;
|
|
1833
|
+
const gate = assertGuardedRemediationAttemptAllowed(this.store, task, stepId, planRiskAudit, recovery?.correctiveDecisionEventId ?? null, stopOverrideContextRebind?.stopDecision.eventId ?? null);
|
|
1801
1834
|
resumesCorrectiveReplan = gate.posture === 'replan-ready';
|
|
1802
1835
|
}
|
|
1803
1836
|
const knowledgeMap = this.assertTaskKnowledgeBinding(context.identity.repositoryRoot, task);
|
|
@@ -2035,7 +2068,7 @@ export class WorkflowService {
|
|
|
2035
2068
|
checksHash: sha256Hex(canonicalJsonStringify(checks)),
|
|
2036
2069
|
reviewEventHash: null,
|
|
2037
2070
|
reviewerAttestationHash: null,
|
|
2038
|
-
}, planRiskAudit, this.now());
|
|
2071
|
+
}, planRiskAudit, this.now(), this.stopOverrideContextRebindDecisionId(task, stepId));
|
|
2039
2072
|
}
|
|
2040
2073
|
const steps = task.steps.map((candidate) => candidate.id === stepId ? { ...candidate, status: 'failed' } : candidate);
|
|
2041
2074
|
return this.store.writeTask({ ...task, status: 'needs_fix', steps, blockReason: `${stepId} checks failed.` }, expectedRevision);
|
|
@@ -2155,7 +2188,7 @@ export class WorkflowService {
|
|
|
2155
2188
|
checksHash: currentCycle.reviewRecordedEvent.checksHash,
|
|
2156
2189
|
reviewEventHash: currentCycle.reviewRecordedEvent.eventHash,
|
|
2157
2190
|
reviewerAttestationHash: currentCycle.reviewerAttestationEvent.eventHash,
|
|
2158
|
-
}, planRiskAudit, this.now());
|
|
2191
|
+
}, planRiskAudit, this.now(), this.stopOverrideContextRebindDecisionId(task, stepId));
|
|
2159
2192
|
}
|
|
2160
2193
|
return this.store.writeTask(applyStrictStepReviewResolution(task, stepId, currentCycle.resolution), expectedRevision);
|
|
2161
2194
|
}
|
|
@@ -2183,7 +2216,7 @@ export class WorkflowService {
|
|
|
2183
2216
|
checksHash: reviewRecordedEvent.checksHash,
|
|
2184
2217
|
reviewEventHash: reviewRecordedEvent.eventHash,
|
|
2185
2218
|
reviewerAttestationHash: reviewerAttestationEvent.eventHash,
|
|
2186
|
-
}, planRiskAudit, this.now());
|
|
2219
|
+
}, planRiskAudit, this.now(), this.stopOverrideContextRebindDecisionId(task, stepId));
|
|
2187
2220
|
}
|
|
2188
2221
|
return this.store.writeTask(applyStrictStepReviewResolution(task, stepId, recorded.resolution, launch.review.summary), expectedRevision);
|
|
2189
2222
|
}
|
|
@@ -2255,7 +2288,7 @@ export class WorkflowService {
|
|
|
2255
2288
|
checksHash: recorded.reviewRecordedEvent.checksHash,
|
|
2256
2289
|
reviewEventHash: recorded.reviewRecordedEvent.eventHash,
|
|
2257
2290
|
reviewerAttestationHash: recorded.reviewerAttestationEvent.eventHash,
|
|
2258
|
-
}, readCurrentPlanRiskAudit(this.store, task), this.now());
|
|
2291
|
+
}, readCurrentPlanRiskAudit(this.store, task), this.now(), this.stopOverrideContextRebindDecisionId(task, stepId));
|
|
2259
2292
|
}
|
|
2260
2293
|
const saved = this.store.writeTask(applyStrictStepReviewResolution(task, stepId, recorded.resolution, review.summary), expectedRevision);
|
|
2261
2294
|
return {
|
|
@@ -3926,6 +3959,39 @@ export class WorkflowService {
|
|
|
3926
3959
|
case 'decision-required':
|
|
3927
3960
|
if (guardedCorrectivePosture.correctiveDecision
|
|
3928
3961
|
&& guardedCorrectivePosture.correctiveDecision.planHash !== task.planHash) {
|
|
3962
|
+
if (guardedCorrectivePosture.correctiveDecision.decision === 'stop-escalate') {
|
|
3963
|
+
try {
|
|
3964
|
+
const assessment = readValidatedStopOverrideContextRebindIfApplicable(this.store, task, guardedCorrectivePosture.stepId);
|
|
3965
|
+
if (!assessment) {
|
|
3966
|
+
throw new WorkflowError('TRANSITION_BLOCKED', 'Stale stop decision has no validated stop-override context-rebind continuation.');
|
|
3967
|
+
}
|
|
3968
|
+
guardedCorrectiveOverlay = {
|
|
3969
|
+
action: 'task run',
|
|
3970
|
+
stepId: guardedCorrectivePosture.stepId,
|
|
3971
|
+
stopOverrideContextRebind: {
|
|
3972
|
+
state: 'validated',
|
|
3973
|
+
overrideEventId: assessment.override.eventId,
|
|
3974
|
+
stopDecisionEventId: assessment.stopDecision.eventId,
|
|
3975
|
+
sourcePlanHash: assessment.override.planHash,
|
|
3976
|
+
reboundPlanHash: task.planHash,
|
|
3977
|
+
semanticPlanHash: assessment.semanticPlanHash,
|
|
3978
|
+
appendOnly: true,
|
|
3979
|
+
},
|
|
3980
|
+
};
|
|
3981
|
+
}
|
|
3982
|
+
catch (error) {
|
|
3983
|
+
guardedCorrectiveOverlay = {
|
|
3984
|
+
action: 'doctor',
|
|
3985
|
+
stepId: guardedCorrectivePosture.stepId,
|
|
3986
|
+
blockedAction: 'task run',
|
|
3987
|
+
stopOverrideContextRebind: {
|
|
3988
|
+
state: 'blocked',
|
|
3989
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
3990
|
+
},
|
|
3991
|
+
};
|
|
3992
|
+
}
|
|
3993
|
+
break;
|
|
3994
|
+
}
|
|
3929
3995
|
try {
|
|
3930
3996
|
const navigation = readValidatedCorrectiveDecisionRecoveryForNavigation(this.store, task, guardedCorrectivePosture.stepId);
|
|
3931
3997
|
guardedCorrectiveOverlay = navigation.recovery
|
|
@@ -4039,16 +4105,50 @@ export class WorkflowService {
|
|
|
4039
4105
|
}
|
|
4040
4106
|
break;
|
|
4041
4107
|
case 'stop-escalate':
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4108
|
+
try {
|
|
4109
|
+
this.assertStopOverrideRepositoryBoundary(resolveRepositoryIdentity(repositoryRoot), task);
|
|
4110
|
+
prepareStopEscalateOverride(this.store, task, guardedCorrectivePosture.stepId, task.revision, 'user', 'navigation eligibility probe', headCommit(repositoryRoot));
|
|
4111
|
+
guardedCorrectiveOverlay = {
|
|
4112
|
+
action: 'task stop-override-prepare',
|
|
4113
|
+
blockedAction: 'task run',
|
|
4114
|
+
stepId: guardedCorrectivePosture.stepId,
|
|
4115
|
+
correctiveDecisionGate: {
|
|
4116
|
+
attemptCount: guardedCorrectivePosture.attemptCount,
|
|
4117
|
+
decision: guardedCorrectivePosture.correctiveDecision?.decision ?? null,
|
|
4118
|
+
decisionEventId: guardedCorrectivePosture.correctiveDecision?.eventId ?? null,
|
|
4119
|
+
humanApprovalRequired: true,
|
|
4120
|
+
delegatedApprovalAllowed: false,
|
|
4121
|
+
},
|
|
4122
|
+
stopOverride: {
|
|
4123
|
+
state: 'eligible',
|
|
4124
|
+
policy: 'beta11-attempt4-stop-compatibility-v1',
|
|
4125
|
+
prepareCommand: 'task stop-override-prepare',
|
|
4126
|
+
applyCommand: 'task stop-override-apply',
|
|
4127
|
+
expectedRevision: task.revision,
|
|
4128
|
+
appendOnly: true,
|
|
4129
|
+
preservesOriginalDecision: true,
|
|
4130
|
+
requiredAction: 'Prepare with an explicit human actor and reason, then apply the exact confirmation code in a later user turn.',
|
|
4131
|
+
},
|
|
4132
|
+
};
|
|
4133
|
+
}
|
|
4134
|
+
catch (error) {
|
|
4135
|
+
guardedCorrectiveOverlay = {
|
|
4136
|
+
action: 'doctor',
|
|
4137
|
+
blockedAction: 'task stop-override-prepare',
|
|
4138
|
+
stepId: guardedCorrectivePosture.stepId,
|
|
4139
|
+
correctiveDecisionGate: {
|
|
4140
|
+
attemptCount: guardedCorrectivePosture.attemptCount,
|
|
4141
|
+
decision: guardedCorrectivePosture.correctiveDecision?.decision ?? null,
|
|
4142
|
+
decisionEventId: guardedCorrectivePosture.correctiveDecision?.eventId ?? null,
|
|
4143
|
+
humanApprovalRequired: true,
|
|
4144
|
+
},
|
|
4145
|
+
stopOverride: {
|
|
4146
|
+
state: 'blocked',
|
|
4147
|
+
policy: 'beta11-attempt4-stop-compatibility-v1',
|
|
4148
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
4149
|
+
},
|
|
4150
|
+
};
|
|
4151
|
+
}
|
|
4052
4152
|
break;
|
|
4053
4153
|
default:
|
|
4054
4154
|
break;
|
|
@@ -4170,6 +4270,9 @@ export class WorkflowService {
|
|
|
4170
4270
|
: 'Escalate outside this Task; stop-escalate cannot be resumed or rebound.',
|
|
4171
4271
|
});
|
|
4172
4272
|
}
|
|
4273
|
+
stopOverrideContextRebindDecisionId(task, stepId) {
|
|
4274
|
+
return readValidatedStopOverrideContextRebindIfApplicable(this.store, task, stepId)?.stopDecision.eventId ?? null;
|
|
4275
|
+
}
|
|
4173
4276
|
taskHasTerminalCorrectiveDecision(task) {
|
|
4174
4277
|
return this.taskTerminalCorrectivePosture(task) !== null;
|
|
4175
4278
|
}
|
|
@@ -4184,6 +4287,42 @@ export class WorkflowService {
|
|
|
4184
4287
|
? posture
|
|
4185
4288
|
: null;
|
|
4186
4289
|
}
|
|
4290
|
+
assertStopOverrideRepositoryBoundary(identity, task, observedLeases) {
|
|
4291
|
+
const blockers = [];
|
|
4292
|
+
const dirty = changedFiles(identity.repositoryRoot);
|
|
4293
|
+
if (dirty.length > 0)
|
|
4294
|
+
blockers.push('Repository checkout must be clean.');
|
|
4295
|
+
if (task.workspaceOwner !== 'local')
|
|
4296
|
+
blockers.push('Stop override is limited to a local Task workspace.');
|
|
4297
|
+
if (!task.taskBranch || currentBranch(identity.repositoryRoot) !== task.taskBranch) {
|
|
4298
|
+
blockers.push('The current branch must be the recorded Task branch.');
|
|
4299
|
+
}
|
|
4300
|
+
if (task.steps.some((step) => step.status === 'in_progress'))
|
|
4301
|
+
blockers.push('No Step may be in progress.');
|
|
4302
|
+
const leases = observedLeases
|
|
4303
|
+
?? new WriterLockManager(this.store.lockRoot(identity.projectId), this.now, this.store.root).list();
|
|
4304
|
+
if (leases.some((lease) => lease.entityId === task.id))
|
|
4305
|
+
blockers.push('No active or stale Task writer lease may exist.');
|
|
4306
|
+
const projectRoot = this.store.projectRoot(identity.projectId);
|
|
4307
|
+
const replanTransactions = inspectCorrectiveReplanTaskTransactions(projectRoot, this.store.root);
|
|
4308
|
+
const yieldTransactions = inspectCorrectiveYieldTaskTransactions(projectRoot, this.store.root);
|
|
4309
|
+
if (replanTransactions.pending.some((transaction) => transaction.taskId === task.id)
|
|
4310
|
+
|| replanTransactions.corrupt.some((transaction) => transaction.taskId === task.id)
|
|
4311
|
+
|| yieldTransactions.pending.some((transaction) => transaction.taskId === task.id)
|
|
4312
|
+
|| yieldTransactions.corrupt.some((transaction) => transaction.taskId === task.id)) {
|
|
4313
|
+
blockers.push('No pending or corrupt Task transaction may exist.');
|
|
4314
|
+
}
|
|
4315
|
+
if (listCoreTaskOperationMutexes(this.store.lockRoot(identity.projectId), this.store.root)
|
|
4316
|
+
.some((operation) => operation.entityId === task.id)) {
|
|
4317
|
+
blockers.push('No Core Task operation may exist.');
|
|
4318
|
+
}
|
|
4319
|
+
if (blockers.length > 0) {
|
|
4320
|
+
throw new WorkflowError('TRANSITION_BLOCKED', 'Stop override repository preconditions are not satisfied.', {
|
|
4321
|
+
taskId: task.id,
|
|
4322
|
+
blockers,
|
|
4323
|
+
});
|
|
4324
|
+
}
|
|
4325
|
+
}
|
|
4187
4326
|
delegatedApprovalOptions(projectId, transition, target) {
|
|
4188
4327
|
return this.store.listDelegations(projectId)
|
|
4189
4328
|
.filter((grant) => {
|