codex-workflow-v2 2.0.0-beta.12.7 → 2.0.0-beta.12.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +9 -1
  2. package/dist/src/alpha6/review.d.ts +6 -0
  3. package/dist/src/alpha6/review.js +12 -0
  4. package/dist/src/alpha6/review.js.map +1 -1
  5. package/dist/src/cli.js +37 -3
  6. package/dist/src/cli.js.map +1 -1
  7. package/dist/src/contracts.d.ts +37 -1
  8. package/dist/src/dependency-provenance.d.ts +2 -2
  9. package/dist/src/dependency-provenance.js +21 -5
  10. package/dist/src/dependency-provenance.js.map +1 -1
  11. package/dist/src/git.js +1 -0
  12. package/dist/src/git.js.map +1 -1
  13. package/dist/src/historical-step-provenance.d.ts +20 -0
  14. package/dist/src/historical-step-provenance.js +111 -0
  15. package/dist/src/historical-step-provenance.js.map +1 -0
  16. package/dist/src/state/corrective-replan-executor.js +5 -0
  17. package/dist/src/state/corrective-replan-executor.js.map +1 -1
  18. package/dist/src/version.d.ts +1 -1
  19. package/dist/src/version.js +1 -1
  20. package/dist/src/workflow.d.ts +7 -2
  21. package/dist/src/workflow.js +206 -11
  22. package/dist/src/workflow.js.map +1 -1
  23. package/docs/pdf/codex-workflow-v2-architecture-ru.pdf +0 -0
  24. package/docs/pdf/codex-workflow-v2-chat-only-guide-ru.pdf +0 -0
  25. package/docs/pdf/codex-workflow-v2-technical-reference-ru.pdf +0 -0
  26. package/docs/pdf/sources/codex-workflow-v2-architecture-ru.md +23 -6
  27. package/docs/pdf/sources/codex-workflow-v2-chat-only-guide-ru.md +28 -28
  28. package/docs/pdf/sources/codex-workflow-v2-technical-reference-ru.md +41 -26
  29. package/docs/release.md +9 -1
  30. package/docs/updating-existing-project.md +30 -0
  31. package/docs/validation-report.md +90 -96
  32. package/package.json +1 -1
  33. package/plugins/codex-workflow-gateway/.codex-plugin/plugin.json +1 -1
  34. package/plugins/codex-workflow-gateway/references/protocol.md +15 -0
  35. package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +35 -0
  36. package/schemas/task.schema.json +43 -0
@@ -3,6 +3,7 @@ import { createHash } from 'node:crypto';
3
3
  import path from 'node:path';
4
4
  import { PROTOCOL_VERSION, STATE_SCHEMA_VERSION, } from './contracts.js';
5
5
  import { inspectDependencyProvenanceRecovery, } from './dependency-provenance.js';
6
+ import { inspectHistoricalStepProvenanceRecovery, omittedStepEvidenceCommits, } from './historical-step-provenance.js';
6
7
  import { renderBrief, renderPlan, renderResult } from './artifacts.js';
7
8
  import { assertDelegationCanAuthorize, hashDelegationPolicy, prepareDelegationGrantGate, } from './delegation.js';
8
9
  import { assessDiscovery, mergeUnique } from './domain/discovery.js';
@@ -11,7 +12,7 @@ import { WorkflowError } from './errors.js';
11
12
  import { bindGraphEvidence, createGraphRefreshRequest, fallbackGraphBinding, inspectGraphBinding, validateGraphRequestCurrent, } from './graph.js';
12
13
  import { inspectLocalDependency, inspectWorkflowVersions } from './diagnostics.js';
13
14
  import { appendTaskClaim, appendTaskHandback, appendTaskHandoff, appendTaskWriterCredentialReplacement, assertTaskClaimAllowed, assertTaskMutationAllowedByC1, defaultTaskWorkerActor, prepareTaskCorrectiveYield, readTaskC1Posture, } from './alpha6/handoff.js';
