{"version":3,"file":"requirement-ledger.d.ts","sourceRoot":"","sources":["../../../src/core/long-horizon/requirement-ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAWH,OAAO,KAAK,EACX,4BAA4B,EAE5B,wBAAwB,EACxB,MAAM,sBAAsB,CAAC;AAQ9B,OAAO,KAAK,EACX,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EAEf,mBAAmB,EAEnB,0BAA0B,EAC1B,iBAAiB,EACjB,MAAM,YAAY,CAAC;AAMpB,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,iBAAiB,GAAG,eAAe,CAAC,mBAAmB,CAAC,CAwC7G;AAuQD;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAChD,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,mBAAmB,GACzB,0BAA0B,CA6B5B;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CACxC,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,mBAAmB,EAC3B,iBAAiB,EAAE,wBAAwB,GACzC,eAAe,CAAC,OAAO,CAAC,CA4Y1B;AA6KD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IACnD,WAAW,EAAE,OAAO,YAAY,EAAE,kBAAkB,CAAC;IACrD,eAAe,EAAE,oBAAoB,EAAE,CAAC;IACxC,wBAAwB,CAAC,EAAE,MAAM,CAAC;CAClC,GAAG,eAAe,CAAC,OAAO,CAAC,CA4D3B;AAoGD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,+BAA+B,CAC9C,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,mBAAmB,EAC3B,iBAAiB,EAAE,wBAAwB,GACzC,OAAO,YAAY,EAAE,mCAAmC,CAuE1D;AAMD,wBAAgB,iBAAiB,CAChC,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,qBAAqB,EAC9B,OAAO,CAAC,EAAE,4BAA4B,EACtC,iBAAiB,CAAC,EAAE,wBAAwB,GAC1C,eAAe,CAAC,mBAAmB,CAAC,CA6FtC;AAMD,wBAAgB,0BAA0B,CACzC,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE,4BAA4B,EACtC,iBAAiB,CAAC,EAAE,wBAAwB,GAC1C,eAAe,CAAC,mBAAmB,CAAC,CAiMtC","sourcesContent":["/**\n * Requirement Ledger v1 — core operations.\n *\n * Pure, filesystem-independent, provider-neutral ledger operations.\n * All functions are immutable — they return new ledger instances.\n *\n * Mutation Model:\n *   - Every accepted mutation (evidence or transition) increments revision by 1.\n *   - Evidence gets addedAtRevision = ledger.revision + 1.\n *   - Transitions require an explicit, caller-supplied transitionId.\n *   - Global mutation sequence: evidence and transition revisions interleave.\n *\n * Trust Model (LH-1 hardened):\n *   - Authorization is derived from TrustedLedgerMutationContext, not payload fields.\n *   - The default untrusted context (agent, no capabilities) can only record claims\n *     and perform non-privileged workflow transitions.\n *   - SATISFIED requires transition:satisfy capability.\n *   - Runtime NOT_APPLICABLE requires transition:not-applicable capability.\n *   - Authoritative evidence requires matching evidence capability.\n *   - Evidence freshness after regression enforced.\n *\n * Validation Model (LH-1 hardened, principal/source fixes applied):\n *   - Authoritative validation requires a TrustedValidationContext.\n *   - Trust checks are ALWAYS enforced when a context is provided.\n *   - Stored verified provenance is verified against the context registry\n *     using exact (principalId + principalKind) tuples.\n *   - Source verification requires explicit trusted evidence-source grants.\n *   - Contract evidence policy is re-evaluated during replay.\n *   - Criterion evidence requirements are re-evaluated during replay.\n *   - Missing required sources fail closed.\n *   - Separate structural inspection is available for untrusted callers.\n */\n\nimport { computeMissionContractDigest } from \"./contract-digest.js\";\nimport type { RequirementEvaluationStatus } from \"./domain-types.js\";\nimport { validateMissionContract } from \"./mission-contract-schema.js\";\nimport {\n\tauthorizeTransition,\n\tcheckEvidenceFreshnessAfterRegression,\n\tisSatisfactionAuthorized,\n\tvalidateTransition,\n} from \"./transition-policy.js\";\nimport type {\n\tTrustedLedgerMutationContext,\n\tTrustedPrincipalKind,\n\tTrustedValidationContext,\n} from \"./trusted-context.js\";\nimport {\n\t_getBoundContractDigest,\n\tderiveEffectiveAuthority,\n\tgetUntrustedContext,\n\tisSourceRequiredForEvidence,\n\tisTrustedValidationContext,\n} from \"./trusted-context.js\";\nimport type {\n\tLedgerEvidenceRecord,\n\tLedgerEvidenceRequest,\n\tMissionContractV1,\n\tOperationResult,\n\tRequirementLedgerEntry,\n\tRequirementLedgerV1,\n\tRequirementTransition,\n\tStructuralLedgerInspection,\n\tTransitionRequest,\n} from \"./types.js\";\n\n// =============================================================================\n// Initialize ledger from contract\n// =============================================================================\n\nexport function initializeRequirementLedger(contract: MissionContractV1): OperationResult<RequirementLedgerV1> {\n\tconst validation = validateMissionContract(contract);\n\tif (!validation.valid) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: `Invalid contract: ${validation.errors.map((e) => e.message).join(\"; \")}`,\n\t\t\tcode: \"INVALID_CONTRACT\",\n\t\t};\n\t}\n\n\tconst digest = computeMissionContractDigest(contract);\n\n\tconst entries: RequirementLedgerEntry[] = contract.requirements.map((req) => {\n\t\tconst initialNotApplicable = req.initialApplicability === \"NOT_APPLICABLE\";\n\t\tconst status: RequirementEvaluationStatus = initialNotApplicable ? \"NOT_APPLICABLE\" : \"UNASSESSED\";\n\n\t\treturn {\n\t\t\trequirementId: req.id,\n\t\t\tstatus,\n\t\t\tworkstreamId: req.workstreamId,\n\t\t\tinitialNotApplicable,\n\t\t\tnotApplicableRationale: initialNotApplicable\n\t\t\t\t? (req.rationale ?? \"Declared NOT_APPLICABLE in contract\")\n\t\t\t\t: undefined,\n\t\t};\n\t});\n\n\tconst ledger: RequirementLedgerV1 = {\n\t\tledgerVersion: 1,\n\t\tmissionId: contract.missionId,\n\t\tcontractVersion: contract.contractVersion,\n\t\tcontractRevision: contract.revision,\n\t\tcontractDigest: digest,\n\t\trevision: 0,\n\t\trequirements: entries,\n\t\tevidence: [],\n\t\ttransitions: [],\n\t};\n\n\treturn { ok: true, value: ledger };\n}\n\n// =============================================================================\n// Build global mutation revision sequence for validation\n// =============================================================================\n\ninterface MutationSlot {\n\trevision: number;\n\ttype: \"evidence\" | \"transition\";\n\tid: string;\n}\n\nfunction buildMutationSequence(ledger: RequirementLedgerV1): MutationSlot[] {\n\tconst slots: MutationSlot[] = [];\n\n\tfor (const ev of ledger.evidence) {\n\t\tslots.push({ revision: ev.addedAtRevision, type: \"evidence\", id: ev.id });\n\t}\n\n\tfor (const tx of ledger.transitions) {\n\t\tslots.push({ revision: tx.ledgerRevisionAfter, type: \"transition\", id: tx.id });\n\t}\n\n\tslots.sort((a, b) => a.revision - b.revision);\n\treturn slots;\n}\n\n// =============================================================================\n// Internal structural-only validation (no trust checks)\n// =============================================================================\n\n/**\n * Validate ledger structure only — contract binding, mutation sequence,\n * state reconstruction. Does NOT verify principal provenance, capability\n * grants, or evidence authority. Used by mutation pre-condition checks.\n */\nfunction validateRequirementLedgerStructure(\n\tcontract: MissionContractV1,\n\tledger: RequirementLedgerV1,\n): OperationResult<boolean> {\n\t// Check contract binding\n\tconst digest = computeMissionContractDigest(contract);\n\tif (ledger.contractDigest !== digest) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: `Contract digest mismatch: ledger has ${ledger.contractDigest}, contract computes ${digest}`,\n\t\t\tcode: \"CONTRACT_DIGEST_MISMATCH\",\n\t\t};\n\t}\n\n\tif (ledger.ledgerVersion !== 1) {\n\t\treturn { ok: false, error: \"Ledger version must be 1\", code: \"INVALID_LEDGER\" };\n\t}\n\n\tif (ledger.missionId !== contract.missionId) {\n\t\treturn { ok: false, error: \"Ledger missionId does not match contract\", code: \"INVALID_LEDGER\" };\n\t}\n\n\tif (ledger.contractRevision !== contract.revision) {\n\t\treturn { ok: false, error: \"Ledger contractRevision does not match contract\", code: \"INVALID_LEDGER\" };\n\t}\n\n\t// Every contract requirement must have a ledger entry\n\tconst contractReqs = new Set(contract.requirements.map((r) => r.id));\n\tconst ledgerReqs = new Set(ledger.requirements.map((r) => r.requirementId));\n\n\tfor (const reqId of contractReqs) {\n\t\tif (!ledgerReqs.has(reqId)) {\n\t\t\treturn { ok: false, error: `Ledger missing entry for requirement: ${reqId}`, code: \"INVALID_LEDGER\" };\n\t\t}\n\t}\n\n\tfor (const reqId of ledgerReqs) {\n\t\tif (!contractReqs.has(reqId)) {\n\t\t\treturn { ok: false, error: `Ledger has entry for unknown requirement: ${reqId}`, code: \"INVALID_LEDGER\" };\n\t\t}\n\t}\n\n\tconst reqIdSet = new Set<string>();\n\tfor (const entry of ledger.requirements) {\n\t\tif (reqIdSet.has(entry.requirementId)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Duplicate ledger entry for requirement: ${entry.requirementId}`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\t\treqIdSet.add(entry.requirementId);\n\t}\n\n\tconst evIds = new Set<string>();\n\tfor (const ev of ledger.evidence) {\n\t\tif (evIds.has(ev.id)) {\n\t\t\treturn { ok: false, error: `Duplicate evidence id: ${ev.id}`, code: \"INVALID_LEDGER\" };\n\t\t}\n\t\tevIds.add(ev.id);\n\n\t\tif (!Number.isInteger(ev.addedAtRevision) || ev.addedAtRevision <= 0) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Evidence ${ev.id} has invalid addedAtRevision: ${ev.addedAtRevision}`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\n\t\tif (ev.addedAtRevision > ledger.revision) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Evidence ${ev.id} has addedAtRevision ${ev.addedAtRevision} > ledger.revision ${ledger.revision}`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\n\t\tfor (const reqId of ev.requirementIds) {\n\t\t\tif (!contractReqs.has(reqId)) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Evidence ${ev.id} references unknown requirement: ${reqId}`,\n\t\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\tconst txIds = new Set<string>();\n\tfor (const tx of ledger.transitions) {\n\t\tif (txIds.has(tx.id)) {\n\t\t\treturn { ok: false, error: `Duplicate transition id: ${tx.id}`, code: \"INVALID_LEDGER\" };\n\t\t}\n\t\ttxIds.add(tx.id);\n\n\t\tif (!contractReqs.has(tx.requirementId)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Transition ${tx.id} references unknown requirement: ${tx.requirementId}`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\n\t\tif (tx.ledgerRevisionAfter !== tx.ledgerRevisionBefore + 1) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Transition ${tx.id} has non-sequential revision change from ${tx.ledgerRevisionBefore} to ${tx.ledgerRevisionAfter}`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\n\t\tfor (const evId of tx.evidenceIds) {\n\t\t\tconst ev = ledger.evidence.find((e) => e.id === evId);\n\t\t\tif (!ev) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Transition ${tx.id} references unknown evidence: ${evId}`,\n\t\t\t\t\tcode: \"UNKNOWN_EVIDENCE\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (ev.addedAtRevision >= tx.ledgerRevisionAfter) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Transition ${tx.id} at revision ${tx.ledgerRevisionAfter} references evidence ${evId} added at revision ${ev.addedAtRevision} (evidence must exist before the transition)`,\n\t\t\t\t\tcode: \"INVALID_TRANSITION\",\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\t// Global mutation sequence\n\tconst mutationSeq = buildMutationSequence(ledger);\n\n\tconst seenRevisions = new Set<number>();\n\tfor (const slot of mutationSeq) {\n\t\tif (seenRevisions.has(slot.revision)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Duplicate mutation revision ${slot.revision}: ${slot.type} ${slot.id}`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\t\tseenRevisions.add(slot.revision);\n\t}\n\n\tif (mutationSeq.length > 0) {\n\t\tif (mutationSeq[0].revision !== 1) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `First mutation is at revision ${mutationSeq[0].revision}, expected 1`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\n\t\tfor (let i = 1; i < mutationSeq.length; i++) {\n\t\t\tif (mutationSeq[i].revision !== mutationSeq[i - 1].revision + 1) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Gap in mutation sequence between revision ${mutationSeq[i - 1].revision} and ${mutationSeq[i].revision}`,\n\t\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tconst last = mutationSeq[mutationSeq.length - 1];\n\t\tif (last.revision !== ledger.revision) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Last mutation at revision ${last.revision} but ledger.revision is ${ledger.revision}`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\t}\n\n\tconst totalMutations = ledger.evidence.length + ledger.transitions.length;\n\tif (ledger.revision !== totalMutations) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: `Ledger revision ${ledger.revision} does not match total mutations ${totalMutations} (${ledger.evidence.length} evidence + ${ledger.transitions.length} transitions)`,\n\t\t\tcode: \"INVALID_LEDGER\",\n\t\t};\n\t}\n\n\t// State reconstruction\n\tconst initialStates = new Map<string, RequirementEvaluationStatus>();\n\tfor (const req of contract.requirements) {\n\t\tconst initialNotApplicable = req.initialApplicability === \"NOT_APPLICABLE\";\n\t\tinitialStates.set(req.id, initialNotApplicable ? \"NOT_APPLICABLE\" : \"UNASSESSED\");\n\t}\n\n\tconst reconstructedStates = new Map(initialStates);\n\n\tfor (const slot of mutationSeq) {\n\t\tif (slot.type === \"transition\") {\n\t\t\tconst tx = ledger.transitions.find((t) => t.id === slot.id)!;\n\t\t\tconst currentState = reconstructedStates.get(tx.requirementId);\n\n\t\t\tif (currentState !== tx.fromStatus) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Transition ${tx.id} at revision ${slot.revision} has fromStatus \"${tx.fromStatus}\" but reconstructed state is \"${currentState}\"`,\n\t\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treconstructedStates.set(tx.requirementId, tx.toStatus);\n\t\t}\n\t}\n\n\tfor (const entry of ledger.requirements) {\n\t\tconst reconstructed = reconstructedStates.get(entry.requirementId);\n\t\tif (reconstructed !== entry.status) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Requirement ${entry.requirementId} has snapshot status \"${entry.status}\" but mutation history reconstructs to \"${reconstructed}\"`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\t}\n\n\treturn { ok: true, value: true };\n}\n\n// =============================================================================\n// Untrusted structural inspection — no trust checks, no completionCandidate\n// =============================================================================\n\n/**\n * Inspect a ledger's structural state without any trust verification.\n *\n * This is the untrusted inspection path. It validates structural integrity\n * (contract binding, mutation sequence, state reconstruction) but does NOT\n * verify principal provenance, capability grants, or evidence authority.\n *\n * completionCandidate is always \"unavailable\".\n */\nexport function inspectRequirementLedgerStructure(\n\tcontract: MissionContractV1,\n\tledger: RequirementLedgerV1,\n): StructuralLedgerInspection {\n\tconst validationResult = validateRequirementLedgerStructure(contract, ledger);\n\n\tconst stateCounts: Record<string, number> = {};\n\tlet applicableCount = 0;\n\n\tfor (const entry of ledger.requirements) {\n\t\tif (entry.initialNotApplicable) continue;\n\t\tapplicableCount++;\n\t\tconst s = entry.status;\n\t\tstateCounts[s] = (stateCounts[s] ?? 0) + 1;\n\t}\n\n\tconst blockedRequirements = ledger.requirements.filter((r) => r.status === \"BLOCKED\").map((r) => r.requirementId);\n\tconst failedRequirements = ledger.requirements.filter((r) => r.status === \"FAILED\").map((r) => r.requirementId);\n\n\treturn {\n\t\tmissionId: contract.missionId,\n\t\tcontractDigest: ledger.contractDigest,\n\t\tledgerRevision: ledger.revision,\n\t\ttotalRequirements: contract.requirements.length,\n\t\tapplicableRequirements: applicableCount,\n\t\tstructurallyValid: validationResult.ok,\n\t\tstateCounts,\n\t\tblockedRequirements,\n\t\tfailedRequirements,\n\t\tcompletionCandidate: \"unavailable\",\n\t\ttrustVerified: false,\n\t};\n}\n\n// =============================================================================\n// Authoritative ledger validation — REQUIRES TrustedValidationContext\n// =============================================================================\n\n/**\n * Validate a ledger against its contract with full trust verification.\n *\n * The validationContext is MANDATORY for this function.\n * All trust and freshness checks are always enforced.\n *\n * The context's registry is used to verify:\n *   - Every stored verifiedPrincipalId/verifiedPrincipalKind is known\n *   - Every stored verifiedCapability was actually granted (exact tuple)\n *   - Every evidence source matches a trusted grant\n *   - Contract evidence policy is enforced\n *   - Criterion evidence requirements are enforced\n *   - Stored effectiveAuthority is consistent with verified capability\n */\nexport function validateRequirementLedger(\n\tcontract: MissionContractV1,\n\tledger: RequirementLedgerV1,\n\tvalidationContext: TrustedValidationContext,\n): OperationResult<boolean> {\n\t// === RUNTIME CONTEXT GUARD ===\n\t// TypeScript signatures are NOT a security boundary.\n\t// A plain object, Proxy, JSON-derived object, or Object.assign copy\n\t// must be rejected at runtime, not merely type-checked at compile time.\n\tif (!isTrustedValidationContext(validationContext)) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: \"A genuine TrustedValidationContext is required. This context is not in the trusted registry WeakSet.\",\n\t\t\tcode: \"TRUSTED_VALIDATION_CONTEXT_REQUIRED\",\n\t\t};\n\t}\n\n\t// === CONTRACT-BINDING GUARD ===\n\t// Every genuine TrustedValidationContext is bound to exactly one\n\t// Mission Contract digest. A context minted for Contract A must not\n\t// validate Contract B, even when IDs happen to overlap.\n\tconst contextDigest = _getBoundContractDigest(validationContext);\n\tif (contextDigest !== undefined) {\n\t\tconst contractDigest = computeMissionContractDigest(contract);\n\t\tif (contextDigest !== contractDigest) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `TrustedValidationContext is bound to contract digest ${contextDigest} but the supplied contract computes ${contractDigest}`,\n\t\t\t\tcode: \"TRUSTED_VALIDATION_CONTEXT_CONTRACT_MISMATCH\",\n\t\t\t};\n\t\t}\n\t\t// Also verify ledger contract digest matches\n\t\tif (ledger.contractDigest !== contractDigest) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Ledger contract digest ${ledger.contractDigest} does not match contract digest ${contractDigest}`,\n\t\t\t\tcode: \"CONTRACT_DIGEST_MISMATCH\",\n\t\t\t};\n\t\t}\n\t}\n\n\t// =========================================================================\n\t// Phase 1: Structural checks (always run)\n\t// =========================================================================\n\n\tconst structuralResult = runStructuralChecks(contract, ledger);\n\tif (!structuralResult.ok) {\n\t\treturn structuralResult;\n\t}\n\n\t// =========================================================================\n\t// Phase 2: Trust replay — provenance, policy, and source verification\n\t// =========================================================================\n\n\t// Helper: find contract requirement\n\tconst contractReqs = new Set(contract.requirements.map((r) => r.id));\n\n\t// --- Evidence trust replay ---\n\tconst evIds = new Set<string>();\n\tfor (const ev of ledger.evidence) {\n\t\tif (evIds.has(ev.id)) {\n\t\t\treturn { ok: false, error: `Duplicate evidence id: ${ev.id}`, code: \"INVALID_LEDGER\" };\n\t\t}\n\t\tevIds.add(ev.id);\n\n\t\tfor (const reqId of ev.requirementIds) {\n\t\t\tif (!contractReqs.has(reqId)) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Evidence ${ev.id} references unknown requirement: ${reqId}`,\n\t\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// --- PRINCIPAL VERIFICATION: exact tuple ---\n\t\tif (!validationContext.verifyPrincipal(ev.verifiedPrincipalId, ev.verifiedPrincipalKind)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Evidence ${ev.id}: unknown verified principal ${ev.verifiedPrincipalId}/${ev.verifiedPrincipalKind}`,\n\t\t\t\tcode: \"AUTHORIZATION_FAILED\",\n\t\t\t};\n\t\t}\n\n\t\t// --- CAPABILITY VERIFICATION: exact tuple ---\n\t\tif (ev.effectiveAuthority !== \"agent-claim\" && ev.verifiedCapability) {\n\t\t\tif (\n\t\t\t\t!validationContext.verifyCapability(\n\t\t\t\t\tev.verifiedPrincipalId,\n\t\t\t\t\tev.verifiedPrincipalKind as TrustedPrincipalKind,\n\t\t\t\t\tev.verifiedCapability,\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Evidence ${ev.id}: capability ${ev.verifiedCapability} not granted to principal ${ev.verifiedPrincipalId}/${ev.verifiedPrincipalKind}`,\n\t\t\t\t\tcode: \"AUTHORIZATION_FAILED\",\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Verify effectiveAuthority is consistent with the claimed capability\n\t\t\tconst expectedAuthority = capabilityToAuthoritySimple(ev.verifiedCapability);\n\t\t\tif (expectedAuthority && ev.effectiveAuthority !== expectedAuthority) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Evidence ${ev.id}: effectiveAuthority \"${ev.effectiveAuthority}\" inconsistent with verified capability \"${ev.verifiedCapability}\" (tampered provenance)`,\n\t\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Non-agent-claim evidence requires non-agent verified principal\n\t\tif (ev.effectiveAuthority !== \"agent-claim\" && ev.verifiedPrincipalKind === \"agent\") {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Evidence ${ev.id}: effectiveAuthority ${ev.effectiveAuthority} but verifiedPrincipalKind is agent (tampered provenance)`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\n\t\t// --- SOURCE VERIFICATION ---\n\t\t// Determine if source is required\n\t\tconst sourceRequired = isSourceRequiredForEvidence({\n\t\t\teffectiveAuthority: ev.effectiveAuthority,\n\t\t\tcontractAuthoritativeSources: contract.evidencePolicy.authoritativeSources,\n\t\t});\n\n\t\tif (sourceRequired && (!ev.source || ev.source.trim().length === 0)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Evidence ${ev.id}: authoritative source required but source is empty or missing`,\n\t\t\t\tcode: \"AUTHORITATIVE_SOURCE_REQUIRED\",\n\t\t\t};\n\t\t}\n\n\t\t// Verify source via trusted grant when present\n\t\tif (ev.source && ev.source.trim().length > 0) {\n\t\t\tif (\n\t\t\t\t!validationContext.verifyEvidenceSource({\n\t\t\t\t\tsourceId: ev.source,\n\t\t\t\t\tprincipalId: ev.verifiedPrincipalId,\n\t\t\t\t\tprincipalKind: ev.verifiedPrincipalKind as TrustedPrincipalKind,\n\t\t\t\t\tcapability: ev.verifiedCapability ?? \"evidence:test-result\",\n\t\t\t\t\tevidenceType: ev.type,\n\t\t\t\t\tcollectorClass: ev.reportedCollectorType,\n\t\t\t\t\trequirementIds: ev.requirementIds,\n\t\t\t\t\tcriterionIds: ev.criterionIds,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Evidence ${ev.id}: source \"${ev.source}\" does not match a trusted grant for principal ${ev.verifiedPrincipalId}/${ev.verifiedPrincipalKind}`,\n\t\t\t\t\tcode: \"UNKNOWN_AUTHORITATIVE_SOURCE\",\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// --- CONTRACT EVIDENCE POLICY REPLAY ---\n\t\tconst policyCheck = checkContractEvidencePolicy(contract, ev);\n\t\tif (!policyCheck.ok) {\n\t\t\treturn policyCheck;\n\t\t}\n\n\t\t// --- CRITERION EVIDENCE REQUIREMENT REPLAY ---\n\t\tconst criterionCheck = checkCriterionEvidenceRequirements(contract, ev);\n\t\tif (!criterionCheck.ok) {\n\t\t\treturn criterionCheck;\n\t\t}\n\t}\n\n\t// --- Transition trust replay ---\n\tconst txIds = new Set<string>();\n\tfor (const tx of ledger.transitions) {\n\t\tif (txIds.has(tx.id)) {\n\t\t\treturn { ok: false, error: `Duplicate transition id: ${tx.id}`, code: \"INVALID_LEDGER\" };\n\t\t}\n\t\ttxIds.add(tx.id);\n\n\t\tif (!contractReqs.has(tx.requirementId)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Transition ${tx.id} references unknown requirement: ${tx.requirementId}`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\n\t\tif (tx.ledgerRevisionAfter !== tx.ledgerRevisionBefore + 1) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Transition ${tx.id} has non-sequential revision change from ${tx.ledgerRevisionBefore} to ${tx.ledgerRevisionAfter}`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\n\t\tfor (const evId of tx.evidenceIds) {\n\t\t\tconst ev = ledger.evidence.find((e) => e.id === evId);\n\t\t\tif (!ev) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Transition ${tx.id} references unknown evidence: ${evId}`,\n\t\t\t\t\tcode: \"UNKNOWN_EVIDENCE\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (ev.addedAtRevision >= tx.ledgerRevisionAfter) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Transition ${tx.id} at revision ${tx.ledgerRevisionAfter} references evidence ${evId} added at revision ${ev.addedAtRevision} (evidence must exist before the transition)`,\n\t\t\t\t\tcode: \"INVALID_TRANSITION\",\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// --- PRINCIPAL VERIFICATION: exact tuple ---\n\t\tif (!validationContext.verifyPrincipal(tx.verifiedPrincipalId, tx.verifiedPrincipalKind)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Transition ${tx.id}: unknown verified principal ${tx.verifiedPrincipalId}/${tx.verifiedPrincipalKind}`,\n\t\t\t\tcode: \"AUTHORIZATION_FAILED\",\n\t\t\t};\n\t\t}\n\n\t\t// SATISFIED transitions require non-agent principal\n\t\tif (tx.toStatus === \"SATISFIED\" && tx.verifiedPrincipalKind === \"agent\") {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Transition ${tx.id}: SATISFIED with agent verifiedPrincipalKind (tampered provenance)`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\n\t\t// --- CAPABILITY VERIFICATION: exact tuple ---\n\t\tif (tx.verifiedCapability) {\n\t\t\tif (\n\t\t\t\t!validationContext.verifyCapability(\n\t\t\t\t\ttx.verifiedPrincipalId,\n\t\t\t\t\ttx.verifiedPrincipalKind as TrustedPrincipalKind,\n\t\t\t\t\ttx.verifiedCapability,\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Transition ${tx.id}: capability ${tx.verifiedCapability} not granted to principal ${tx.verifiedPrincipalId}/${tx.verifiedPrincipalKind}`,\n\t\t\t\t\tcode: \"AUTHORIZATION_FAILED\",\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// SATISFIED must have transition:satisfy\n\t\tif (tx.toStatus === \"SATISFIED\" && tx.verifiedCapability !== \"transition:satisfy\") {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Transition ${tx.id}: SATISFIED with verifiedCapability \"${tx.verifiedCapability}\" — expected \"transition:satisfy\" (tampered provenance)`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\n\t\t// Runtime NOT_APPLICABLE must have transition:not-applicable\n\t\tif (tx.toStatus === \"NOT_APPLICABLE\" && tx.fromStatus !== \"UNASSESSED\") {\n\t\t\tif (tx.verifiedCapability !== \"transition:not-applicable\") {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Transition ${tx.id}: runtime NOT_APPLICABLE with verifiedCapability \"${tx.verifiedCapability}\" — expected \"transition:not-applicable\" (tampered provenance)`,\n\t\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// --- CRITERION REPLAY for SATISFIED transitions ---\n\t\tif (tx.toStatus === \"SATISFIED\") {\n\t\t\tconst req = contract.requirements.find((r) => r.id === tx.requirementId);\n\t\t\tif (req) {\n\t\t\t\tfor (const criterion of req.acceptanceCriteria) {\n\t\t\t\t\tconst satCheck = replayCriterionSatisfaction(contract, ledger, tx, criterion, req);\n\t\t\t\t\tif (!satCheck.ok) return satCheck;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// --- Global mutation sequence ---\n\tconst mutationSeq = buildMutationSequence(ledger);\n\n\tconst seenRevisions = new Set<number>();\n\tfor (const slot of mutationSeq) {\n\t\tif (seenRevisions.has(slot.revision)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Duplicate mutation revision ${slot.revision}: ${slot.type} ${slot.id}`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\t\tseenRevisions.add(slot.revision);\n\t}\n\n\tif (mutationSeq.length > 0) {\n\t\tif (mutationSeq[0].revision !== 1) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `First mutation is at revision ${mutationSeq[0].revision}, expected 1`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\n\t\tfor (let i = 1; i < mutationSeq.length; i++) {\n\t\t\tif (mutationSeq[i].revision !== mutationSeq[i - 1].revision + 1) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Gap in mutation sequence between revision ${mutationSeq[i - 1].revision} and ${mutationSeq[i].revision}`,\n\t\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tconst last = mutationSeq[mutationSeq.length - 1];\n\t\tif (last.revision !== ledger.revision) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Last mutation at revision ${last.revision} but ledger.revision is ${ledger.revision}`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\t}\n\n\tconst totalMutations = ledger.evidence.length + ledger.transitions.length;\n\tif (ledger.revision !== totalMutations) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: `Ledger revision ${ledger.revision} does not match total mutations ${totalMutations} (${ledger.evidence.length} evidence + ${ledger.transitions.length} transitions)`,\n\t\t\tcode: \"INVALID_LEDGER\",\n\t\t};\n\t}\n\n\t// --- State reconstruction ---\n\tconst initialStates = new Map<string, RequirementEvaluationStatus>();\n\tfor (const req of contract.requirements) {\n\t\tconst initialNotApplicable = req.initialApplicability === \"NOT_APPLICABLE\";\n\t\tinitialStates.set(req.id, initialNotApplicable ? \"NOT_APPLICABLE\" : \"UNASSESSED\");\n\t}\n\n\tconst reconstructedStates = new Map(initialStates);\n\n\tfor (const slot of mutationSeq) {\n\t\tif (slot.type === \"transition\") {\n\t\t\tconst tx = ledger.transitions.find((t) => t.id === slot.id)!;\n\t\t\tconst currentState = reconstructedStates.get(tx.requirementId);\n\n\t\t\tif (currentState !== tx.fromStatus) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Transition ${tx.id} at revision ${slot.revision} has fromStatus \"${tx.fromStatus}\" but reconstructed state is \"${currentState}\"`,\n\t\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treconstructedStates.set(tx.requirementId, tx.toStatus);\n\t\t}\n\t}\n\n\tfor (const entry of ledger.requirements) {\n\t\tconst reconstructed = reconstructedStates.get(entry.requirementId);\n\t\tif (reconstructed !== entry.status) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Requirement ${entry.requirementId} has snapshot status \"${entry.status}\" but mutation history reconstructs to \"${reconstructed}\"`,\n\t\t\t\tcode: \"INVALID_LEDGER\",\n\t\t\t};\n\t\t}\n\t}\n\n\t// --- Evidence freshness after regression (always enforced) ---\n\tfor (const entry of ledger.requirements) {\n\t\tif (entry.status !== \"SATISFIED\") continue;\n\t\tif (entry.latestRegressionRevision === undefined) continue;\n\n\t\tconst lastSatTx = [...ledger.transitions]\n\t\t\t.reverse()\n\t\t\t.find((t) => t.requirementId === entry.requirementId && t.toStatus === \"SATISFIED\");\n\n\t\tif (!lastSatTx) continue;\n\n\t\tconst requirement = contract.requirements.find((r) => r.id === entry.requirementId);\n\t\tif (!requirement) continue;\n\n\t\tfor (const criterion of requirement.acceptanceCriteria) {\n\t\t\tconst hasFresh = lastSatTx.evidenceIds.some((evId) => {\n\t\t\t\tconst ev = ledger.evidence.find((e) => e.id === evId);\n\t\t\t\treturn ev?.criterionIds.includes(criterion.id) && ev.addedAtRevision > entry.latestRegressionRevision!;\n\t\t\t});\n\n\t\t\tif (!hasFresh) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Requirement ${entry.requirementId}: criterion \"${criterion.id}\" satisfied with stale evidence after regression at revision ${entry.latestRegressionRevision}`,\n\t\t\t\t\tcode: \"STALE_EVIDENCE_AFTER_REGRESSION\",\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { ok: true, value: true };\n}\n\n// =============================================================================\n// Structural checks subset (shared path) — returns on first error\n// =============================================================================\n\nfunction runStructuralChecks(contract: MissionContractV1, ledger: RequirementLedgerV1): OperationResult<boolean> {\n\tconst digest = computeMissionContractDigest(contract);\n\tif (ledger.contractDigest !== digest) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: `Contract digest mismatch: ledger has ${ledger.contractDigest}, contract computes ${digest}`,\n\t\t\tcode: \"CONTRACT_DIGEST_MISMATCH\",\n\t\t};\n\t}\n\n\tif (ledger.ledgerVersion !== 1) {\n\t\treturn { ok: false, error: \"Ledger version must be 1\", code: \"INVALID_LEDGER\" };\n\t}\n\n\tif (ledger.missionId !== contract.missionId) {\n\t\treturn { ok: false, error: \"Ledger missionId does not match contract\", code: \"INVALID_LEDGER\" };\n\t}\n\n\tif (ledger.contractRevision !== contract.revision) {\n\t\treturn { ok: false, error: \"Ledger contractRevision does not match contract\", code: \"INVALID_LEDGER\" };\n\t}\n\n\tconst contractReqs = new Set(contract.requirements.map((r) => r.id));\n\tconst ledgerReqs = new Set(ledger.requirements.map((r) => r.requirementId));\n\n\tfor (const reqId of contractReqs) {\n\t\tif (!ledgerReqs.has(reqId)) {\n\t\t\treturn { ok: false, error: `Ledger missing entry for requirement: ${reqId}`, code: \"INVALID_LEDGER\" };\n\t\t}\n\t}\n\n\tfor (const reqId of ledgerReqs) {\n\t\tif (!contractReqs.has(reqId)) {\n\t\t\treturn { ok: false, error: `Ledger has entry for unknown requirement: ${reqId}`, code: \"INVALID_LEDGER\" };\n\t\t}\n\t}\n\n\treturn { ok: true, value: true };\n}\n\n// =============================================================================\n// Contract evidence policy check during replay\n// =============================================================================\n\nfunction checkContractEvidencePolicy(contract: MissionContractV1, ev: LedgerEvidenceRecord): OperationResult<boolean> {\n\t// Agent claims are never authoritative — policy doesn't apply\n\tif (ev.effectiveAuthority === \"agent-claim\") {\n\t\treturn { ok: true, value: true };\n\t}\n\n\tconst policy = contract.evidencePolicy;\n\n\t// When contract declares authoritative sources, evidence must match\n\tif (policy.authoritativeSources && policy.authoritativeSources.length > 0) {\n\t\tif (!policy.authoritativeSources.includes(ev.effectiveAuthority)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Evidence ${ev.id}: effectiveAuthority \"${ev.effectiveAuthority}\" not in contract authoritativeSources [${policy.authoritativeSources.join(\", \")}]`,\n\t\t\t\tcode: \"CONTRACT_EVIDENCE_POLICY_VIOLATION\",\n\t\t\t};\n\t\t}\n\t}\n\n\t// Check evidence policy rules\n\tif (policy.rules) {\n\t\tfor (const rule of policy.rules) {\n\t\t\t// Rule applies if evidence type matches\n\t\t\tif (rule.allowedTypes && !rule.allowedTypes.includes(ev.type)) {\n\t\t\t\tcontinue; // Rule doesn't apply to this type\n\t\t\t}\n\n\t\t\t// Check minAuthority\n\t\t\tif (rule.minAuthority) {\n\t\t\t\tconst authRank = authorityRank(ev.effectiveAuthority);\n\t\t\t\tconst requiredRank = authorityRank(rule.minAuthority);\n\t\t\t\tif (authRank < requiredRank) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tok: false,\n\t\t\t\t\t\terror: `Evidence ${ev.id}: authority \"${ev.effectiveAuthority}\" below rule \"${rule.id}\" minAuthority \"${rule.minAuthority}\"`,\n\t\t\t\t\t\tcode: \"CONTRACT_EVIDENCE_POLICY_VIOLATION\",\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check requiredCollectorClass\n\t\t\tif (rule.requiredCollectorClass && ev.reportedCollectorType !== rule.requiredCollectorClass) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Evidence ${ev.id}: collector \"${ev.reportedCollectorType}\" does not match rule \"${rule.id}\" requiredCollectorClass \"${rule.requiredCollectorClass}\"`,\n\t\t\t\t\tcode: \"CONTRACT_EVIDENCE_POLICY_VIOLATION\",\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { ok: true, value: true };\n}\n\n// =============================================================================\n// Criterion evidence requirement replay\n// =============================================================================\n\nfunction checkCriterionEvidenceRequirements(\n\tcontract: MissionContractV1,\n\tev: LedgerEvidenceRecord,\n): OperationResult<boolean> {\n\tfor (const reqId of ev.requirementIds) {\n\t\tconst requirement = contract.requirements.find((r) => r.id === reqId);\n\t\tif (!requirement) continue;\n\n\t\tfor (const critId of ev.criterionIds) {\n\t\t\tconst criterion = requirement.acceptanceCriteria.find((c) => c.id === critId);\n\t\t\tif (!criterion) continue;\n\n\t\t\tfor (const evReq of criterion.requiredEvidence) {\n\t\t\t\t// Check allowedTypes\n\t\t\t\tif (evReq.allowedTypes && evReq.allowedTypes.length > 0) {\n\t\t\t\t\tif (!evReq.allowedTypes.includes(ev.type)) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tok: false,\n\t\t\t\t\t\t\terror: `Evidence ${ev.id}: type \"${ev.type}\" not in criterion \"${critId}\" allowedTypes [${evReq.allowedTypes.join(\", \")}]`,\n\t\t\t\t\t\t\tcode: \"CRITERION_EVIDENCE_POLICY_VIOLATION\",\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Check minAuthority\n\t\t\t\tif (evReq.minAuthority && evReq.minAuthority !== \"agent-claim\") {\n\t\t\t\t\tconst authRank1 = authorityRank(ev.effectiveAuthority);\n\t\t\t\t\tconst requiredRank1 = authorityRank(evReq.minAuthority);\n\t\t\t\t\tif (authRank1 < requiredRank1) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tok: false,\n\t\t\t\t\t\t\terror: `Evidence ${ev.id}: authority \"${ev.effectiveAuthority}\" below criterion \"${critId}\" minAuthority \"${evReq.minAuthority}\"`,\n\t\t\t\t\t\t\tcode: \"CRITERION_EVIDENCE_POLICY_VIOLATION\",\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Check requiredCollectorClass\n\t\t\t\tif (evReq.requiredCollectorClass && ev.reportedCollectorType !== evReq.requiredCollectorClass) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tok: false,\n\t\t\t\t\t\terror: `Evidence ${ev.id}: collector \"${ev.reportedCollectorType}\" does not match criterion \"${critId}\" requiredCollectorClass \"${evReq.requiredCollectorClass}\"`,\n\t\t\t\t\t\tcode: \"CRITERION_EVIDENCE_POLICY_VIOLATION\",\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Check minPassingStatus\n\t\t\t\tif (evReq.minPassingStatus === \"pass\" && ev.status !== \"pass\") {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tok: false,\n\t\t\t\t\t\terror: `Evidence ${ev.id}: status \"${ev.status}\" does not meet criterion \"${critId}\" minPassingStatus \"pass\"`,\n\t\t\t\t\t\tcode: \"CRITERION_EVIDENCE_POLICY_VIOLATION\",\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { ok: true, value: true };\n}\n\n// =============================================================================\n// Shared SATISFIED Evaluator — canonical single source of truth\n// =============================================================================\n\n/**\n * Evaluate whether a set of evidence records satisfies every acceptance\n * criterion for a requirement.\n *\n * This is the ONE canonical evaluator used by:\n *   - Mutation-time authorization (through isSatisfactionAuthorized)\n *   - Historical authoritative replay (replayCriterionSatisfaction)\n *   - Completion assessment\n *\n * It evaluates only the evidence explicitly provided — it does NOT\n * consult the full ledger. The caller is responsible for resolving\n * the canonical evidence set (transition.evidenceIds) into records\n * before calling this function.\n *\n * @returns An OperationResult<boolean> with specific typed failures\n *          for missing criteria, missing evidence rules, stale evidence,\n *          and policy violations.\n */\nexport function evaluateSatisfiedTransition(params: {\n\trequirement: import(\"./types.js\").MissionRequirement;\n\tevidenceRecords: LedgerEvidenceRecord[];\n\tlatestRegressionRevision?: number;\n}): OperationResult<boolean> {\n\tconst { requirement, evidenceRecords, latestRegressionRevision } = params;\n\n\tif (requirement.acceptanceCriteria.length === 0) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: `Requirement ${requirement.id} has no acceptance criteria`,\n\t\t\tcode: \"MISSING_ACCEPTANCE_CRITERIA\",\n\t\t};\n\t}\n\n\tfor (const criterion of requirement.acceptanceCriteria) {\n\t\tconst matching = evidenceRecords.filter(\n\t\t\t(ev) => ev.criterionIds.includes(criterion.id) && ev.requirementIds.includes(requirement.id),\n\t\t);\n\n\t\tif (matching.length === 0) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Criterion \"${criterion.id}\": no evidence in the canonical evidence set`,\n\t\t\t\tcode: \"UNKNOWN_CRITERION\",\n\t\t\t};\n\t\t}\n\n\t\t// Freshness check: if there was a regression, at least one evidence\n\t\t// for this criterion must have been added after regression\n\t\tif (latestRegressionRevision !== undefined) {\n\t\t\tconst hasFresh = matching.some((ev) => ev.addedAtRevision > latestRegressionRevision);\n\t\t\tif (!hasFresh) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Criterion \"${criterion.id}\": no evidence added after regression at revision ${latestRegressionRevision}`,\n\t\t\t\t\tcode: \"STALE_EVIDENCE_AFTER_REGRESSION\",\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Find at least one evidence record that meets ALL required-evidence constraints\n\t\tlet satisfied = false;\n\t\tfor (const evRecord of matching) {\n\t\t\tif (evRecord.status !== \"pass\") continue;\n\t\t\tif (evRecord.effectiveAuthority === \"agent-claim\") continue;\n\n\t\t\tconst meetsAll = criterion.requiredEvidence.every((req) => evidenceMeetsRequirementReplay(evRecord, req));\n\t\t\tif (meetsAll) {\n\t\t\t\tsatisfied = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!satisfied) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Criterion \"${criterion.id}\": no evidence satisfies all required evidence constraints`,\n\t\t\t\tcode: \"CRITERION_EVIDENCE_POLICY_VIOLATION\",\n\t\t\t};\n\t\t}\n\t}\n\n\treturn { ok: true, value: true };\n}\n\n/**\n * Check if a single evidence record meets a single EvidenceRequirement\n * during replay evaluation.\n */\nfunction evidenceMeetsRequirementReplay(\n\tevRecord: LedgerEvidenceRecord,\n\trequirement: import(\"./types.js\").EvidenceRequirement,\n): boolean {\n\tif (evRecord.status !== \"pass\") return false;\n\tif (evRecord.effectiveAuthority === \"agent-claim\") return false;\n\n\tif (requirement.allowedTypes && requirement.allowedTypes.length > 0) {\n\t\tif (!requirement.allowedTypes.includes(evRecord.type)) return false;\n\t}\n\n\tif (requirement.minAuthority) {\n\t\tif (!authorityMeetsMinimumReplay(evRecord.effectiveAuthority, requirement.minAuthority)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif (requirement.requiredCollectorClass) {\n\t\tif (evRecord.verifiedPrincipalKind !== requirement.requiredCollectorClass) return false;\n\t}\n\n\tif (requirement.minPassingStatus === \"pass\" && evRecord.status !== \"pass\") return false;\n\n\treturn true;\n}\n\nfunction authorityMeetsMinimumReplay(actual: string, minimum: string): boolean {\n\tconst ranks: Record<string, number> = {\n\t\t\"agent-claim\": 0,\n\t\t\"repository-observation\": 1,\n\t\t\"command-result\": 2,\n\t\t\"test-result\": 3,\n\t\t\"runtime-observation\": 4,\n\t\t\"operator-confirmation\": 5,\n\t\t\"trusted-collector\": 6,\n\t};\n\tconst actualRank = ranks[actual] ?? -1;\n\tconst minRank = ranks[minimum] ?? -1;\n\treturn actualRank >= minRank;\n}\n\n// =============================================================================\n// Criterion satisfaction replay for SATISFIED transitions\n// =============================================================================\n\nfunction replayCriterionSatisfaction(\n\t_contract: MissionContractV1,\n\tledger: RequirementLedgerV1,\n\ttx: RequirementTransition,\n\t_criterion: import(\"./types.js\").AcceptanceCriterion,\n\trequirement: import(\"./types.js\").MissionRequirement,\n): OperationResult<boolean> {\n\t// Resolve evidence from the transition's canonical evidence set\n\tconst evidenceRecords: LedgerEvidenceRecord[] = [];\n\tfor (const evId of tx.evidenceIds) {\n\t\tconst ev = ledger.evidence.find((e) => e.id === evId);\n\t\tif (ev) evidenceRecords.push(ev);\n\t}\n\n\treturn evaluateSatisfiedTransition({\n\t\trequirement,\n\t\tevidenceRecords,\n\t});\n}\n\n// =============================================================================\n// Authority ranking for minAuthority comparison\n// =============================================================================\n\nfunction authorityRank(authority: string): number {\n\tswitch (authority) {\n\t\tcase \"agent-claim\":\n\t\t\treturn 0;\n\t\tcase \"repository-observation\":\n\t\t\treturn 1;\n\t\tcase \"command-result\":\n\t\t\treturn 2;\n\t\tcase \"test-result\":\n\t\t\treturn 3;\n\t\tcase \"runtime-observation\":\n\t\t\treturn 4;\n\t\tcase \"operator-confirmation\":\n\t\t\treturn 5;\n\t\tcase \"trusted-collector\":\n\t\t\treturn 6;\n\t\tdefault:\n\t\t\treturn 0;\n\t}\n}\n\n// =============================================================================\n// Authoritative ledger validation — returns rich result type\n// =============================================================================\n\n/**\n * Authoritative validation returning a typed result with truthful semantics.\n *\n * Unlike validateRequirementLedger which returns a generic OperationResult,\n * this returns an AuthoritativeLedgerValidationResult whose types prove\n * that trust verification was attempted against a genuine registry.\n *\n * Fields:\n *   - structuralValidation: \"passed\" or { status: \"failed\", code, message }\n *   - provenanceValidation: \"passed\", { status: \"failed\", code, message }, or \"not-reached\"\n *\n * Structural failure cannot report structural validity true.\n * Provenance failure cannot report provenance validity true.\n * Provenance not executed is distinguishable from provenance passed.\n */\nexport function validateRequirementLedgerStrict(\n\tcontract: MissionContractV1,\n\tledger: RequirementLedgerV1,\n\tvalidationContext: TrustedValidationContext,\n): import(\"./types.js\").AuthoritativeLedgerValidationResult {\n\tconst result = validateRequirementLedger(contract, ledger, validationContext);\n\n\tif (!result.ok) {\n\t\tconst code = result.code ?? \"INTERNAL_ERROR\";\n\t\tconst message = result.error ?? \"Unknown error\";\n\n\t\t// Distinguish structural from provenance/capability/source failures\n\t\tconst isStructural =\n\t\t\tcode === \"CONTRACT_DIGEST_MISMATCH\" ||\n\t\t\tcode === \"INVALID_LEDGER\" ||\n\t\t\tcode === \"INVALID_CONTRACT\" ||\n\t\t\tcode === \"INVALID_TRANSITION\" ||\n\t\t\tcode === \"STALE_REVISION\" ||\n\t\t\tcode === \"STALE_EVIDENCE_AFTER_REGRESSION\" ||\n\t\t\tcode === \"UNKNOWN_REQUIREMENT\" ||\n\t\t\tcode === \"UNKNOWN_CRITERION\" ||\n\t\t\tcode === \"UNKNOWN_EVIDENCE\" ||\n\t\t\tcode === \"UNKNOWN_SEMANTIC_FIELD\" ||\n\t\t\tcode === \"DUPLICATE_EVIDENCE_ID\" ||\n\t\t\tcode === \"DUPLICATE_TRANSITION_ID\" ||\n\t\t\tcode === \"INTERNAL_REPLAY_INVARIANT_VIOLATION\" ||\n\t\t\tcode === \"INTERNAL_ERROR\";\n\n\t\tconst isProvenance =\n\t\t\tcode === \"AUTHORIZATION_FAILED\" ||\n\t\t\tcode === \"UNKNOWN_AUTHORITATIVE_SOURCE\" ||\n\t\t\tcode === \"AUTHORITATIVE_SOURCE_REQUIRED\" ||\n\t\t\tcode === \"SOURCE_PRINCIPAL_MISMATCH\" ||\n\t\t\tcode === \"SOURCE_EVIDENCE_CAPABILITY_MISMATCH\" ||\n\t\t\tcode === \"SOURCE_COLLECTOR_MISMATCH\" ||\n\t\t\tcode === \"SOURCE_EVIDENCE_TYPE_MISMATCH\" ||\n\t\t\tcode === \"SOURCE_REQUIREMENT_MISMATCH\" ||\n\t\t\tcode === \"SOURCE_CRITERION_MISMATCH\" ||\n\t\t\tcode === \"CONTRACT_EVIDENCE_POLICY_VIOLATION\" ||\n\t\t\tcode === \"CRITERION_EVIDENCE_POLICY_VIOLATION\" ||\n\t\t\tcode === \"TRUSTED_VALIDATION_CONTEXT_REQUIRED\";\n\n\t\tif (isStructural) {\n\t\t\treturn {\n\t\t\t\tvalid: false,\n\t\t\t\ttrustVerified: true,\n\t\t\t\tstructuralValidation: { status: \"failed\", code, message },\n\t\t\t\tprovenanceValidation: { status: \"not-reached\" },\n\t\t\t};\n\t\t}\n\n\t\tif (isProvenance) {\n\t\t\treturn {\n\t\t\t\tvalid: false,\n\t\t\t\ttrustVerified: true,\n\t\t\t\tstructuralValidation: { status: \"passed\" },\n\t\t\t\tprovenanceValidation: { status: \"failed\", code, message },\n\t\t\t};\n\t\t}\n\n\t\t// Unknown codes: both failed (conservative)\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\ttrustVerified: true,\n\t\t\tstructuralValidation: { status: \"failed\", code, message },\n\t\t\tprovenanceValidation: { status: \"not-reached\" },\n\t\t};\n\t}\n\n\treturn {\n\t\tvalid: true,\n\t\ttrustVerified: true,\n\t\tstructuralValidation: { status: \"passed\" },\n\t\tprovenanceValidation: { status: \"passed\" },\n\t};\n}\n\n// =============================================================================\n// Add evidence to ledger — increments revision\n// =============================================================================\n\nexport function addLedgerEvidence(\n\tcontract: MissionContractV1,\n\tledger: RequirementLedgerV1,\n\trequest: LedgerEvidenceRequest,\n\tcontext?: TrustedLedgerMutationContext,\n\tvalidationContext?: TrustedValidationContext,\n): OperationResult<RequirementLedgerV1> {\n\tconst ctx = context ?? getUntrustedContext();\n\n\tif (request.expectedRevision !== ledger.revision) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: `Stale revision: expected ${request.expectedRevision}, current ${ledger.revision}`,\n\t\t\tcode: \"STALE_REVISION\",\n\t\t};\n\t}\n\n\t// Validate ledger (structural only — pre-condition for evidence)\n\tconst valid = validateRequirementLedgerStructure(contract, ledger);\n\tif (!valid.ok) {\n\t\treturn { ok: false, error: valid.error ?? \"Invalid ledger\", code: valid.code ?? \"INVALID_LEDGER\" };\n\t}\n\n\tif (ledger.evidence.some((e) => e.id === request.evidence.id)) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: `Duplicate evidence id: ${request.evidence.id}`,\n\t\t\tcode: \"DUPLICATE_EVIDENCE_ID\",\n\t\t};\n\t}\n\n\tconst effectiveAuthority = deriveEffectiveAuthority(ctx, request.evidence.type);\n\n\tconst contractReqs = new Set(contract.requirements.map((r) => r.id));\n\tfor (const reqId of request.evidence.requirementIds) {\n\t\tif (!contractReqs.has(reqId)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Evidence references unknown requirement: ${reqId}`,\n\t\t\t\tcode: \"UNKNOWN_REQUIREMENT\",\n\t\t\t};\n\t\t}\n\t}\n\n\tconst newRevision = ledger.revision + 1;\n\n\tconst evidenceRecord: LedgerEvidenceRecord = {\n\t\tid: request.evidence.id,\n\t\ttype: request.evidence.type,\n\t\trequirementIds: request.evidence.requirementIds,\n\t\tcriterionIds: request.evidence.criterionIds,\n\t\tstatus: request.evidence.status,\n\t\tsource: request.evidence.source,\n\t\tsummary: request.evidence.summary,\n\t\tdigest: request.evidence.digest,\n\t\tclaimText: request.evidence.claimText,\n\n\t\treportedCollectorType: request.evidence.reportedCollectorType ?? \"agent\",\n\t\treportedAuthority: request.evidence.reportedAuthority ?? false,\n\n\t\teffectiveAuthority,\n\t\tverifiedPrincipalId: ctx.principalId,\n\t\tverifiedPrincipalKind: ctx.principalKind,\n\t\tverifiedCapability:\n\t\t\teffectiveAuthority !== \"agent-claim\" ? deriveCapabilityFromAuthority(effectiveAuthority) : undefined,\n\n\t\taddedAtRevision: newRevision,\n\t\tmetadata: request.evidence.metadata,\n\t};\n\n\tconst newLedger: RequirementLedgerV1 = {\n\t\t...ledger,\n\t\trevision: newRevision,\n\t\tevidence: [...ledger.evidence, evidenceRecord],\n\t};\n\n\t// =========================================================================\n\t// MUTATION CLOSURE GATE — authoritative evidence insertion\n\t// Privileged operations MUST have a genuine TrustedValidationContext.\n\t// =========================================================================\n\tif (effectiveAuthority !== \"agent-claim\") {\n\t\tif (!validationContext || !isTrustedValidationContext(validationContext)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: \"A genuine TrustedValidationContext is required for authoritative evidence insertion\",\n\t\t\t\tcode: \"TRUSTED_VALIDATION_CONTEXT_REQUIRED\",\n\t\t\t};\n\t\t}\n\t\tconst closureResult = validateRequirementLedger(contract, newLedger, validationContext);\n\t\tif (!closureResult.ok) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Mutation closure replay failed: ${closureResult.error}`,\n\t\t\t\tcode: \"INTERNAL_REPLAY_INVARIANT_VIOLATION\",\n\t\t\t};\n\t\t}\n\t}\n\n\treturn { ok: true, value: newLedger };\n}\n\n// =============================================================================\n// Apply transition to ledger — increments revision\n// =============================================================================\n\nexport function applyRequirementTransition(\n\tcontract: MissionContractV1,\n\tledger: RequirementLedgerV1,\n\trequest: TransitionRequest,\n\tcontext?: TrustedLedgerMutationContext,\n\tvalidationContext?: TrustedValidationContext,\n): OperationResult<RequirementLedgerV1> {\n\tconst ctx = context ?? getUntrustedContext();\n\n\tif (!request.transitionId || request.transitionId.trim().length === 0) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: \"transitionId is required (must be non-empty)\",\n\t\t\tcode: \"DUPLICATE_TRANSITION_ID\",\n\t\t};\n\t}\n\n\tif (request.expectedRevision !== ledger.revision) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: `Stale revision: expected ${request.expectedRevision}, current ${ledger.revision}`,\n\t\t\tcode: \"STALE_REVISION\",\n\t\t};\n\t}\n\n\t// Validate ledger (structural only — pre-condition for transition)\n\tconst valid = validateRequirementLedgerStructure(contract, ledger);\n\tif (!valid.ok) {\n\t\treturn { ok: false, error: valid.error ?? \"Invalid ledger\", code: valid.code ?? \"INVALID_LEDGER\" };\n\t}\n\n\tif (ledger.transitions.some((t) => t.id === request.transitionId)) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: `Duplicate transition id: ${request.transitionId}`,\n\t\t\tcode: \"DUPLICATE_TRANSITION_ID\",\n\t\t};\n\t}\n\n\tconst entryIdx = ledger.requirements.findIndex((r) => r.requirementId === request.requirementId);\n\tif (entryIdx === -1) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: `Unknown requirement: ${request.requirementId}`,\n\t\t\tcode: \"UNKNOWN_REQUIREMENT\",\n\t\t};\n\t}\n\n\tconst currentEntry = ledger.requirements[entryIdx];\n\tconst currentStatus = currentEntry.status;\n\n\tconst policy = validateTransition(currentStatus, request);\n\tif (!policy.permitted) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: policy.reason ?? \"Transition not permitted\",\n\t\t\tcode: \"INVALID_TRANSITION\",\n\t\t};\n\t}\n\n\tconst authCheck = authorizeTransition(currentStatus, request, ctx);\n\tif (!authCheck.permitted) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: authCheck.reason ?? \"Transition not authorized\",\n\t\t\tcode: \"TRUSTED_CONTEXT_REQUIRED\",\n\t\t};\n\t}\n\n\tconst newRevision = ledger.revision + 1;\n\tfor (const evId of request.evidenceIds) {\n\t\tconst ev = ledger.evidence.find((e) => e.id === evId);\n\t\tif (!ev) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Evidence ${evId} not found in ledger`,\n\t\t\t\tcode: \"UNKNOWN_EVIDENCE\",\n\t\t\t};\n\t\t}\n\t\tif (ev.addedAtRevision >= newRevision) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Evidence ${evId} added at revision ${ev.addedAtRevision} — must exist before transition at revision ${newRevision}`,\n\t\t\t\tcode: \"INVALID_TRANSITION\",\n\t\t\t};\n\t\t}\n\t}\n\n\tif (request.toStatus === \"SATISFIED\") {\n\t\tconst authCheck2 = isSatisfactionAuthorized(request, ledger, contract, ctx);\n\t\tif (!authCheck2.permitted) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: authCheck2.reason ?? \"Satisfaction not authorized\",\n\t\t\t\tcode: \"SELF_AUTH_SATISFIED\",\n\t\t\t};\n\t\t}\n\n\t\tconst freshnessCheck = checkEvidenceFreshnessAfterRegression(\n\t\t\trequest,\n\t\t\tledger,\n\t\t\tcontract,\n\t\t\tcurrentEntry.latestRegressionRevision,\n\t\t);\n\t\tif (!freshnessCheck.permitted) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: freshnessCheck.reason ?? \"Evidence not fresh after regression\",\n\t\t\t\tcode: \"STALE_EVIDENCE_AFTER_REGRESSION\",\n\t\t\t};\n\t\t}\n\t}\n\n\tif (request.toStatus === \"NOT_APPLICABLE\" && !request.reason) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: \"Transition to NOT_APPLICABLE requires a reason\",\n\t\t\tcode: \"NOT_APPLICABLE_AUTHORITY\",\n\t\t};\n\t}\n\n\tconst transition: RequirementTransition = {\n\t\tid: request.transitionId,\n\t\tledgerRevisionBefore: ledger.revision,\n\t\tledgerRevisionAfter: newRevision,\n\t\trequirementId: request.requirementId,\n\t\tfromStatus: currentStatus,\n\t\ttoStatus: request.toStatus,\n\n\t\treportedActorType: request.reportedActorType ?? \"agent\",\n\t\treportedActorId: request.reportedActorId,\n\n\t\tverifiedPrincipalId: ctx.principalId,\n\t\tverifiedPrincipalKind: ctx.principalKind,\n\t\tverifiedCapability:\n\t\t\trequest.toStatus === \"SATISFIED\"\n\t\t\t\t? \"transition:satisfy\"\n\t\t\t\t: request.toStatus === \"NOT_APPLICABLE\" && currentStatus !== \"UNASSESSED\"\n\t\t\t\t\t? \"transition:not-applicable\"\n\t\t\t\t\t: undefined,\n\n\t\treason: request.reason,\n\t\tevidenceIds: request.evidenceIds,\n\t\tblockerReference: request.blockerReference,\n\t\tmetadata: request.metadata,\n\t};\n\n\tconst newEntries = [...ledger.requirements];\n\tconst updatedEntry: RequirementLedgerEntry = {\n\t\t...currentEntry,\n\t\tstatus: request.toStatus,\n\t};\n\n\tif (currentStatus === \"SATISFIED\" && request.toStatus !== \"SATISFIED\") {\n\t\tupdatedEntry.latestRegressionRevision = newRevision;\n\t}\n\n\tnewEntries[entryIdx] = updatedEntry;\n\n\tconst newLedger: RequirementLedgerV1 = {\n\t\t...ledger,\n\t\trevision: newRevision,\n\t\trequirements: newEntries,\n\t\ttransitions: [...ledger.transitions, transition],\n\t};\n\n\t// =========================================================================\n\t// MUTATION CLOSURE GATE\n\t// After a privileged mutation (SATISFIED, regression, NOT_APPLICABLE),\n\t// validate the returned ledger through authoritative replay before\n\t// returning success. This ensures any accepted mutation produces a\n\t// ledger that immediately passes strict authoritative validation\n\t// under the same trusted context.\n\t// Privileged operations MUST have a genuine TrustedValidationContext.\n\t// =========================================================================\n\tconst isPrivileged =\n\t\trequest.toStatus === \"SATISFIED\" ||\n\t\tString(currentStatus) === \"SATISFIED\" ||\n\t\trequest.toStatus === \"NOT_APPLICABLE\";\n\n\tif (isPrivileged) {\n\t\tif (!validationContext || !isTrustedValidationContext(validationContext)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: \"A genuine TrustedValidationContext is required for privileged transitions\",\n\t\t\t\tcode: \"TRUSTED_VALIDATION_CONTEXT_REQUIRED\",\n\t\t\t};\n\t\t}\n\t\tconst closureResult = validateRequirementLedger(contract, newLedger, validationContext);\n\t\tif (!closureResult.ok) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Mutation closure replay failed: ${closureResult.error}`,\n\t\t\t\tcode: \"INTERNAL_REPLAY_INVARIANT_VIOLATION\",\n\t\t\t};\n\t\t}\n\t}\n\n\treturn { ok: true, value: newLedger };\n}\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction deriveCapabilityFromAuthority(authority: string): string | undefined {\n\tswitch (authority) {\n\t\tcase \"test-result\":\n\t\t\treturn \"evidence:test-result\";\n\t\tcase \"command-result\":\n\t\t\treturn \"evidence:command-result\";\n\t\tcase \"repository-observation\":\n\t\t\treturn \"evidence:repository-observation\";\n\t\tcase \"runtime-observation\":\n\t\t\treturn \"evidence:runtime-observation\";\n\t\tcase \"operator-confirmation\":\n\t\t\treturn \"evidence:operator-confirmation\";\n\t\tcase \"trusted-collector\":\n\t\t\treturn \"evidence:trusted-collector\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nfunction capabilityToAuthoritySimple(capability: string): string | undefined {\n\tswitch (capability) {\n\t\tcase \"evidence:repository-observation\":\n\t\t\treturn \"repository-observation\";\n\t\tcase \"evidence:command-result\":\n\t\t\treturn \"command-result\";\n\t\tcase \"evidence:test-result\":\n\t\t\treturn \"test-result\";\n\t\tcase \"evidence:runtime-observation\":\n\t\t\treturn \"runtime-observation\";\n\t\tcase \"evidence:operator-confirmation\":\n\t\t\treturn \"operator-confirmation\";\n\t\tcase \"evidence:trusted-collector\":\n\t\t\treturn \"trusted-collector\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n"]}