codex-workflow-v2 2.0.0-beta.13.9 → 2.0.0-beta.14
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 +27 -388
- package/dist/reviewer-runtime-build.json +89 -29
- package/dist/src/alpha6/adoption.d.ts +2 -0
- package/dist/src/alpha6/adoption.js +22 -0
- package/dist/src/alpha6/adoption.js.map +1 -1
- package/dist/src/alpha6/captured-check-evidence.d.ts +51 -0
- package/dist/src/alpha6/captured-check-evidence.js +152 -0
- package/dist/src/alpha6/captured-check-evidence.js.map +1 -0
- package/dist/src/alpha6/component-owner.d.ts +15 -1
- package/dist/src/alpha6/component-owner.js +44 -2
- package/dist/src/alpha6/component-owner.js.map +1 -1
- package/dist/src/alpha6/corrective-decision-boundary.d.ts +4 -0
- package/dist/src/alpha6/corrective-decision-boundary.js +47 -0
- package/dist/src/alpha6/corrective-decision-boundary.js.map +1 -0
- package/dist/src/alpha6/downstream-proof.d.ts +1 -25
- package/dist/src/alpha6/downstream-proof.js +0 -171
- package/dist/src/alpha6/downstream-proof.js.map +1 -1
- package/dist/src/alpha6/literal-test-invocation.d.ts +2 -0
- package/dist/src/alpha6/literal-test-invocation.js +106 -0
- package/dist/src/alpha6/literal-test-invocation.js.map +1 -0
- package/dist/src/alpha6/milestone.d.ts +2 -0
- package/dist/src/alpha6/milestone.js +10 -1
- package/dist/src/alpha6/milestone.js.map +1 -1
- package/dist/src/alpha6/navigation-dirty-carryover.d.ts +11 -0
- package/dist/src/alpha6/navigation-dirty-carryover.js +130 -0
- package/dist/src/alpha6/navigation-dirty-carryover.js.map +1 -0
- package/dist/src/alpha6/plan-integrity.js +7 -5
- package/dist/src/alpha6/plan-integrity.js.map +1 -1
- package/dist/src/alpha6/remediation.d.ts +6 -21
- package/dist/src/alpha6/remediation.js +161 -476
- package/dist/src/alpha6/remediation.js.map +1 -1
- package/dist/src/alpha6/root-cause-replan-carryover.d.ts +4 -1
- package/dist/src/alpha6/root-cause-replan-carryover.js +29 -5
- package/dist/src/alpha6/root-cause-replan-carryover.js.map +1 -1
- package/dist/src/beta1/project-transaction.d.ts +3 -1
- package/dist/src/beta1/project-transaction.js +6 -2
- package/dist/src/beta1/project-transaction.js.map +1 -1
- package/dist/src/checks/runner.d.ts +26 -0
- package/dist/src/checks/runner.js +223 -0
- package/dist/src/checks/runner.js.map +1 -0
- package/dist/src/checks/task-sync.d.ts +10 -0
- package/dist/src/checks/task-sync.js +41 -0
- package/dist/src/checks/task-sync.js.map +1 -0
- package/dist/src/checks/worker.d.ts +1 -0
- package/dist/src/checks/worker.js +154 -0
- package/dist/src/checks/worker.js.map +1 -0
- package/dist/src/cli-actions.d.ts +2 -2
- package/dist/src/cli-actions.js +3 -15
- package/dist/src/cli-actions.js.map +1 -1
- package/dist/src/cli.js +14 -98
- package/dist/src/cli.js.map +1 -1
- package/dist/src/contracts.d.ts +35 -32
- package/dist/src/dependency-provenance.d.ts +2 -2
- package/dist/src/dependency-provenance.js +12 -69
- package/dist/src/dependency-provenance.js.map +1 -1
- package/dist/src/domain/base-sync-conflict.d.ts +13 -0
- package/dist/src/domain/base-sync-conflict.js +32 -0
- package/dist/src/domain/base-sync-conflict.js.map +1 -0
- package/dist/src/domain/step-start-admission.d.ts +4 -0
- package/dist/src/domain/step-start-admission.js +9 -0
- package/dist/src/domain/step-start-admission.js.map +1 -0
- package/dist/src/domain/virgin-registration.d.ts +3 -0
- package/dist/src/domain/virgin-registration.js +65 -0
- package/dist/src/domain/virgin-registration.js.map +1 -0
- package/dist/src/errors.d.ts +1 -1
- package/dist/src/errors.js.map +1 -1
- package/dist/src/gateway-handshake.js +0 -8
- package/dist/src/gateway-handshake.js.map +1 -1
- package/dist/src/git.d.ts +3 -1
- package/dist/src/git.js +41 -14
- package/dist/src/git.js.map +1 -1
- package/dist/src/graph.js +25 -3
- package/dist/src/graph.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/navigation-actions.d.ts +9 -0
- package/dist/src/navigation-actions.js +72 -0
- package/dist/src/navigation-actions.js.map +1 -0
- package/dist/src/navigation-update-artifact.d.ts +5 -0
- package/dist/src/navigation-update-artifact.js +227 -0
- package/dist/src/navigation-update-artifact.js.map +1 -0
- package/dist/src/navigation-update.d.ts +39 -0
- package/dist/src/navigation-update.js +82 -0
- package/dist/src/navigation-update.js.map +1 -0
- package/dist/src/observation.js +52 -29
- package/dist/src/observation.js.map +1 -1
- package/dist/src/observed-routes.js +5 -6
- package/dist/src/observed-routes.js.map +1 -1
- package/dist/src/pending-review-update.d.ts +0 -13
- package/dist/src/pending-review-update.js +1 -6
- package/dist/src/pending-review-update.js.map +1 -1
- package/dist/src/reviewer.d.ts +1 -1
- package/dist/src/reviewer.js +20 -17
- package/dist/src/reviewer.js.map +1 -1
- package/dist/src/runtime.d.ts +3 -0
- package/dist/src/runtime.js +6 -0
- package/dist/src/runtime.js.map +1 -0
- package/dist/src/state/corrective-replan-executor.d.ts +10 -0
- package/dist/src/state/corrective-replan-executor.js +37 -1
- package/dist/src/state/corrective-replan-executor.js.map +1 -1
- package/dist/src/state/corrective-replan-public-schema.js +15 -2
- package/dist/src/state/corrective-replan-public-schema.js.map +1 -1
- package/dist/src/state/corrective-replan-public.js +1 -1
- package/dist/src/state/corrective-replan-public.js.map +1 -1
- package/dist/src/state/corrective-replan-transaction.d.ts +1 -0
- package/dist/src/state/corrective-replan-transaction.js +12 -11
- package/dist/src/state/corrective-replan-transaction.js.map +1 -1
- package/dist/src/state/corrective-yield-transaction.d.ts +1 -0
- package/dist/src/state/corrective-yield-transaction.js +11 -10
- package/dist/src/state/corrective-yield-transaction.js.map +1 -1
- package/dist/src/state/lock.d.ts +4 -0
- package/dist/src/state/lock.js +21 -0
- package/dist/src/state/lock.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-blocker-route.d.ts +8 -0
- package/dist/src/workflow-blocker-route.js +106 -0
- package/dist/src/workflow-blocker-route.js.map +1 -0
- package/dist/src/workflow.d.ts +48 -63
- package/dist/src/workflow.js +666 -1460
- package/dist/src/workflow.js.map +1 -1
- package/docs/autonomy-guardrails.md +26 -304
- package/docs/decisions.md +14 -112
- package/docs/development-flow.md +35 -238
- package/docs/project-memory.md +31 -50
- package/docs/release-app-evidence.md +190 -0
- package/docs/release.md +95 -388
- package/docs/updating-existing-project.md +19 -717
- package/package.json +11 -13
- package/plugins/codex-workflow-gateway/.codex-plugin/plugin.json +2 -2
- package/plugins/codex-workflow-gateway/references/chat-dispatch.md +73 -197
- package/plugins/codex-workflow-gateway/references/codebase-memory-routing.md +57 -0
- package/plugins/codex-workflow-gateway/references/protocol.md +42 -445
- package/plugins/codex-workflow-gateway/scripts/chat-dispatch.mjs +7 -1
- package/plugins/codex-workflow-gateway/scripts/chat-model-policy.mjs +10 -8
- package/plugins/codex-workflow-gateway/scripts/chat-registry.mjs +23 -5
- package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +66 -757
- package/references/state-machine.md +4 -4
- package/roles/technical-planner.md +1 -1
- package/schemas/corrective-decision-event.schema.json +3 -1
- package/schemas/project-knowledge-map.schema.json +3 -1
- package/schemas/remediation-event.schema.json +10 -1
- package/schemas/task.schema.json +46 -2
- package/schemas/transition-payloads.schema.json +16 -1
- package/src/alpha6/adoption.ts +1123 -0
- package/src/alpha6/captured-check-evidence.ts +132 -0
- package/src/alpha6/check-support-anchor.ts +128 -0
- package/src/alpha6/component-owner.ts +168 -0
- package/src/alpha6/corrective-decision-boundary.ts +39 -0
- package/src/alpha6/downstream-proof.ts +520 -0
- package/src/alpha6/failed-step-planning-recovery.ts +88 -0
- package/src/alpha6/handoff.ts +1443 -0
- package/src/alpha6/journal.ts +473 -0
- package/src/alpha6/literal-test-invocation.ts +84 -0
- package/src/alpha6/mechanical-feasibility.ts +488 -0
- package/src/alpha6/milestone.ts +2192 -0
- package/src/alpha6/navigation-dirty-carryover.ts +154 -0
- package/src/alpha6/npm-check-contract.ts +47 -0
- package/src/alpha6/plan-integrity.ts +298 -0
- package/src/alpha6/plan-risk.ts +1480 -0
- package/src/alpha6/preexecution-replan.ts +187 -0
- package/src/alpha6/remediation-cause.ts +98 -0
- package/src/alpha6/remediation.ts +2438 -0
- package/src/alpha6/review.ts +1198 -0
- package/src/alpha6/root-cause-replan-carryover.ts +491 -0
- package/src/alpha6/store-sidecars.ts +335 -0
- package/src/alpha7/autonomy.ts +411 -0
- package/src/alpha7/corrective-recovery.ts +1332 -0
- package/src/artifacts.ts +130 -0
- package/src/beta1/project-transaction.ts +355 -0
- package/src/change-explanation.ts +153 -0
- package/src/checks/runner.ts +245 -0
- package/src/checks/task-sync.ts +41 -0
- package/src/checks/worker.ts +149 -0
- package/src/cli-actions.ts +107 -0
- package/src/cli.ts +1457 -0
- package/src/contracts.ts +1494 -0
- package/src/credential-output.ts +89 -0
- package/src/credential-transport.ts +215 -0
- package/src/delegation.ts +190 -0
- package/src/dependency-provenance.ts +472 -0
- package/src/diagnostics.ts +93 -0
- package/src/domain/base-sync-conflict.ts +35 -0
- package/src/domain/completed-step-carryover.ts +76 -0
- package/src/domain/discovery.ts +27 -0
- package/src/domain/plan-semantics.ts +58 -0
- package/src/domain/step-start-admission.ts +10 -0
- package/src/domain/validation.ts +177 -0
- package/src/domain/virgin-registration.ts +46 -0
- package/src/errors.ts +24 -0
- package/src/fs-utils.ts +61 -0
- package/src/gateway-handshake.ts +95 -0
- package/src/git.ts +183 -0
- package/src/graph.ts +342 -0
- package/src/historical-step-provenance.ts +136 -0
- package/src/index.ts +23 -0
- package/src/lifecycle/canonical-hash.ts +28 -0
- package/src/lifecycle/catalog.ts +202 -0
- package/src/lifecycle/compiler-inspection.ts +29 -0
- package/src/lifecycle/core-static-readiness.ts +132 -0
- package/src/lifecycle/corrective-replan-authority.ts +136 -0
- package/src/lifecycle/corrective-replan-binding-manifest.ts +51 -0
- package/src/lifecycle/corrective-replan-credential-core.ts +408 -0
- package/src/lifecycle/corrective-replan-credential-schema.ts +54 -0
- package/src/lifecycle/corrective-replan-credentials.ts +48 -0
- package/src/lifecycle/corrective-replan.ts +843 -0
- package/src/lifecycle/evaluator.ts +48 -0
- package/src/lifecycle/fingerprint.ts +488 -0
- package/src/lifecycle/immutable.ts +8 -0
- package/src/lifecycle/implementation-table.ts +118 -0
- package/src/lifecycle/index.ts +8 -0
- package/src/lifecycle/schema-artifact.ts +263 -0
- package/src/lifecycle/semantic-registry.ts +572 -0
- package/src/lifecycle/types.ts +838 -0
- package/src/memory.ts +273 -0
- package/src/migration.ts +161 -0
- package/src/navigation-actions.ts +70 -0
- package/src/navigation-update-artifact.ts +198 -0
- package/src/navigation-update.ts +121 -0
- package/src/observation.ts +225 -0
- package/src/observed-routes.ts +660 -0
- package/src/operational-contract.ts +125 -0
- package/src/pending-review-update.ts +175 -0
- package/src/repository.ts +99 -0
- package/src/reviewer.ts +1879 -0
- package/src/runtime.ts +6 -0
- package/src/state/corrective-replan-executor.ts +818 -0
- package/src/state/corrective-replan-public-schema.ts +83 -0
- package/src/state/corrective-replan-public.ts +908 -0
- package/src/state/corrective-replan-transaction.ts +949 -0
- package/src/state/corrective-yield-executor.ts +327 -0
- package/src/state/corrective-yield-transaction.ts +730 -0
- package/src/state/lock.ts +902 -0
- package/src/state/store.ts +567 -0
- package/src/transition-core.ts +330 -0
- package/src/ulid.ts +24 -0
- package/src/version.ts +2 -0
- package/src/workflow-blocker-route.ts +109 -0
- package/src/workflow.ts +10172 -0
- package/docs/alpha7.1-implementation-brief.md +0 -268
- package/docs/alpha7.2-corrective-context-refresh-brief.md +0 -484
- package/docs/alpha7.2.1-remediation-recovery-brief.md +0 -86
- package/docs/beta1-stabilization-brief.md +0 -165
- package/docs/beta11-plan-integrity-recovery-brief.md +0 -38
- package/docs/beta13.2-signal-review-recovery.md +0 -38
- package/docs/beta2-initial-assembly-navigation-brief.md +0 -616
- package/docs/change-model.md +0 -118
- package/docs/delegated-approval.md +0 -254
- package/docs/lifecycle/state-machine-stabilization.md +0 -641
- package/docs/pdf/README.md +0 -24
- 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/requirements.txt +0 -1
- package/docs/pdf/sources/codex-workflow-v2-architecture-ru.md +0 -478
- package/docs/pdf/sources/codex-workflow-v2-chat-only-guide-ru.md +0 -506
- package/docs/pdf/sources/codex-workflow-v2-technical-reference-ru.md +0 -778
- package/docs/pending-review-update.md +0 -15
- package/docs/problem-briefs/01-pre-implementation-integrity.md +0 -482
- package/docs/problem-briefs/02-minimal-step-integrity.md +0 -411
- package/docs/problem-briefs/03-minimal-agent-context-integrity.md +0 -358
- package/docs/problem-briefs/04-task-dependency-and-structural-replacement-integrity.md +0 -573
- package/docs/problem-briefs/BRIEF-TEMPLATE.md +0 -56
- package/docs/problem-briefs/README.md +0 -120
- package/docs/problem-briefs/evidence/p01-mechanical-feasibility-corpus.md +0 -90
- package/docs/problem-briefs/evidence/signal-v4-pre-m3-replay.md +0 -246
- package/docs/split-required-recovery.md +0 -47
- package/docs/stable-release-defect-register.md +0 -730
- package/docs/validation-report.md +0 -182
- package/scripts/generate-pdf-docs.py +0 -524
- package/scripts/run-pdf-docs.mjs +0 -62
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { DiscoveryState } from '../contracts.js';
|
|
2
|
+
|
|
3
|
+
export interface DiscoveryReadiness {
|
|
4
|
+
ready: boolean;
|
|
5
|
+
status: 'needs_discovery' | 'needs_clarification' | 'ready_to_materialize';
|
|
6
|
+
missing: string[];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function assessDiscovery(discovery: DiscoveryState): DiscoveryReadiness {
|
|
10
|
+
const missing: string[] = [];
|
|
11
|
+
if (!discovery.goal.trim()) missing.push('goal');
|
|
12
|
+
if (!discovery.outcome?.trim()) missing.push('observable outcome');
|
|
13
|
+
if (discovery.scope.length === 0) missing.push('scope');
|
|
14
|
+
if (discovery.acceptance.length === 0) missing.push('acceptance scenario');
|
|
15
|
+
if (discovery.blockingUnknowns.length > 0) missing.push('resolved blocking unknowns');
|
|
16
|
+
if (missing.length === 0) return { ready: true, status: 'ready_to_materialize', missing };
|
|
17
|
+
const hasInitialUnderstanding = Boolean(discovery.goal.trim() && (discovery.outcome || discovery.scope.length > 0));
|
|
18
|
+
return {
|
|
19
|
+
ready: false,
|
|
20
|
+
status: hasInitialUnderstanding ? 'needs_clarification' : 'needs_discovery',
|
|
21
|
+
missing,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function mergeUnique(current: string[], additions: string[]): string[] {
|
|
26
|
+
return [...new Set([...current, ...additions].map((value) => value.trim()).filter(Boolean))];
|
|
27
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { WorkflowError } from '../errors.js';
|
|
5
|
+
|
|
6
|
+
const HASH64 = /^[a-f0-9]{64}$/;
|
|
7
|
+
const KNOWLEDGE_LINE = /^- Knowledge map: revision ([1-9]\d*), hash ([a-f0-9]{64})$/gm;
|
|
8
|
+
const KNOWLEDGE_SENTINEL = '- Knowledge map: revision <context>, hash <context>';
|
|
9
|
+
|
|
10
|
+
export interface NormalizedPlanSemantics {
|
|
11
|
+
normalized: string;
|
|
12
|
+
semanticHash: string;
|
|
13
|
+
binding: { revision: number; hash: string };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function normalizePlanKnowledgeBinding(content: string, label: string): NormalizedPlanSemantics {
|
|
17
|
+
const matches = [...content.matchAll(KNOWLEDGE_LINE)];
|
|
18
|
+
if (matches.length !== 1) {
|
|
19
|
+
throw new WorkflowError('STATE_CORRUPT', `${label} Plan must contain exactly one canonical Knowledge Map binding line.`, {
|
|
20
|
+
matchCount: matches.length,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
const match = matches[0]!;
|
|
24
|
+
const normalized = content.slice(0, match.index) + KNOWLEDGE_SENTINEL + content.slice(match.index! + match[0].length);
|
|
25
|
+
return {
|
|
26
|
+
normalized,
|
|
27
|
+
semanticHash: sha256Hex(normalized),
|
|
28
|
+
binding: { revision: Number(match[1]), hash: match[2]! },
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function assertKnowledgeBindingOnlyPlanChange(historical: string, current: string): string {
|
|
33
|
+
const source = normalizePlanKnowledgeBinding(historical, 'historical');
|
|
34
|
+
const target = normalizePlanKnowledgeBinding(current, 'current');
|
|
35
|
+
if (source.normalized !== target.normalized) {
|
|
36
|
+
throw new WorkflowError('TRANSITION_BLOCKED', 'Corrective recovery permits only the Knowledge Map binding line to change.');
|
|
37
|
+
}
|
|
38
|
+
return source.semanticHash;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function readVerifiedPlanArtifact(taskRoot: string, planHash: string, currentPlanHash: string): string {
|
|
42
|
+
if (!HASH64.test(planHash)) throw new WorkflowError('STATE_CORRUPT', 'Plan hash is malformed.', { planHash });
|
|
43
|
+
const file = planHash === currentPlanHash
|
|
44
|
+
? path.join(taskRoot, 'plan.md')
|
|
45
|
+
: path.join(taskRoot, '.versions', `plan.md.${planHash}`);
|
|
46
|
+
if (!existsSync(file)) {
|
|
47
|
+
throw new WorkflowError('STATE_CORRUPT', 'Plan artifact required by lifecycle evidence is missing.', { planHash, file });
|
|
48
|
+
}
|
|
49
|
+
const content = readFileSync(file, 'utf8');
|
|
50
|
+
if (sha256Hex(content) !== planHash) {
|
|
51
|
+
throw new WorkflowError('STATE_CORRUPT', 'Plan artifact content does not match its recorded hash.', { planHash, file });
|
|
52
|
+
}
|
|
53
|
+
return content;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function sha256Hex(value: string): string {
|
|
57
|
+
return createHash('sha256').update(value).digest('hex');
|
|
58
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { StepStatus } from '../contracts.js';
|
|
2
|
+
|
|
3
|
+
export type StepStartPhase = 'planned-clean' | 'planned-dirty' | 'failed-retry' | 'not-startable';
|
|
4
|
+
|
|
5
|
+
/** Replacement carryover admits a first start; a retry uses its current write scope. */
|
|
6
|
+
export function stepStartPhase(status: StepStatus | undefined, hasDirtyFiles: boolean): StepStartPhase {
|
|
7
|
+
if (status === 'planned') return hasDirtyFiles ? 'planned-dirty' : 'planned-clean';
|
|
8
|
+
if (status === 'failed') return 'failed-retry';
|
|
9
|
+
return 'not-startable';
|
|
10
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
PlanRiskAuditStepClassification,
|
|
3
|
+
TaskPlanInput,
|
|
4
|
+
TaskState,
|
|
5
|
+
} from '../contracts.js';
|
|
6
|
+
import { WorkflowError } from '../errors.js';
|
|
7
|
+
|
|
8
|
+
export function validatePlan(plan: TaskPlanInput): void {
|
|
9
|
+
const issues: string[] = [];
|
|
10
|
+
if (!plan.objective.trim()) issues.push('Plan objective is required.');
|
|
11
|
+
if (plan.requirements.length === 0) issues.push('At least one requirement is required.');
|
|
12
|
+
if (plan.acceptance.length === 0) issues.push('At least one acceptance scenario is required.');
|
|
13
|
+
if (plan.steps.length === 0) issues.push('At least one STEP-* is required.');
|
|
14
|
+
if (!plan.knowledgeImpactReason.trim()) issues.push('knowledgeImpactReason is required.');
|
|
15
|
+
if (!Number.isInteger(plan.knowledgeMapRevision) || plan.knowledgeMapRevision < 1) {
|
|
16
|
+
issues.push('knowledgeMapRevision must be a positive integer.');
|
|
17
|
+
}
|
|
18
|
+
if (!/^[a-f0-9]{64}$/.test(plan.knowledgeMapHash)) issues.push('knowledgeMapHash must be a SHA-256 hash.');
|
|
19
|
+
if (plan.knowledgeImpact === 'none' && plan.knowledgeTargets.length > 0) {
|
|
20
|
+
issues.push('knowledgeImpact none cannot declare knowledgeTargets.');
|
|
21
|
+
}
|
|
22
|
+
if (plan.knowledgeImpact !== 'none' && plan.knowledgeTargets.length === 0) {
|
|
23
|
+
issues.push(`knowledgeImpact ${plan.knowledgeImpact} requires at least one knowledgeTarget.`);
|
|
24
|
+
}
|
|
25
|
+
for (const target of plan.knowledgeTargets) {
|
|
26
|
+
if (!target.reason.trim()) issues.push(`Knowledge target ${target.path} requires a reason.`);
|
|
27
|
+
if (target.requirementIds.length === 0) issues.push(`Knowledge target ${target.path} requires requirementIds.`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const ids = new Set<string>();
|
|
31
|
+
for (const step of plan.steps) {
|
|
32
|
+
if (!/^STEP-[0-9]{3}(?:-[A-Z0-9-]+)?$/.test(step.id)) issues.push(`Invalid Step id: ${step.id}`);
|
|
33
|
+
if (ids.has(step.id)) issues.push(`Duplicate Step id: ${step.id}`);
|
|
34
|
+
ids.add(step.id);
|
|
35
|
+
if (!step.title.trim() || !step.objective.trim()) issues.push(`${step.id} requires title and objective.`);
|
|
36
|
+
if (step.requirements.length === 0) issues.push(`${step.id} must cover at least one requirement.`);
|
|
37
|
+
if (step.allowedWrites.length === 0) issues.push(`${step.id} must declare allowedWrites.`);
|
|
38
|
+
if (step.expectedOutputs.length === 0) issues.push(`${step.id} must declare expectedOutputs.`);
|
|
39
|
+
if (step.checks.length === 0) issues.push(`${step.id} must declare at least one executable check.`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for (const step of plan.steps) {
|
|
43
|
+
for (const dependency of step.dependencies) {
|
|
44
|
+
if (!ids.has(dependency)) issues.push(`${step.id} depends on missing ${dependency}.`);
|
|
45
|
+
if (dependency === step.id) issues.push(`${step.id} cannot depend on itself.`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const covered = new Set(plan.steps.flatMap((step) => step.requirements));
|
|
50
|
+
for (const requirement of plan.requirements) {
|
|
51
|
+
if (!covered.has(requirement)) issues.push(`Requirement is not covered by any Step: ${requirement}`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const visiting = new Set<string>();
|
|
55
|
+
const visited = new Set<string>();
|
|
56
|
+
const byId = new Map(plan.steps.map((step) => [step.id, step]));
|
|
57
|
+
const visit = (stepId: string): void => {
|
|
58
|
+
if (visited.has(stepId)) return;
|
|
59
|
+
if (visiting.has(stepId)) {
|
|
60
|
+
issues.push(`Step dependency cycle includes ${stepId}.`);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
visiting.add(stepId);
|
|
64
|
+
for (const dependency of byId.get(stepId)?.dependencies ?? []) visit(dependency);
|
|
65
|
+
visiting.delete(stepId);
|
|
66
|
+
visited.add(stepId);
|
|
67
|
+
};
|
|
68
|
+
for (const step of plan.steps) visit(step.id);
|
|
69
|
+
|
|
70
|
+
const productionEdges = plan.productionEdges ?? [];
|
|
71
|
+
if (plan.requiresProductionEdges && productionEdges.length === 0) {
|
|
72
|
+
issues.push('Plan requiresProductionEdges but declares no explicit production edge.');
|
|
73
|
+
}
|
|
74
|
+
if (!plan.requiresProductionEdges && productionEdges.length > 0) {
|
|
75
|
+
issues.push('Plan declares productionEdges without the explicit requiresProductionEdges boundary.');
|
|
76
|
+
}
|
|
77
|
+
const edgeKeys = new Set<string>();
|
|
78
|
+
for (const edge of productionEdges) {
|
|
79
|
+
const key = `${edge.ownerStepId}\0${edge.consumerStepId}\0${edge.checkRef}`;
|
|
80
|
+
if (edgeKeys.has(key)) issues.push(`Duplicate production edge: ${edge.ownerStepId} -> ${edge.consumerStepId}.`);
|
|
81
|
+
edgeKeys.add(key);
|
|
82
|
+
const owner = byId.get(edge.ownerStepId);
|
|
83
|
+
const consumer = byId.get(edge.consumerStepId);
|
|
84
|
+
if (!owner) issues.push(`Production edge owner is missing: ${edge.ownerStepId}.`);
|
|
85
|
+
if (!consumer) issues.push(`Production edge consumer is missing: ${edge.consumerStepId}.`);
|
|
86
|
+
if (owner && consumer && owner.id === consumer.id) issues.push(`Production edge cannot self-reference ${owner.id}.`);
|
|
87
|
+
if (owner && consumer && !transitiveDependencies(consumer.id, byId).has(owner.id)) {
|
|
88
|
+
issues.push(`Production edge owner ${owner.id} is not a transitive dependency of consumer ${consumer.id}.`);
|
|
89
|
+
}
|
|
90
|
+
if (consumer && !consumer.checks.includes(edge.checkRef)) {
|
|
91
|
+
issues.push(`Production edge ${edge.ownerStepId} -> ${edge.consumerStepId} names a check not executed by its consumer.`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (issues.length > 0) throw new WorkflowError('TRANSITION_BLOCKED', 'Plan is not execution-ready.', { issues });
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Derive the narrow beta.13 structural integration obligation from the independent
|
|
100
|
+
* Plan Risk Audit rather than trusting the planner-owned opt-in flag. This is not
|
|
101
|
+
* semantic output-to-evidence authority (P02): it only proves that a multi-Step
|
|
102
|
+
* runtime-composition Plan names an inbound production hand-off and executes its
|
|
103
|
+
* exact check in the consumer Step.
|
|
104
|
+
*/
|
|
105
|
+
export function validateStructuralProductionEdgeAuthority(
|
|
106
|
+
task: Pick<TaskState, 'id' | 'steps' | 'productionEdges' | 'requiresProductionEdges'>,
|
|
107
|
+
classifications: readonly PlanRiskAuditStepClassification[],
|
|
108
|
+
): void {
|
|
109
|
+
if (task.steps.length < 2) return;
|
|
110
|
+
const integrationConsumerIds = classifications
|
|
111
|
+
.filter((classification) => classification.categories.includes('runtime-composition'))
|
|
112
|
+
.map((classification) => classification.stepId)
|
|
113
|
+
.sort();
|
|
114
|
+
if (integrationConsumerIds.length === 0) return;
|
|
115
|
+
|
|
116
|
+
const edges = task.productionEdges ?? [];
|
|
117
|
+
const byId = new Map(task.steps.map((step) => [step.id, step]));
|
|
118
|
+
const missingConsumerEdgeIds = integrationConsumerIds.filter((consumerStepId) =>
|
|
119
|
+
!edges.some((edge) => edge.consumerStepId === consumerStepId));
|
|
120
|
+
const blockingGuardIds = [
|
|
121
|
+
...(task.requiresProductionEdges === true ? [] : ['task.production-edge.explicit-boundary']),
|
|
122
|
+
...(edges.length > 0 ? [] : ['task.production-edge.non-empty']),
|
|
123
|
+
...(missingConsumerEdgeIds.length > 0 ? ['task.production-edge.runtime-consumer-covered'] : []),
|
|
124
|
+
];
|
|
125
|
+
for (const edge of edges) {
|
|
126
|
+
const consumer = byId.get(edge.consumerStepId);
|
|
127
|
+
const owner = byId.get(edge.ownerStepId);
|
|
128
|
+
if (!consumer || !owner || !transitiveDependencies(consumer.id, byId).has(owner.id)
|
|
129
|
+
|| !consumer.checks.includes(edge.checkRef)) {
|
|
130
|
+
blockingGuardIds.push('task.production-edge.executable-predecessor-binding');
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (blockingGuardIds.length === 0) return;
|
|
135
|
+
throw new WorkflowError(
|
|
136
|
+
'TRANSITION_BLOCKED',
|
|
137
|
+
`Runtime-composition authority for Task ${task.id} requires explicit production-edge coverage.`,
|
|
138
|
+
{
|
|
139
|
+
diagnosticCode: 'STRUCTURAL_PRODUCTION_EDGE_REQUIRED',
|
|
140
|
+
triggerAuthority: 'plan-risk-audit.runtime-composition',
|
|
141
|
+
integrationConsumerStepIds: integrationConsumerIds,
|
|
142
|
+
missingConsumerEdgeIds,
|
|
143
|
+
blockingGuardIds: [...new Set(blockingGuardIds)],
|
|
144
|
+
semanticAuthorityClaimed: false,
|
|
145
|
+
requiredAction: 'Declare requiresProductionEdges=true and bind each runtime-composition consumer to a transitive owner and one exact consumer check.',
|
|
146
|
+
},
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function transitiveDependencies(
|
|
151
|
+
stepId: string,
|
|
152
|
+
byId: ReadonlyMap<string, TaskPlanInput['steps'][number]>,
|
|
153
|
+
): Set<string> {
|
|
154
|
+
const result = new Set<string>();
|
|
155
|
+
const visit = (candidateId: string): void => {
|
|
156
|
+
for (const dependency of byId.get(candidateId)?.dependencies ?? []) {
|
|
157
|
+
if (result.has(dependency)) continue;
|
|
158
|
+
result.add(dependency);
|
|
159
|
+
visit(dependency);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
visit(stepId);
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export function pathAllowed(file: string, patterns: string[]): boolean {
|
|
167
|
+
const normalized = file.replaceAll('\\', '/').replace(/^\.\//, '');
|
|
168
|
+
return patterns.some((pattern) => {
|
|
169
|
+
const candidate = pattern.replaceAll('\\', '/').replace(/^\.\//, '');
|
|
170
|
+
if (candidate.endsWith('/**')) return normalized === candidate.slice(0, -3) || normalized.startsWith(candidate.slice(0, -2));
|
|
171
|
+
if (candidate.endsWith('/*')) {
|
|
172
|
+
const prefix = candidate.slice(0, -1);
|
|
173
|
+
return normalized.startsWith(prefix) && !normalized.slice(prefix.length).includes('/');
|
|
174
|
+
}
|
|
175
|
+
return normalized === candidate;
|
|
176
|
+
});
|
|
177
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { lstatSync, readdirSync, readFileSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import type { RepositoryIdentity } from '../repository.js';
|
|
5
|
+
import { isVirginProjectRegistrationContent } from '../alpha6/adoption.js';
|
|
6
|
+
import { assertNoSymlinkPathComponents } from '../alpha6/store-sidecars.js';
|
|
7
|
+
|
|
8
|
+
/** Read-only bootstrap admission. Retained or unrecognized state is never bootstrap. */
|
|
9
|
+
export function isVirginRegistrationRoot(projectRoot: string, trustedRoot: string, identity: RepositoryIdentity, packageVersion: string): boolean {
|
|
10
|
+
try {
|
|
11
|
+
const relative = path.relative(path.resolve(trustedRoot), path.resolve(projectRoot));
|
|
12
|
+
if (relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) return false;
|
|
13
|
+
// The trusted state home itself can be absent on first use. Do not create it
|
|
14
|
+
// during observation, and do not confuse that case with invalid retained data.
|
|
15
|
+
try { lstatSync(trustedRoot); } catch (error) {
|
|
16
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return true;
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
19
|
+
assertNoSymlinkPathComponents(projectRoot, { label: 'Bootstrap project root', trustedRoot });
|
|
20
|
+
let root;
|
|
21
|
+
try { root = lstatSync(projectRoot); } catch (error) {
|
|
22
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return true;
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
if (!root.isDirectory() || root.isSymbolicLink()) return false;
|
|
26
|
+
const validFile = (file: string, hash?: string) => {
|
|
27
|
+
const stat = lstatSync(file);
|
|
28
|
+
if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 64 * 1024) return false;
|
|
29
|
+
const bytes = readFileSync(file);
|
|
30
|
+
return (!hash || createHash('sha256').update(bytes).digest('hex') === hash)
|
|
31
|
+
&& isVirginProjectRegistrationContent(bytes.toString('utf8'), identity, packageVersion);
|
|
32
|
+
};
|
|
33
|
+
for (const entry of readdirSync(projectRoot, { withFileTypes: true })) {
|
|
34
|
+
if (entry.isSymbolicLink()) return false;
|
|
35
|
+
if (entry.name === 'adoption-posture.jsonl') {
|
|
36
|
+
if (!validFile(path.join(projectRoot, entry.name))) return false;
|
|
37
|
+
} else if (entry.name === '.versions' && entry.isDirectory()) {
|
|
38
|
+
for (const snapshot of readdirSync(path.join(projectRoot, '.versions'))) {
|
|
39
|
+
const match = /^adoption-posture\.jsonl\.([a-f0-9]{64})$/.exec(snapshot);
|
|
40
|
+
if (!match || !validFile(path.join(projectRoot, '.versions', snapshot), match[1])) return false;
|
|
41
|
+
}
|
|
42
|
+
} else return false;
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
} catch { return false; }
|
|
46
|
+
}
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type WorkflowErrorCode =
|
|
2
|
+
| 'INVALID_ARGUMENT'
|
|
3
|
+
| 'NOT_FOUND'
|
|
4
|
+
| 'STATE_CONFLICT'
|
|
5
|
+
| 'STATE_CORRUPT'
|
|
6
|
+
| 'LOCKED'
|
|
7
|
+
| 'LOCK_TOKEN_INVALID'
|
|
8
|
+
| 'TASK_RECOVERY_REQUIRED'
|
|
9
|
+
| 'TRANSITION_BLOCKED'
|
|
10
|
+
| 'GIT_PRECONDITION_FAILED'
|
|
11
|
+
| 'COMMAND_FAILED'
|
|
12
|
+
| 'CHECK_INFRASTRUCTURE_FAILED';
|
|
13
|
+
|
|
14
|
+
export class WorkflowError extends Error {
|
|
15
|
+
readonly code: WorkflowErrorCode;
|
|
16
|
+
readonly details: Record<string, unknown>;
|
|
17
|
+
|
|
18
|
+
constructor(code: WorkflowErrorCode, message: string, details: Record<string, unknown> = {}) {
|
|
19
|
+
super(message);
|
|
20
|
+
this.name = 'WorkflowError';
|
|
21
|
+
this.code = code;
|
|
22
|
+
this.details = details;
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/fs-utils.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import {
|
|
2
|
+
chmodSync,
|
|
3
|
+
existsSync,
|
|
4
|
+
lstatSync,
|
|
5
|
+
mkdirSync,
|
|
6
|
+
readFileSync,
|
|
7
|
+
renameSync,
|
|
8
|
+
rmSync,
|
|
9
|
+
writeFileSync,
|
|
10
|
+
} from 'node:fs';
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
import { randomUUID } from 'node:crypto';
|
|
13
|
+
import { WorkflowError } from './errors.js';
|
|
14
|
+
|
|
15
|
+
export function ensureDirectory(directory: string): void {
|
|
16
|
+
mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
17
|
+
if (lstatSync(directory).isSymbolicLink()) {
|
|
18
|
+
throw new WorkflowError('STATE_CORRUPT', `State directory must not be a symlink: ${directory}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function readJson<T>(file: string): T {
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(readFileSync(file, 'utf8')) as T;
|
|
25
|
+
} catch (error) {
|
|
26
|
+
throw new WorkflowError('STATE_CORRUPT', `Cannot read JSON state: ${file}`, {
|
|
27
|
+
cause: error instanceof Error ? error.message : String(error),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function writeJsonAtomic(file: string, value: unknown): void {
|
|
33
|
+
const directory = path.dirname(file);
|
|
34
|
+
ensureDirectory(directory);
|
|
35
|
+
if (existsSync(file) && lstatSync(file).isSymbolicLink()) {
|
|
36
|
+
throw new WorkflowError('STATE_CORRUPT', `Refusing to replace state symlink: ${file}`);
|
|
37
|
+
}
|
|
38
|
+
const temporary = path.join(directory, `.${path.basename(file)}.${randomUUID()}.tmp`);
|
|
39
|
+
try {
|
|
40
|
+
writeFileSync(temporary, `${JSON.stringify(value, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 });
|
|
41
|
+
chmodSync(temporary, 0o600);
|
|
42
|
+
renameSync(temporary, file);
|
|
43
|
+
} finally {
|
|
44
|
+
rmSync(temporary, { force: true });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function writeTextAtomic(file: string, content: string): void {
|
|
49
|
+
const directory = path.dirname(file);
|
|
50
|
+
ensureDirectory(directory);
|
|
51
|
+
const temporary = path.join(directory, `.${path.basename(file)}.${randomUUID()}.tmp`);
|
|
52
|
+
try {
|
|
53
|
+
writeFileSync(temporary, content.endsWith('\n') ? content : `${content}\n`, {
|
|
54
|
+
encoding: 'utf8',
|
|
55
|
+
mode: 0o600,
|
|
56
|
+
});
|
|
57
|
+
renameSync(temporary, file);
|
|
58
|
+
} finally {
|
|
59
|
+
rmSync(temporary, { force: true });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { PROTOCOL_VERSION, STATE_SCHEMA_VERSION } from './contracts.js';
|
|
2
|
+
import { PACKAGE_NAME, PACKAGE_VERSION } from './version.js';
|
|
3
|
+
|
|
4
|
+
export interface GatewayHandshake {
|
|
5
|
+
packageName: typeof PACKAGE_NAME;
|
|
6
|
+
packageVersion: typeof PACKAGE_VERSION;
|
|
7
|
+
protocolVersion: typeof PROTOCOL_VERSION;
|
|
8
|
+
stateSchemaVersion: typeof STATE_SCHEMA_VERSION;
|
|
9
|
+
capabilities: string[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function gatewayHandshake(): GatewayHandshake {
|
|
13
|
+
return {
|
|
14
|
+
packageName: PACKAGE_NAME,
|
|
15
|
+
packageVersion: PACKAGE_VERSION,
|
|
16
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
17
|
+
stateSchemaVersion: STATE_SCHEMA_VERSION,
|
|
18
|
+
capabilities: workflowCapabilities(),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function workflowCapabilities(): string[] {
|
|
23
|
+
return [
|
|
24
|
+
'project-memory-v1',
|
|
25
|
+
'graph-binding-v1',
|
|
26
|
+
'local-state-v1',
|
|
27
|
+
'milestone-lifecycle-v1',
|
|
28
|
+
'milestone-human-final-gate-v1',
|
|
29
|
+
'delegated-approval-v1',
|
|
30
|
+
'task-knowledge-rebind-v1',
|
|
31
|
+
'task-context-refresh-v1',
|
|
32
|
+
'corrective-plan-audit-v1',
|
|
33
|
+
'safe-update-preflight-v1',
|
|
34
|
+
'bounded-dependency-provenance-recovery-v1',
|
|
35
|
+
'task-local-dependency-provenance-recovery-v1',
|
|
36
|
+
'root-cause-corrective-replan-dirty-carryover-v1',
|
|
37
|
+
'stop-override-context-rebind-v1',
|
|
38
|
+
'stop-override-context-rebind-chain-v1',
|
|
39
|
+
'stop-override-post-audit-dependency-revision-v1',
|
|
40
|
+
'retained-reviewed-history-recovery-v1',
|
|
41
|
+
'historical-step-provenance-recovery-v1',
|
|
42
|
+
'milestone-progress-projection-v1',
|
|
43
|
+
'bounded-plan-integrity-recovery-v1',
|
|
44
|
+
'check-support-scope-augmentation-v1',
|
|
45
|
+
'historical-check-support-scope-adoption-v1',
|
|
46
|
+
'historical-check-support-dirty-carryover-v1',
|
|
47
|
+
'downstream-proof-predecessor-recovery-v1',
|
|
48
|
+
'active-downstream-proof-dependency-recovery-v1',
|
|
49
|
+
'task-mechanical-feasibility-v1',
|
|
50
|
+
'task-human-gate-lease-release-v1',
|
|
51
|
+
'strict-reviewer-v1',
|
|
52
|
+
'legacy-snapshot-v1',
|
|
53
|
+
'plan-risk-audit-sidecar-v1',
|
|
54
|
+
'step-strict-review-sidecar-v1',
|
|
55
|
+
'step-remediation-circuit-breaker-sidecar-v1',
|
|
56
|
+
'milestone-scope-change-sidecar-v1',
|
|
57
|
+
'milestone-membership-integrity-v1',
|
|
58
|
+
'milestone-task-dependency-dag-v1',
|
|
59
|
+
'milestone-initial-plan-transaction-v1',
|
|
60
|
+
'task-c1-handoff-sidecar-v1',
|
|
61
|
+
'semantic-plan-risk-audit-v2',
|
|
62
|
+
'guarded-remediation-continuation-v1',
|
|
63
|
+
'cause-bound-rolling-refinement-v1',
|
|
64
|
+
'failed-step-continuation-transaction-v1',
|
|
65
|
+
'host-safe-credential-reference-v1',
|
|
66
|
+
'structural-production-edge-contract-v1',
|
|
67
|
+
'structural-production-edge-authority-v1',
|
|
68
|
+
'observed-route-matrix-v2',
|
|
69
|
+
'compact-status-v1',
|
|
70
|
+
'reviewer-runtime-preflight-v1',
|
|
71
|
+
'explicit-review-mode-v1',
|
|
72
|
+
'app-owned-operational-preflight-v1',
|
|
73
|
+
'milestone-reverse-membership-integrity-v1',
|
|
74
|
+
'task-c1-handoff-bundle-v2',
|
|
75
|
+
'alpha6-adoption-posture-v1',
|
|
76
|
+
'milestone-initial-assembly-v1',
|
|
77
|
+
'milestone-initial-assembly-navigation-v2',
|
|
78
|
+
'milestone-autonomy-contract-v1',
|
|
79
|
+
'milestone-autonomy-content-refresh-v1',
|
|
80
|
+
'milestone-autonomous-membership-evolution-v1',
|
|
81
|
+
'audited-remediation-topology-v1',
|
|
82
|
+
'audited-remediation-dependency-knowledge-refresh-v1',
|
|
83
|
+
'corrective-derived-task-authority-v1',
|
|
84
|
+
'task-c1-derived-worker-actor-v1',
|
|
85
|
+
'guarded-corrective-auditor-routing-v1',
|
|
86
|
+
'corrective-decision-context-recovery-v1',
|
|
87
|
+
'plan-proof-obligations-v1',
|
|
88
|
+
'structural-task-replacement-disabled-v1',
|
|
89
|
+
'project-composite-transaction-journal-v1',
|
|
90
|
+
'corrective-yield-journal-v1',
|
|
91
|
+
'corrective-replan-journal-v1',
|
|
92
|
+
'corrective-replan-human-gate-v1',
|
|
93
|
+
'corrective-replan-protocol-v2',
|
|
94
|
+
];
|
|
95
|
+
}
|