codex-workflow-v2 2.0.0-beta.7 → 2.0.0-beta.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.
@@ -2,6 +2,7 @@ import { appendFileSync, existsSync, lstatSync, readFileSync, readdirSync } from
2
2
  import { createHash } from 'node:crypto';
3
3
  import path from 'node:path';
4
4
  import { PROTOCOL_VERSION, STATE_SCHEMA_VERSION, } from './contracts.js';
5
+ import { inspectDependencyProvenanceRecovery } from './dependency-provenance.js';
5
6
  import { renderBrief, renderPlan, renderResult } from './artifacts.js';
6
7
  import { assertDelegationCanAuthorize, hashDelegationPolicy, prepareDelegationGrantGate, } from './delegation.js';
7
8
  import { assessDiscovery, mergeUnique } from './domain/discovery.js';
@@ -15,7 +16,7 @@ import { appendCurrentPlanRiskAudit, appendReboundPlanRiskAudit, readCurrentPlan
15
16
  import { appendCorrectiveDecisionEvent, appendRemediationEvent, appendRemediationModeRecovery, assertCorrectiveAuditorIndependence, assertGuardedRemediationAttemptAllowed, defaultCorrectiveAuditorActor, findCurrentGuardedRemediationPosture, findRemediationModeRecoveryCandidate, findFailedGuardedStepRequiringCorrectiveDecision, readGuardedRemediationPostureForStep, readCorrectiveDecisionEvents, readRemediationEvents, } from './alpha6/remediation.js';
16
17
  import { assessMilestoneInitialAssembly, applyMilestoneScopeChangeTransaction, assertMilestoneMembershipIntegrity, assertMilestoneScopeChangeStatusAllowed, inspectMilestoneWithIntegrity, normalizeMilestonePlan, prepareMilestoneScopeChangeCandidate, prepareMilestoneScopeChangeBundle, readMilestoneForScopeChange, readMilestoneWithIntegrity, } from './alpha6/milestone.js';
17
18
  import { applyProjectTransaction, recoverProjectTransactions, runRollbackProjectTransaction, } from './beta1/project-transaction.js';
18
- import { buildCurrentStrictStepReviewCycle, countUnverifiedStrictStepReviews, ensurePendingStrictStepReview, isStepReviewRequired, recordStrictStepReview, } from './alpha6/review.js';
19
+ import { buildCurrentStrictStepReviewCycle, countUnverifiedStrictStepReviews, ensurePendingStrictStepReview, isStepReviewRequired, latestPassedVerifiedStepReviewEvent, recordStrictStepReview, } from './alpha6/review.js';
19
20
  import { applyMilestoneAutonomyContract, assertAutonomousPlanEvolution, prepareMilestoneAutonomyContract, readMilestoneAutonomyEvents, requireActiveMilestoneAutonomy, } from './alpha7/autonomy.js';
20
21
  import { appendCorrectiveDecisionRecovery, readValidatedCorrectiveDecisionRecoveryForNavigation, requireCorrectiveDecisionRecoveryForRun, } from './alpha7/corrective-recovery.js';
21
22
  import { applyKnowledgeSelections, hashKnowledgeMap, inspectKnowledgeMap, normalizeRelativePath, reconcileKnowledgeMap, scanProjectKnowledge, selectKnowledgeSources, } from './memory.js';
@@ -32,7 +33,7 @@ import { createCorrectiveYieldExecutor } from './state/corrective-yield-executor
32
33
  import { createCorrectiveReplanPublicController, } from './state/corrective-replan-public.js';
33
34
  import { inspectWorkflowObservationBoundary, } from './observation.js';
34
35
  import { createEntityId } from './ulid.js';
35
- import { PACKAGE_VERSION } from './version.js';
36
+ import { PACKAGE_NAME, PACKAGE_VERSION } from './version.js';
36
37
  import { correctiveReplanBlockedNavigation, correctiveReplanNavigation, evaluateTaskCorrectiveReplanAvailability, evaluateTaskCorrectiveReplanCandidate, identifyCorrectiveReplanPosture, prepareCorrectiveReplanCandidate, TASK_CORRECTIVE_REPLAN_TRANSITION_ID, } from './lifecycle/corrective-replan.js';
37
38
  const MAX_STRICT_REVIEW_INFRASTRUCTURE_FAILURES = 2;
38
39
  export class WorkflowService {
@@ -1015,7 +1016,12 @@ export class WorkflowService {
1015
1016
  ? correctiveDecisionEvents.filter((event) => event.planHash === task.planHash)
1016
1017
  : [];
1017
1018
  const currentReplanDecisions = currentPlanCorrectiveDecisions.filter((event) => event.decision === 'replan-required');
1018
- const currentContinueFixDecisions = currentPlanCorrectiveDecisions.filter((event) => event.decision === 'continue-fix');
1019
+ const currentContinueFixDecisions = currentPlanCorrectiveDecisions.filter((event) => {
1020
+ if (event.decision !== 'continue-fix')
1021
+ return false;
1022
+ const passedBoundary = latestPassedVerifiedStepReviewEvent(this.store, task, event.stepId);
1023
+ return !passedBoundary || passedBoundary.recordedAt <= event.recordedAt;
1024
+ });
1019
1025
  const currentHardBlockingDecisions = currentPlanCorrectiveDecisions.filter((event) => event.decision === 'split-required' || event.decision === 'stop-escalate');
1020
1026
  const currentPlanRiskAudit = task.status === 'needs_fix' || currentReplanDecisions.length > 0
1021
1027
  ? readCurrentPlanRiskAudit(this.store, task)
@@ -2615,6 +2621,111 @@ export class WorkflowService {
2615
2621
  observation: snapshot.observation,
2616
2622
  };
2617
2623
  }
2624
+ dependencyProvenanceRecoveryPreflight(repository, taskId) {
2625
+ const snapshot = this.observationSnapshot(repository);
2626
+ if (snapshot.observation.kind !== 'assessment') {
2627
+ throw new WorkflowError('TRANSITION_BLOCKED', 'Dependency provenance recovery requires a coherent observation boundary.', {
2628
+ observation: snapshot.observation,
2629
+ });
2630
+ }
2631
+ const task = snapshot.tasks.find((candidate) => candidate.id === taskId);
2632
+ if (!task)
2633
+ throw new WorkflowError('NOT_FOUND', `Task ${taskId} was not found in this repository.`);
2634
+ return this.inspectDependencyProvenanceCandidate(snapshot, task);
2635
+ }
2636
+ recoverDependencyProvenance(repository, taskId, expectedRevision, actor, reason) {
2637
+ const normalizedActor = actor.trim();
2638
+ const normalizedReason = reason.trim();
2639
+ if (!normalizedActor)
2640
+ throw new WorkflowError('INVALID_ARGUMENT', 'Dependency provenance recovery requires an actor.');
2641
+ if (!normalizedReason)
2642
+ throw new WorkflowError('INVALID_ARGUMENT', 'Dependency provenance recovery requires a reason.');
2643
+ const context = this.#mutationContext(repository);
2644
+ const current = context.store.readTask(context.identity.projectId, taskId);
2645
+ const currentHead = headCommit(context.identity.repositoryRoot);
2646
+ const prior = current.dependencyProvenanceRecoveries?.find((record) => record.commitSha === currentHead && record.packageVersion === PACKAGE_VERSION);
2647
+ if (prior && current.systemCommits.includes(currentHead))
2648
+ return current;
2649
+ assertExpectedRevision(current, expectedRevision);
2650
+ const snapshot = this.observationSnapshot(repository);
2651
+ const task = snapshot.tasks.find((candidate) => candidate.id === taskId);
2652
+ if (!task)
2653
+ throw new WorkflowError('NOT_FOUND', `Task ${taskId} was not found in this repository.`);
2654
+ const preflight = this.inspectDependencyProvenanceCandidate(snapshot, task);
2655
+ if (!preflight.eligible || !preflight.commitSha || !preflight.parentCommitSha) {
2656
+ throw new WorkflowError('GIT_PRECONDITION_FAILED', 'The bounded dependency provenance recovery preflight failed.', {
2657
+ taskId,
2658
+ blockers: preflight.blockers,
2659
+ });
2660
+ }
2661
+ return context.store.writeTask({
2662
+ ...task,
2663
+ systemCommits: [...task.systemCommits, preflight.commitSha],
2664
+ dependencyProvenanceRecoveries: [
2665
+ ...(task.dependencyProvenanceRecoveries ?? []),
2666
+ {
2667
+ commitSha: preflight.commitSha,
2668
+ parentCommitSha: preflight.parentCommitSha,
2669
+ packageName: PACKAGE_NAME,
2670
+ packageVersion: PACKAGE_VERSION,
2671
+ files: ['package-lock.json', 'package.json'],
2672
+ actor: normalizedActor,
2673
+ reason: normalizedReason,
2674
+ recordedAt: this.now().toISOString(),
2675
+ },
2676
+ ],
2677
+ }, expectedRevision);
2678
+ }
2679
+ milestoneProgress(repository, milestoneId) {
2680
+ const snapshot = this.observationSnapshot(repository);
2681
+ if (snapshot.observation.kind !== 'assessment') {
2682
+ throw new WorkflowError('TRANSITION_BLOCKED', 'Milestone progress requires a coherent read-only observation boundary.', {
2683
+ observation: snapshot.observation,
2684
+ });
2685
+ }
2686
+ const milestone = snapshot.milestones.find((candidate) => candidate.id === milestoneId);
2687
+ if (!milestone)
2688
+ throw new WorkflowError('NOT_FOUND', `Milestone ${milestoneId} was not found in this repository.`);
2689
+ const tasksById = new Map(snapshot.tasks.map((task) => [task.id, task]));
2690
+ const tasks = milestone.memberships.map((membership, index) => {
2691
+ const task = tasksById.get(membership.taskId);
2692
+ if (!task)
2693
+ throw new WorkflowError('STATE_CORRUPT', `Milestone member ${membership.taskId} does not exist.`);
2694
+ const stepsCompleted = task.steps.filter((step) => ['completed', 'skipped'].includes(step.status)).length;
2695
+ return {
2696
+ ordinal: `T${String(index + 1).padStart(2, '0')}`,
2697
+ taskId: task.id,
2698
+ title: task.title,
2699
+ status: task.status,
2700
+ revision: task.revision,
2701
+ disposition: membership.disposition,
2702
+ membershipReason: membership.reason,
2703
+ replacementForTaskId: task.replacementForTaskId ?? null,
2704
+ replacedByTaskId: task.replacedByTaskId ?? null,
2705
+ stepsCompleted,
2706
+ stepsTotal: task.steps.length,
2707
+ steps: task.steps.map((step, stepIndex) => ({
2708
+ ordinal: `S${String(stepIndex + 1).padStart(2, '0')}`,
2709
+ stepId: step.id,
2710
+ title: step.title,
2711
+ status: step.status,
2712
+ })),
2713
+ };
2714
+ });
2715
+ const required = tasks.filter((task) => task.disposition === 'required');
2716
+ return {
2717
+ readOnly: true,
2718
+ projectId: snapshot.identity.projectId,
2719
+ milestoneId: milestone.id,
2720
+ milestoneTitle: milestone.title,
2721
+ milestoneStatus: milestone.status,
2722
+ milestoneRevision: milestone.revision,
2723
+ membershipRevision: milestone.membershipRevision,
2724
+ tasksCompleted: required.filter((task) => task.status === 'merged').length,
2725
+ tasksRequired: required.length,
2726
+ tasks,
2727
+ };
2728
+ }
2618
2729
  alpha6StrictReviewRescuePreflight(repository) {
2619
2730
  const context = this.#mutationContext(repository);
2620
2731
  const dependency = inspectLocalDependency(context.identity.repositoryRoot);
@@ -2934,6 +3045,17 @@ export class WorkflowService {
2934
3045
  const activeTask = requestedTask
2935
3046
  ?? status.tasks.find((task) => taskIsActionableFromRepositoryNext(task, milestonesById));
2936
3047
  if (activeTask) {
3048
+ const dependencyRecovery = this.dependencyProvenanceRecoveryPreflight(repositoryRoot, activeTask.id);
3049
+ if (dependencyRecovery.eligible) {
3050
+ return withAdoption({
3051
+ scope: 'task',
3052
+ id: activeTask.id,
3053
+ status: activeTask.status,
3054
+ action: 'update dependency-provenance-recover',
3055
+ revision: activeTask.revision,
3056
+ dependencyProvenanceRecovery: dependencyRecovery,
3057
+ });
3058
+ }
2937
3059
  const activeTaskMilestone = activeTask.milestoneId
2938
3060
  ? milestonesById.get(activeTask.milestoneId) ?? null
2939
3061
  : null;
@@ -3956,6 +4078,27 @@ export class WorkflowService {
3956
4078
  },
3957
4079
  };
3958
4080
  }
4081
+ inspectDependencyProvenanceCandidate(snapshot, task) {
4082
+ const versions = inspectWorkflowVersions(snapshot.identity.repositoryRoot, [task.baseBranch]);
4083
+ const now = this.now().getTime();
4084
+ return inspectDependencyProvenanceRecovery(snapshot.identity.repositoryRoot, task, {
4085
+ activeLeaseCount: snapshot.leases.filter((lease) => Date.parse(lease.expiresAt) > now).length,
4086
+ staleLeaseCount: snapshot.leases.filter((lease) => Date.parse(lease.expiresAt) <= now).length,
4087
+ pendingTransactionCount: snapshot.observation.pendingProjectTransactions.length
4088
+ + snapshot.observation.pendingMilestoneTransactions.length
4089
+ + snapshot.observation.pendingTaskTransactions.length,
4090
+ corruptTransactionCount: snapshot.observation.corruptTaskTransactions.length,
4091
+ coreOperationCount: snapshot.observation.coreTaskOperations.length,
4092
+ versions: {
4093
+ runtime: versions.runtime,
4094
+ declared: versions.declared,
4095
+ locked: versions.locked,
4096
+ installed: versions.installed,
4097
+ currentBranch: versions.currentBranch,
4098
+ baseBranch: versions.milestoneBases.find((base) => base.branch === task.baseBranch)?.version ?? null,
4099
+ },
4100
+ });
4101
+ }
3959
4102
  withTaskNavigationContracts(task, next) {
3960
4103
  const action = typeof next.action === 'string' ? next.action : null;
3961
4104
  if (!action)