14
- import { assessDownstreamProofCarryover, assessDownstreamProofReplanRecovery, assessDownstreamProofRecovery, downstreamProofInvalidationSidecar, downstreamProofReplanRecoverySidecar, prepareDownstreamProofInvalidation, prepareDownstreamProofReplanRecovery, readDownstreamProofInvalidations, readDownstreamProofReplanRecoveries, } from './alpha6/downstream-proof.js';
15
+ import { assessDownstreamProofCarryover, assessDownstreamProofReplanRecovery, assessDownstreamProofRecovery, downstreamProofInvalidationSidecar, downstreamProofReplanRecoverySidecar, prepareDownstreamProofInvalidation, prepareDownstreamProofReplanRecovery, readDownstreamProofInvalidations, readDownstreamProofReplanRecoveries, hashDirtyWorktree, } from './alpha6/downstream-proof.js';
15
16
  import { applyAdoptionPosture, assertAdoptionBaselinePreserved, buildAdoptionPreparation, initializeProjectRegistrationAdoption, readCurrentAdoptionPosture, } from './alpha6/adoption.js';
16
17
  import { appendCurrentPlanRiskAudit, appendReboundPlanRiskAudit, readCurrentPlanRiskAudit, readPlanRiskAuditEvents, validatePlanRiskAuditCandidate, } from './alpha6/plan-risk.js';
17
18
  import { appendCorrectiveDecisionEvent, appendPlanIntegrityRecoveryDecision, appendRemediationEvent, appendRemediationModeRecovery, appendStopEscalateOverride, assertCorrectiveAuditorIndependence, assertGuardedRemediationAttemptAllowed, defaultCorrectiveAuditorActor, findCurrentGuardedRemediationPosture, findRemediationModeRecoveryCandidate, findFailedGuardedStepRequiringCorrectiveDecision, readGuardedRemediationPostureForStep, readCorrectiveDecisionEvents, readRemediationEvents, prepareStopEscalateOverride, stopEscalateOverrideDecisionEventIds, } from './alpha6/remediation.js';
@@ -19,7 +20,7 @@ import { assessPlanIntegrityRecovery, defaultPlanIntegrityRecoveryActor, } from
19
20
  import { assertMechanicalFeasibilityFresh, evaluateMechanicalFeasibility, hashMechanicalFeasibilityEvidence, } from './alpha6/mechanical-feasibility.js';
20
21
  import { assessMilestoneInitialAssembly, applyInitialMilestonePlanTransaction, applyMilestoneScopeChangeTransaction, assertMilestoneDependenciesDeclared, assertMilestoneTaskRunnable, assessMilestoneTaskDependencies, assertMilestoneMembershipIntegrity, assertMilestoneScopeChangeStatusAllowed, inspectMilestoneWithIntegrity, normalizeMilestonePlan, prepareMilestoneScopeChangeCandidate, prepareMilestoneScopeChangeBundle, readMilestoneForScopeChange, readMilestoneWithIntegrity, } from './alpha6/milestone.js';
21
22
  import { applyProjectTransaction, recoverProjectTransactions, runRollbackProjectTransaction, } from './beta1/project-transaction.js';
22
- import { buildCurrentStrictStepReviewCycle, countUnverifiedStrictStepReviews, ensurePendingStrictStepReview, isStepReviewRequired, latestFailedStepReviewRouting, latestPassedVerifiedStepReviewEvent, recordStrictStepReview, verifiedHistoricalStepReviewCommits, } from './alpha6/review.js';
23
+ import { buildCurrentStrictStepReviewCycle, countUnverifiedStrictStepReviews, ensurePendingStrictStepReview, isStepReviewRequired, latestFailedStepReviewRouting, latestPassedVerifiedStepReviewEvent, recordStrictStepReview, verifiedHistoricalStepReviewCommits, verifiedHistoricalStepReviewBindings, } from './alpha6/review.js';
23
24
  import { applyMilestoneAutonomyContract, assertAutonomousPlanEvolution, prepareMilestoneAutonomyContract, readMilestoneAutonomyEvents, requireActiveMilestoneAutonomy, } from './alpha7/autonomy.js';
