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.
- package/README.md +5 -2
- package/dist/src/alpha6/remediation.js +18 -6
- package/dist/src/alpha6/remediation.js.map +1 -1
- package/dist/src/alpha6/review.d.ts +1 -0
- package/dist/src/alpha6/review.js +8 -0
- package/dist/src/alpha6/review.js.map +1 -1
- package/dist/src/cli.js +25 -1
- package/dist/src/cli.js.map +1 -1
- package/dist/src/contracts.d.ts +56 -0
- package/dist/src/dependency-provenance.d.ts +18 -0
- package/dist/src/dependency-provenance.js +179 -0
- package/dist/src/dependency-provenance.js.map +1 -0
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/workflow.d.ts +5 -1
- package/dist/src/workflow.js +146 -3
- package/dist/src/workflow.js.map +1 -1
- package/docs/autonomy-guardrails.md +6 -6
- package/docs/delegated-approval.md +5 -3
- package/docs/development-flow.md +4 -4
- package/docs/release.md +4 -1
- package/docs/stable-release-defect-register.md +61 -2
- package/docs/updating-existing-project.md +7 -5
- package/docs/validation-report.md +70 -56
- package/package.json +1 -1
- package/plugins/codex-workflow-gateway/.codex-plugin/plugin.json +10 -3
- package/plugins/codex-workflow-gateway/references/protocol.md +14 -2
- package/plugins/codex-workflow-gateway/scripts/chat-registry.mjs +376 -0
- package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +51 -14
- package/roles/delivery-coordinator.md +10 -5
- package/schemas/task.schema.json +19 -1
package/dist/src/workflow.js
CHANGED
|
@@ -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) =>
|
|
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)
|