24
25
  import { appendCorrectiveDecisionRecovery, readValidatedCorrectiveDecisionRecoveryForNavigation, readValidatedStopOverrideContextRebindIfApplicable, requireCorrectiveDecisionRecoveryForRun, } from './alpha7/corrective-recovery.js';
25
26
  import { applyKnowledgeSelections, hashKnowledgeMap, inspectKnowledgeMap, normalizeRelativePath, reconcileKnowledgeMap, scanProjectKnowledge, selectKnowledgeSources, } from './memory.js';
@@ -1399,6 +1400,10 @@ export class WorkflowService {
1399
1400
  status: dependenciesComplete(step, completedIds) ? 'planned' : 'blocked',
1400
1401
  evidence: null,
1401
1402
  }));
1403
+ const invalidatedStepCommits = [...new Set([
1404
+ ...(task.invalidatedStepCommits ?? []),
1405
+ ...omittedStepEvidenceCommits(task, plannedSteps),
1406
+ ])];
1402
1407
  if (task.status === 'needs_fix' &&
1403
1408
  task.review.status === 'failed' &&
1404
1409
  plannedSteps.every((step) => step.status === 'completed')) {
@@ -1437,6 +1442,7 @@ export class WorkflowService {
1437
1442
  knowledgeMapHash: plan.knowledgeMapHash,
1438
1443
  graphUse: plan.graphUse,
1439
1444
  steps: plannedSteps,
1445
+ invalidatedStepCommits,
1440
1446
  authorizations,
1441
1447
  review: emptyReview(),
1442
1448
  resultHash: null,
@@ -2733,16 +2739,23 @@ export class WorkflowService {
2733
2739
  assertCorrectiveAuditorIndependence(this.store, task, stepId, correctiveAudit.auditor);
2734
2740
  return appendCorrectiveDecisionEvent(this.store, task, stepId, correctiveAudit, planRiskAudit, task.planHash, this.now());
2735
2741
  }
2736
- setTaskResult(repository, taskId, expectedRevision, summary, limitations) {
2737
- const { identity } = this.#mutationContext(repository);
2742
+ setTaskResult(repository, taskId, expectedRevision, summary, limitations, writerToken, actor) {
2743
+ const context = this.#mutationContext(repository);
2744
+ const { identity } = context;
2738
2745
  const task = this.store.readTask(identity.projectId, taskId);
2739
2746
  assertExpectedRevision(task, expectedRevision);
2740
2747
  if (task.status !== 'validating' || task.review.status !== 'passed') {
2741
2748
  throw new WorkflowError('TRANSITION_BLOCKED', 'Result requires a passing independent review.');
2742
2749
  }
2743
2750
  this.assertReviewFresh(identity.repositoryRoot, task);
2751
+ const lease = context.locks.heartbeat(taskId, writerToken);
2752
+ this.assertTaskMutationAllowedByHandoff(task, actor ?? null, lease.token);
2744
2753
  const root = this.store.taskRoot(task.projectId, task.id);
2745
2754
  const stagedResult = this.store.stageArtifact(root, 'result.md', renderResult(task, summary, limitations));
2755
+ // Human final acceptance is an intentionally unbounded pause. Release the
2756
+ // execution lease before entering that gate so elapsed human time cannot
2757
+ // turn a successful Task into a repository-wide stale-lock repair route.
2758
+ context.locks.release(taskId, lease.token);
2746
2759
  const saved = this.store.writeTask({ ...task, status: 'awaiting_final_acceptance', resultHash: stagedResult.hash, blockReason: null }, expectedRevision);
2747
2760
  this.store.publishArtifact(stagedResult);
2748
2761
  return saved;
@@ -3005,6 +3018,137 @@ export class WorkflowService {
3005
3018
  throw new WorkflowError('NOT_FOUND', `Task ${taskId} was not found in this repository.`);
3006
3019
  return this.inspectDependencyProvenanceCandidate(snapshot, task);
3007
3020
  }
3021
+ historicalStepProvenanceRecoveryPreflight(repository, taskId) {
3022
+ const snapshot = this.observationSnapshot(repository);
3023
+ if (snapshot.observation.kind !== 'assessment') {
3024
+ throw new WorkflowError('TRANSITION_BLOCKED', 'Historical Step provenance recovery requires a coherent observation boundary.', {
3025
+ observation: snapshot.observation,
3026
+ });
3027
+ }
3028
+ const task = snapshot.tasks.find((candidate) => candidate.id === taskId);
3029
+ if (!task)
3030
+ throw new WorkflowError('NOT_FOUND', `Task ${taskId} was not found in this repository.`);
3031
+ return this.inspectHistoricalStepProvenanceCandidate(snapshot, task);
3032
+ }
3033
+ historicalStepDependencyRecoveryPreflight(repository, taskId) {
3034
+ const snapshot = this.observationSnapshot(repository);
3035
+ if (snapshot.observation.kind !== 'assessment') {
3036
+ throw new WorkflowError('TRANSITION_BLOCKED', 'Historical Step dependency recovery requires a coherent observation boundary.', {
3037
+ observation: snapshot.observation,
3038
+ });
3039
+ }
3040
+ const task = snapshot.tasks.find((candidate) => candidate.id === taskId);
3041
+ if (!task)
3042
+ throw new WorkflowError('NOT_FOUND', `Task ${taskId} was not found in this repository.`);
3043
+ let candidateParent = null;
3044
+ try {
3045
+ candidateParent = runGit(snapshot.identity.repositoryRoot, ['rev-parse', 'HEAD^']);
3046
+ }
3047
+ catch {
3048
+ candidateParent = null;
3049
+ }
3050
+ const assessment = candidateParent
3051
+ ? this.inspectHistoricalStepProvenanceCandidate(snapshot, task, {
3052
+ historyBoundary: 'HEAD^',
3053
+ preservedHeadCommit: candidateParent,
3054
+ })
3055
+ : null;
3056
+ if (!assessment?.eligible
3057
+ || !assessment.activeStepId
3058
+ || !assessment.commitSha
3059
+ || !task.planHash) {
3060
+ const ordinary = this.inspectDependencyProvenanceCandidate(snapshot, task);
3061
+ return {
3062
+ ...ordinary,
3063
+ eligible: false,
3064
+ action: null,
3065
+ historicalStepProvenance: null,
3066
+ blockers: [...new Set([
3067
+ ...ordinary.blockers,
3068
+ ...(assessment?.blockers ?? []),
3069
+ 'The dependency candidate parent must contain exactly one accepted and strictly reviewed historical Step commit omitted by the current corrective Plan.',
3070
+ ])],
3071
+ };
3072
+ }
3073
+ let dirtyWorktreeHash;
3074
+ try {
3075
+ dirtyWorktreeHash = hashDirtyWorktree(snapshot.identity.repositoryRoot, assessment.dirtyFiles);
3076
+ }
3077
+ catch (error) {
3078
+ const ordinary = this.inspectDependencyProvenanceCandidate(snapshot, task);
3079
+ return {
3080
+ ...ordinary,
3081
+ eligible: false,
3082
+ action: null,
3083
+ historicalStepProvenance: null,
3084
+ blockers: [...new Set([
3085
+ ...ordinary.blockers,
3086
+ error instanceof Error ? error.message : String(error),
3087
+ ])],
3088
+ };
3089
+ }
3090
+ return this.inspectDependencyProvenanceCandidate(snapshot, task, null, null, {
3091
+ activeStepId: assessment.activeStepId,
3092
+ planHash: task.planHash,
3093
+ dirtyFiles: assessment.dirtyFiles,
3094
+ dirtyWorktreeHash,
3095
+ retainedCommitSha: assessment.commitSha,
3096
+ });
3097
+ }
3098
+ recoverHistoricalStepProvenance(repository, taskId, expectedRevision, commitSha, actor, reason) {
3099
+ const normalizedActor = actor.trim();
3100
+ const normalizedReason = reason.trim();
3101
+ if (!normalizedActor)
3102
+ throw new WorkflowError('INVALID_ARGUMENT', 'Historical Step provenance recovery requires an actor.');
3103
+ if (!normalizedReason)
3104
+ throw new WorkflowError('INVALID_ARGUMENT', 'Historical Step provenance recovery requires a reason.');
3105
+ const context = this.#mutationContext(repository);
3106
+ const current = context.store.readTask(context.identity.projectId, taskId);
3107
+ const prior = current.historicalStepProvenanceRecoveries?.find((record) => record.commitSha === commitSha);
3108
+ if (prior && (current.invalidatedStepCommits ?? []).includes(commitSha)) {
3109
+ validateTaskHistory(context.identity.repositoryRoot, current);
3110
+ return current;
3111
+ }
3112
+ assertExpectedRevision(current, expectedRevision);
3113
+ const preflight = this.historicalStepProvenanceRecoveryPreflight(repository, taskId);
3114
+ if (!preflight.eligible || preflight.commitSha !== commitSha || !preflight.sourceFinalAcceptanceRecordedAt) {
3115
+ throw new WorkflowError('GIT_PRECONDITION_FAILED', 'The bounded historical Step provenance recovery preflight failed.', {
3116
+ taskId,
3117
+ requestedCommit: commitSha,
3118
+ candidateCommit: preflight.commitSha,
3119
+ blockers: preflight.blockers,
3120
+ });
3121
+ }
3122
+ const sourceAcceptance = current.authorizations.find((authorization) => authorization.kind === 'final_acceptance'
3123
+ && ['approved', 'superseded'].includes(authorization.decision)
3124
+ && authorization.headCommit === commitSha
3125
+ && authorization.recordedAt === preflight.sourceFinalAcceptanceRecordedAt
3126
+ && authorization.planHash
3127
+ && authorization.resultHash
3128
+ && authorization.evidenceHash);
3129
+ if (!sourceAcceptance?.planHash || !sourceAcceptance.resultHash || !sourceAcceptance.evidenceHash) {
3130
+ throw new WorkflowError('STATE_CONFLICT', 'The source final acceptance changed after historical provenance preflight.');
3131
+ }
3132
+ const saved = context.store.writeTask({
3133
+ ...current,
3134
+ invalidatedStepCommits: [...new Set([...(current.invalidatedStepCommits ?? []), commitSha])],
3135
+ historicalStepProvenanceRecoveries: [
3136
+ ...(current.historicalStepProvenanceRecoveries ?? []),
3137
+ {
3138
+ commitSha,
3139
+ actor: normalizedActor,
3140
+ reason: normalizedReason,
3141
+ recordedAt: this.now().toISOString(),
3142
+ sourceFinalAcceptanceRecordedAt: sourceAcceptance.recordedAt,
3143
+ sourcePlanHash: sourceAcceptance.planHash,
3144
+ sourceResultHash: sourceAcceptance.resultHash,
3145
+ sourceEvidenceHash: sourceAcceptance.evidenceHash,
3146
+ },
3147
+ ],
3148
+ }, expectedRevision);
3149
+ validateTaskHistory(context.identity.repositoryRoot, saved);
3150
+ return saved;
3151
+ }
3008
3152
  activeDownstreamProofDependencyRecoveryPreflight(repository, taskId) {
3009
3153
  const snapshot = this.observationSnapshot(repository);
3010
3154
  if (snapshot.observation.kind !== 'assessment') {
@@ -3152,6 +3296,9 @@ export class WorkflowService {
3152
3296
  recoverDownstreamProofReplanDependencyProvenance(repository, taskId, expectedRevision, actor, reason) {
3153
3297
  return this.recoverDependencyProvenanceCandidate(repository, taskId, expectedRevision, actor, reason, 'downstream-replan');
3154
3298
  }
3299
+ recoverHistoricalStepDependencyProvenance(repository, taskId, expectedRevision, actor, reason) {
3300
+ return this.recoverDependencyProvenanceCandidate(repository, taskId, expectedRevision, actor, reason, 'historical-step');
3301
+ }
3155
3302
  recoverDependencyProvenanceCandidate(repository, taskId, expectedRevision, actor, reason, recoveryMode) {
3156
3303
  const normalizedActor = actor.trim();
3157
3304
  const normalizedReason = reason.trim();
@@ -3166,7 +3313,9 @@ export class WorkflowService {
3166
3313
  && record.packageVersion === PACKAGE_VERSION
3167
3314
  && (recoveryMode === 'downstream-replan'
3168
3315
  ? Boolean(record.downstreamProofReplan)
3169
- : Boolean(record.activeDownstreamProof) === recoveryMode));
3316
+ : recoveryMode === 'historical-step'
3317
+ ? Boolean(record.historicalStepProvenance)
3318
+ : Boolean(record.activeDownstreamProof) === recoveryMode));
3170
3319
  if (prior && current.systemCommits.includes(currentHead))
3171
3320
  return current;
3172
3321
  assertExpectedRevision(current, expectedRevision);
@@ -3176,9 +3325,11 @@ export class WorkflowService {
3176
3325
  throw new WorkflowError('NOT_FOUND', `Task ${taskId} was not found in this repository.`);
3177
3326
  const preflight = recoveryMode === 'downstream-replan'
3178
3327
  ? this.downstreamProofReplanDependencyRecoveryPreflight(repository, taskId)
3179
- : recoveryMode
3180
- ? this.activeDownstreamProofDependencyRecoveryPreflight(repository, taskId)
3181
- : this.inspectDependencyProvenanceCandidate(snapshot, task);
3328
+ : recoveryMode === 'historical-step'
3329
+ ? this.historicalStepDependencyRecoveryPreflight(repository, taskId)
3330
+ : recoveryMode
3331
+ ? this.activeDownstreamProofDependencyRecoveryPreflight(repository, taskId)
3332
+ : this.inspectDependencyProvenanceCandidate(snapshot, task);
3182
3333
  if (!preflight.eligible || !preflight.commitSha || !preflight.parentCommitSha) {
3183
3334
  throw new WorkflowError('GIT_PRECONDITION_FAILED', 'The bounded dependency provenance recovery preflight failed.', {
3184
3335
  taskId,
@@ -3206,6 +3357,9 @@ export class WorkflowService {
3206
3357
  ...(preflight.downstreamProofReplan
3207
3358
  ? { downstreamProofReplan: preflight.downstreamProofReplan }
3208
3359
  : {}),
3360
+ ...(preflight.historicalStepProvenance
3361
+ ? { historicalStepProvenance: preflight.historicalStepProvenance }
3362
+ : {}),
3209
3363
  },
3210
3364
  ],
3211
3365
  }, expectedRevision);
@@ -3608,6 +3762,33 @@ export class WorkflowService {
3608
3762
  const activeTask = requestedTask
3609
3763
  ?? status.tasks.find((task) => taskIsActionableFromRepositoryNext(task, milestonesById, tasksById));
3610
3764
  if (activeTask) {
3765
+ const historicalStepProvenanceRecovery = this.historicalStepProvenanceRecoveryPreflight(repositoryRoot, activeTask.id);
3766
+ if (historicalStepProvenanceRecovery.eligible) {
3767
+ return withAdoption({
3768
+ scope: 'task',
3769
+ id: activeTask.id,
3770
+ status: activeTask.status,
3771
+ action: 'task historical-step-provenance-recover',
3772
+ revision: activeTask.revision,
3773
+ historicalStepProvenanceRecovery,
3774
+ });
3775
+ }
3776
+ const historicalStepDependencyRecovery = this.historicalStepDependencyRecoveryPreflight(repositoryRoot, activeTask.id);
3777
+ if (historicalStepDependencyRecovery.eligible) {
3778
+ return withAdoption({
3779
+ scope: 'task',
3780
+ id: activeTask.id,
3781
+ status: activeTask.status,
3782
+ action: 'update historical-step-dependency-recover',
3783
+ revision: activeTask.revision,
3784
+ dependencyProvenanceRecovery: historicalStepDependencyRecovery,
3785
+ compatibilityBoundary: {
3786
+ preservesWorktree: true,
3787
+ prerequisite: 'The active Milestone base and Task branch contain only the exact target dependency commits; the candidate parent still binds the reviewed historical Step commit.',
3788
+ continuation: 'Register the dependency commit and historical provenance atomically, then follow fresh next.',
3789
+ },
3790
+ });
3791
+ }
3611
3792
  const dependencyRecovery = this.dependencyProvenanceRecoveryPreflight(repositoryRoot, activeTask.id);
3612
3793
  if (dependencyRecovery.eligible) {
3613
3794
  return withAdoption({
@@ -5056,7 +5237,7 @@ export class WorkflowService {
5056
5237
  },
5057
5238
  };
5058
5239
  }
5059
- inspectDependencyProvenanceCandidate(snapshot, task, activeDownstreamProof = null, downstreamProofReplan = null) {
5240
+ inspectDependencyProvenanceCandidate(snapshot, task, activeDownstreamProof = null, downstreamProofReplan = null, historicalStepProvenance = null) {
5060
5241
  const versions = inspectWorkflowVersions(snapshot.identity.repositoryRoot, [task.baseBranch]);
5061
5242
  const now = this.now().getTime();
5062
5243
  return inspectDependencyProvenanceRecovery(snapshot.identity.repositoryRoot, task, {
@@ -5076,7 +5257,20 @@ export class WorkflowService {
5076
5257
  currentBranch: versions.currentBranch,
5077
5258
  baseBranch: versions.milestoneBases.find((base) => base.branch === task.baseBranch)?.version ?? null,
5078
5259
  },
5079
- }, activeDownstreamProof, downstreamProofReplan);
5260
+ }, activeDownstreamProof, downstreamProofReplan, historicalStepProvenance);
5261
+ }
5262
+ inspectHistoricalStepProvenanceCandidate(snapshot, task, options = {}) {
5263
+ const now = this.now().getTime();
5264
+ return inspectHistoricalStepProvenanceRecovery(snapshot.identity.repositoryRoot, task, {
5265
+ activeLeaseCount: snapshot.leases.filter((lease) => Date.parse(lease.expiresAt) > now).length,
5266
+ staleLeaseCount: snapshot.leases.filter((lease) => Date.parse(lease.expiresAt) <= now).length,
5267
+ pendingTransactionCount: snapshot.observation.pendingProjectTransactions.length
5268
+ + snapshot.observation.pendingMilestoneTransactions.length
5269
+ + snapshot.observation.pendingTaskTransactions.length,
5270
+ corruptTransactionCount: snapshot.observation.corruptTaskTransactions.length,
5271
+ coreOperationCount: snapshot.observation.coreTaskOperations.length,
5272
+ verifiedHistoricalStepBindings: verifiedHistoricalStepReviewBindings(this.store, task),
5273
+ }, options);
5080
5274
  }
5081
5275
  withTaskNavigationContracts(task, next) {
5082
5276
  const action = typeof next.action === 'string' ? next.action : null;
@@ -5114,7 +5308,7 @@ export class WorkflowService {
5114
5308
  return activeLeaseOwner;
5115
5309
  const authorizationKind = ['task merge', 'task merge-confirm'].includes(action)
5116
5310
  ? 'final_acceptance'
5117
- : ['task step-complete', 'task downstream-proof-recover', 'task submit'].includes(action)
5311
+ : ['task step-complete', 'task downstream-proof-recover', 'task submit', 'task result-set'].includes(action)
5118
5312
  ? 'execution'
5119
5313
  : null;
5120
5314
  if (!authorizationKind)
@@ -5902,6 +6096,7 @@ function writerTokenContractForAction(action, claimedC1Posture = false) {
5902
6096
  'task step-complete',
5903
6097
  'task downstream-proof-recover',
5904
6098
  'task submit',
6099
+ 'task result-set',
5905
6100
  'task merge',
5906
6101
  'task merge-confirm',
5907
6102
  ];