{"version":3,"file":"mission-runtime.d.ts","sourceRoot":"","sources":["../../../src/core/reliability/mission-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Mission Runtime — the Reliability Kernel's runtime facade.\n *\n * Owns the durable Mission Contract, Requirement Ledger, and Mission Execution\n * State Machine (all from the Long-Horizon subsystem) and exposes a small,\n * Jensen-owned API for the agent loop:\n *\n *   - decode/validate model actions (validator is separate; see action-validator)\n *   - record deterministic verification evidence (authoritative, never agent-claim)\n *   - advance acceptance criteria to SATISFIED only from authoritative evidence\n *   - run the Completion Gate on FINAL_CANDIDATE\n *   - serialize/deserialize durably (survives resume/compaction/restart)\n *\n * The model interacts only through the untrusted context; the runtime holds the\n * trusted mutation/validation contexts that authorize authoritative evidence and\n * SATISFIED transitions.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport type {\n\tMissionConstraint,\n\tMissionContractV1,\n\tMissionExecutionRecordV1,\n\tMissionExecutionState,\n\tMissionExecutionTransitionKind,\n\tRequirementEvaluationStatus,\n\tRequirementLedgerV1,\n} from \"../long-horizon/index.js\";\nimport {\n\taddLedgerEvidence,\n\tapplyMissionExecutionTransition,\n\tapplyRequirementTransition,\n\tinitializeMissionExecution,\n\tinitializeRequirementLedger,\n\tinspectRequirementLedgerStructure,\n\tvalidateMissionContract,\n} from \"../long-horizon/index.js\";\nimport type { TrustedLedgerMutationContext, TrustedValidationContext } from \"../long-horizon/trusted-context.js\";\nimport {\n\t_internalCreateTrustedContext,\n\t_internalCreateTrustedValidationContext,\n} from \"../long-horizon/trusted-context.js\";\nimport { evaluateCompletionGate } from \"./completion-gate.js\";\nimport { runtimeSourceId, VERIFICATION_EVIDENCE_MAP } from \"./evidence-mapping.js\";\nimport { buildMissionContract, type MissionDefinitionInput } from \"./mission-contract-factory.js\";\nimport { InMemoryReliabilityRecorder, type ReliabilityRecorder } from \"./telemetry.js\";\nimport type {\n\tCompletionGateResult,\n\tCriterionSource,\n\tFailureEvent,\n\tMissionEvidence,\n\tReliabilityPhase,\n\tRuntimeAcceptanceCriterion,\n\tVerificationResult,\n\tVerificationSpec,\n} from \"./types.js\";\n\nexport const MISSION_RUNTIME_SCHEMA_VERSION = 1 as const;\n\nexport const RUNTIME_PRINCIPAL = \"jensen-runtime\";\nexport const COMPLETION_PRINCIPAL = \"completion-operator\";\n\ninterface CriterionMeta {\n\tid: string;\n\tdescription: string;\n\tsource: CriterionSource;\n\tverification: VerificationSpec;\n}\n\nexport interface MissionRuntimeDocumentV1 {\n\tschemaVersion: 1;\n\tmissionId: string;\n\tgoal: string;\n\tcontract: MissionContractV1;\n\tledger: RequirementLedgerV1;\n\texecution: MissionExecutionRecordV1;\n\tcriteria: CriterionMeta[];\n\tconstraints: MissionConstraint[];\n\tcreatedAtMs: number;\n\tupdatedAtMs: number;\n}\n\nconst RUNTIME_CAPABILITIES = [\n\t\"evidence:command-result\",\n\t\"evidence:test-result\",\n\t\"evidence:repository-observation\",\n\t\"evidence:runtime-observation\",\n\t\"evidence:operator-confirmation\",\n\t\"transition:satisfy\",\n\t\"transition:not-applicable\",\n] as const;\n\nconst RUNTIME_SOURCE_GRANTS = [\n\t{\n\t\tauthority: \"command-result\",\n\t\tcapability: \"evidence:command-result\",\n\t\tallowedEvidenceTypes: [\"command-result\", \"build-result\"],\n\t},\n\t{ authority: \"test-result\", capability: \"evidence:test-result\", allowedEvidenceTypes: [\"test-result\"] },\n\t{\n\t\tauthority: \"repository-observation\",\n\t\tcapability: \"evidence:repository-observation\",\n\t\tallowedEvidenceTypes: [\"file-change\", \"repository-state\"],\n\t},\n\t{\n\t\tauthority: \"runtime-observation\",\n\t\tcapability: \"evidence:runtime-observation\",\n\t\tallowedEvidenceTypes: [\"runtime-observation\"],\n\t},\n\t{\n\t\tauthority: \"operator-confirmation\",\n\t\tcapability: \"evidence:operator-confirmation\",\n\t\tallowedEvidenceTypes: [\"operator-confirmation\"],\n\t},\n] as const;\n\nfunction buildTrustedMutationContext(): TrustedLedgerMutationContext {\n\treturn _internalCreateTrustedContext({\n\t\tprincipalId: RUNTIME_PRINCIPAL,\n\t\tprincipalKind: \"system\",\n\t\tcapabilities: [...RUNTIME_CAPABILITIES],\n\t});\n}\n\nfunction buildTrustedValidationContext(contract: MissionContractV1): TrustedValidationContext {\n\treturn _internalCreateTrustedValidationContext({\n\t\tcontract,\n\t\tprincipals: [\n\t\t\t{ principalId: RUNTIME_PRINCIPAL, principalKind: \"system\", capabilities: [...RUNTIME_CAPABILITIES] },\n\t\t\t{ principalId: COMPLETION_PRINCIPAL, principalKind: \"operator\", capabilities: [\"execution:complete\"] },\n\t\t],\n\t\tsourceGrants: RUNTIME_SOURCE_GRANTS.map((g) => ({\n\t\t\tsourceId: runtimeSourceId(g.authority),\n\t\t\tprincipalId: RUNTIME_PRINCIPAL,\n\t\t\tprincipalKind: \"system\" as const,\n\t\t\tcapability: g.capability,\n\t\t\tallowedEvidenceTypes: [...g.allowedEvidenceTypes],\n\t\t})),\n\t});\n}\n\nconst PHASE_BY_STATE: Record<MissionExecutionState, ReliabilityPhase> = {\n\tPLANNING: \"PLANNING\",\n\tEXECUTION: \"ACTING\",\n\tVERIFICATION: \"VERIFYING\",\n\tCOMPLETION_REVIEW: \"FINALIZING\",\n\tBLOCKED: \"BLOCKED\",\n\tCOMPLETED: \"COMPLETED\",\n\tFAILED: \"FAILED\",\n\tCANCELLED: \"FAILED\",\n};\n\nexport class MissionRuntime {\n\tprivate _contract: MissionContractV1;\n\tprivate _ledger: RequirementLedgerV1;\n\tprivate _execution: MissionExecutionRecordV1;\n\tprivate readonly _criteria: CriterionMeta[];\n\tprivate readonly _constraints: MissionConstraint[];\n\tprivate readonly _createdAtMs: number;\n\tprivate _updatedAtMs: number;\n\tprivate readonly _recorder: ReliabilityRecorder;\n\tprivate readonly _failures: FailureEvent[];\n\tprivate readonly _trustedMutation: TrustedLedgerMutationContext;\n\tprivate readonly _trustedValidation: TrustedValidationContext;\n\n\tprivate constructor(input: {\n\t\tcontract: MissionContractV1;\n\t\tledger: RequirementLedgerV1;\n\t\texecution: MissionExecutionRecordV1;\n\t\tcriteria: CriterionMeta[];\n\t\tconstraints: MissionConstraint[];\n\t\tcreatedAtMs: number;\n\t\tupdatedAtMs: number;\n\t\trecorder: ReliabilityRecorder;\n\t\tfailures: FailureEvent[];\n\t}) {\n\t\tthis._contract = input.contract;\n\t\tthis._ledger = input.ledger;\n\t\tthis._execution = input.execution;\n\t\tthis._criteria = input.criteria;\n\t\tthis._constraints = input.constraints;\n\t\tthis._createdAtMs = input.createdAtMs;\n\t\tthis._updatedAtMs = input.updatedAtMs;\n\t\tthis._recorder = input.recorder;\n\t\tthis._failures = input.failures;\n\t\tthis._trustedMutation = buildTrustedMutationContext();\n\t\tthis._trustedValidation = buildTrustedValidationContext(this._contract);\n\t}\n\n\tstatic create(\n\t\tdefinition: MissionDefinitionInput,\n\t\toptions: { recorder?: ReliabilityRecorder; now?: number } = {},\n\t): MissionRuntime {\n\t\tconst contract = buildMissionContract(definition);\n\t\tconst validation = validateMissionContract(contract);\n\t\tif (!validation.valid) {\n\t\t\tthrow new Error(`Invalid mission contract: ${validation.errors.map((e) => e.message).join(\"; \")}`);\n\t\t}\n\t\tconst ledgerResult = initializeRequirementLedger(contract);\n\t\tif (!ledgerResult.ok) {\n\t\t\tthrow new Error(`Failed to initialize requirement ledger: ${ledgerResult.error}`);\n\t\t}\n\t\tconst execution = initializeMissionExecution(contract, `${contract.missionId}-exec`);\n\t\tconst now = options.now ?? Date.now();\n\n\t\tconst criteria: CriterionMeta[] = definition.criteria.map((c) => ({\n\t\t\tid: c.id,\n\t\t\tdescription: c.description,\n\t\t\tsource: c.source,\n\t\t\tverification: c.verification,\n\t\t}));\n\n\t\tconst recorder =\n\t\t\toptions.recorder ?? new InMemoryReliabilityRecorder({ missionId: contract.missionId, now: () => now });\n\t\trecorder.record(\"mission_started\", { goal: contract.objective });\n\n\t\treturn new MissionRuntime({\n\t\t\tcontract,\n\t\t\tledger: ledgerResult.value!,\n\t\t\texecution,\n\t\t\tcriteria,\n\t\t\tconstraints: contract.constraints,\n\t\t\tcreatedAtMs: now,\n\t\t\tupdatedAtMs: now,\n\t\t\trecorder,\n\t\t\tfailures: [],\n\t\t});\n\t}\n\n\tstatic deserialize(\n\t\tdocument: unknown,\n\t\toptions: { recorder?: ReliabilityRecorder; now?: number } = {},\n\t): MissionRuntime {\n\t\tif (typeof document !== \"object\" || document === null) {\n\t\t\tthrow new Error(\"MissionRuntime document must be an object\");\n\t\t}\n\t\tconst doc = document as Partial<MissionRuntimeDocumentV1>;\n\t\tif (doc.schemaVersion !== 1) {\n\t\t\tthrow new Error(`Unsupported MissionRuntime schema version: ${String(doc.schemaVersion)}`);\n\t\t}\n\t\tif (!doc.contract || !doc.ledger || !doc.execution || !Array.isArray(doc.criteria)) {\n\t\t\tthrow new Error(\"MissionRuntime document is missing required fields\");\n\t\t}\n\n\t\tconst contractValidation = validateMissionContract(doc.contract);\n\t\tif (!contractValidation.valid) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid persisted mission contract: ${contractValidation.errors.map((e) => e.message).join(\"; \")}`,\n\t\t\t);\n\t\t}\n\n\t\tconst structural = inspectRequirementLedgerStructure(doc.contract, doc.ledger);\n\t\tif (!structural.structurallyValid) {\n\t\t\tthrow new Error(`Invalid persisted requirement ledger: ${JSON.stringify(structural)}`);\n\t\t}\n\n\t\tconst now = options.now ?? Date.now();\n\t\tconst recorder =\n\t\t\toptions.recorder ?? new InMemoryReliabilityRecorder({ missionId: doc.missionId, now: () => now });\n\t\trecorder.record(\"mission_started\", { goal: doc.goal });\n\n\t\treturn new MissionRuntime({\n\t\t\tcontract: doc.contract,\n\t\t\tledger: doc.ledger,\n\t\t\texecution: doc.execution,\n\t\t\tcriteria: doc.criteria,\n\t\t\tconstraints: doc.constraints ?? [],\n\t\t\tcreatedAtMs: doc.createdAtMs ?? now,\n\t\t\tupdatedAtMs: doc.updatedAtMs ?? now,\n\t\t\trecorder,\n\t\t\tfailures: [],\n\t\t});\n\t}\n\n\t// =========================================================================\n\t// Accessors\n\t// =========================================================================\n\n\tget missionId(): string {\n\t\treturn this._contract.missionId;\n\t}\n\n\tget goal(): string {\n\t\treturn this._contract.objective;\n\t}\n\n\tget contract(): MissionContractV1 {\n\t\treturn this._contract;\n\t}\n\n\tget ledger(): RequirementLedgerV1 {\n\t\treturn this._ledger;\n\t}\n\n\tget execution(): MissionExecutionRecordV1 {\n\t\treturn this._execution;\n\t}\n\n\tget phase(): ReliabilityPhase {\n\t\treturn PHASE_BY_STATE[this._execution.state];\n\t}\n\n\tget recorder(): ReliabilityRecorder {\n\t\treturn this._recorder;\n\t}\n\n\tget failures(): readonly FailureEvent[] {\n\t\treturn this._failures;\n\t}\n\n\tget constraints(): readonly MissionConstraint[] {\n\t\treturn this._constraints;\n\t}\n\n\t// =========================================================================\n\t// Criteria view\n\t// =========================================================================\n\n\tcriterionView(): RuntimeAcceptanceCriterion[] {\n\t\treturn this._criteria.map((meta) => ({\n\t\t\tid: meta.id,\n\t\t\tdescription: meta.description,\n\t\t\tsource: meta.source,\n\t\t\tstatus: this._criterionStatus(meta.id),\n\t\t\tverification: meta.verification,\n\t\t\tevidenceIds: this._ledger.evidence.filter((e) => e.criterionIds.includes(meta.id)).map((e) => e.id),\n\t\t}));\n\t}\n\n\tprivate _criterionStatus(criterionId: string): \"pending\" | \"passed\" | \"failed\" | \"blocked\" {\n\t\tconst entry = this._ledger.requirements.find((r) => r.requirementId === criterionId);\n\t\tif (entry?.status === \"SATISFIED\") return \"passed\";\n\t\tif (entry?.status === \"BLOCKED\") return \"blocked\";\n\t\tif (entry?.status === \"FAILED\") return \"failed\";\n\t\treturn \"pending\";\n\t}\n\n\t// =========================================================================\n\t// Deterministic verification\n\t// =========================================================================\n\n\t/**\n\t * Record the outcome of a deterministic verification for a criterion.\n\t * A passing verification advances the criterion to SATISFIED using only\n\t * authoritative evidence; a failing verification records a fail evidence\n\t * and leaves the criterion unsatisfied (the model cannot self-certify).\n\t */\n\trecordVerification(criterionId: string, result: VerificationResult): void {\n\t\tconst meta = this._criteria.find((c) => c.id === criterionId);\n\t\tif (!meta) {\n\t\t\tthis._recordFailure(\"INTERNAL_RUNTIME_FAILURE\", `Unknown criterion id: ${criterionId}`, false);\n\t\t\treturn;\n\t\t}\n\t\tconst mapping = VERIFICATION_EVIDENCE_MAP[meta.verification.kind];\n\t\tconst status = result.passed ? (\"pass\" as const) : (\"fail\" as const);\n\t\tconst evidenceId = this._nextEvidenceId(criterionId);\n\n\t\t// Passing evidence binds to the criterion (authorizes SATISFIED). Failing\n\t\t// evidence is recorded as an unbound observation of a failed verification\n\t\t// so it can never violate a criterion's pass-required evidence policy.\n\t\tconst requirementIds = result.passed ? [criterionId] : [];\n\t\tconst criterionIds = result.passed ? [criterionId] : [];\n\n\t\tconst addResult = addLedgerEvidence(\n\t\t\tthis._contract,\n\t\t\tthis._ledger,\n\t\t\t{\n\t\t\t\texpectedRevision: this._ledger.revision,\n\t\t\t\tevidence: {\n\t\t\t\t\tid: evidenceId,\n\t\t\t\t\ttype: mapping.ledgerType,\n\t\t\t\t\trequirementIds,\n\t\t\t\t\tcriterionIds,\n\t\t\t\t\tstatus,\n\t\t\t\t\tsource: runtimeSourceId(mapping.authority),\n\t\t\t\t\tsummary: result.evidence.summary,\n\t\t\t\t\treportedCollectorType: mapping.collector,\n\t\t\t\t\treportedAuthority: true,\n\t\t\t\t\tmetadata: { verificationKind: meta.verification.kind },\n\t\t\t\t},\n\t\t\t},\n\t\t\tthis._trustedMutation,\n\t\t\tthis._trustedValidation,\n\t\t);\n\n\t\tif (!addResult.ok) {\n\t\t\tthis._recordFailure(\"VERIFICATION_FAILURE\", `Failed to record evidence: ${addResult.error}`, false);\n\t\t\treturn;\n\t\t}\n\t\tthis._ledger = addResult.value!;\n\t\tthis._recorder.record(\"evidence_recorded\", { criterionId, evidenceId, passed: result.passed });\n\n\t\tif (result.passed) {\n\t\t\tthis._advanceToSatisfied(criterionId, evidenceId);\n\t\t\tthis._recorder.record(\"criterion_passed\", { criterionId });\n\t\t} else {\n\t\t\tthis._regressIfSatisfied(criterionId);\n\t\t\tthis._recorder.record(\"criterion_failed\", { criterionId });\n\t\t}\n\t\tthis._recorder.record(\"verification_executed\", { criterionId, passed: result.passed });\n\t\tthis._touch();\n\t}\n\n\t/**\n\t * Record an observed tool-execution outcome as mission evidence (not tied to\n\t * a specific criterion). Jensen records the observed facts; the model cannot\n\t * fabricate them.\n\t */\n\trecordToolEvidence(evidence: MissionEvidence): void {\n\t\tconst mapping = VERIFICATION_EVIDENCE_MAP.command;\n\t\tconst evidenceId = this._nextEvidenceId(\"tool\");\n\t\tconst addResult = addLedgerEvidence(\n\t\t\tthis._contract,\n\t\t\tthis._ledger,\n\t\t\t{\n\t\t\t\texpectedRevision: this._ledger.revision,\n\t\t\t\tevidence: {\n\t\t\t\t\tid: evidenceId,\n\t\t\t\t\ttype: mapping.ledgerType,\n\t\t\t\t\trequirementIds: [],\n\t\t\t\t\tcriterionIds: evidence.criterionIds ?? [],\n\t\t\t\t\tstatus: evidence.success === false ? \"fail\" : \"unknown\",\n\t\t\t\t\tsource: runtimeSourceId(mapping.authority),\n\t\t\t\t\tsummary: evidence.summary,\n\t\t\t\t\treportedCollectorType: mapping.collector,\n\t\t\t\t\treportedAuthority: true,\n\t\t\t\t\tmetadata: evidence.data as Record<string, unknown> | undefined,\n\t\t\t\t},\n\t\t\t},\n\t\t\tthis._trustedMutation,\n\t\t\tthis._trustedValidation,\n\t\t);\n\t\tif (addResult.ok) {\n\t\t\tthis._ledger = addResult.value!;\n\t\t\tthis._recorder.record(\"evidence_recorded\", { evidenceId, tool: evidence.source });\n\t\t}\n\t\tthis._touch();\n\t}\n\n\tprivate _nextEvidenceId(criterionId: string): string {\n\t\treturn `ev_${criterionId}_${this._ledger.revision + 1}`;\n\t}\n\n\tprivate _advanceToSatisfied(requirementId: string, evidenceId: string): void {\n\t\tlet entry = this._ledger.requirements.find((r) => r.requirementId === requirementId);\n\t\tif (!entry) return;\n\n\t\t// Reach IMPLEMENTED_UNVERIFIED, then SATISFIED.\n\t\tlet guard = 0;\n\t\twhile (entry.status !== \"SATISFIED\" && guard < 8) {\n\t\t\tguard += 1;\n\t\t\tconst next = this._nextTowardSatisfied(entry.status);\n\t\t\tif (next === undefined) return;\n\t\t\tconst transition = applyRequirementTransition(\n\t\t\t\tthis._contract,\n\t\t\t\tthis._ledger,\n\t\t\t\t{\n\t\t\t\t\ttransitionId: this._txId(requirementId, next),\n\t\t\t\t\texpectedRevision: this._ledger.revision,\n\t\t\t\t\trequirementId,\n\t\t\t\t\ttoStatus: next,\n\t\t\t\t\treason: next === \"SATISFIED\" ? \"deterministic verification passed\" : \"advancing toward satisfaction\",\n\t\t\t\t\tevidenceIds: next === \"SATISFIED\" ? [evidenceId] : [],\n\t\t\t\t\treportedActorType: \"system\",\n\t\t\t\t\treportedActorId: RUNTIME_PRINCIPAL,\n\t\t\t\t},\n\t\t\t\tthis._trustedMutation,\n\t\t\t\tthis._trustedValidation,\n\t\t\t);\n\t\t\tif (!transition.ok) {\n\t\t\t\tthis._recordFailure(\"VERIFICATION_FAILURE\", `Transition to ${next} failed: ${transition.error}`, false);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis._ledger = transition.value!;\n\t\t\tentry = this._ledger.requirements.find((r) => r.requirementId === requirementId)!;\n\t\t}\n\t}\n\n\t/**\n\t * When a previously-satisfied criterion fails verification, transition it out\n\t * of SATISFIED so the completion gate requires fresh authoritative evidence.\n\t */\n\tprivate _regressIfSatisfied(requirementId: string): void {\n\t\tconst entry = this._ledger.requirements.find((r) => r.requirementId === requirementId);\n\t\tif (entry?.status !== \"SATISFIED\") return;\n\t\tconst transition = applyRequirementTransition(\n\t\t\tthis._contract,\n\t\t\tthis._ledger,\n\t\t\t{\n\t\t\t\ttransitionId: this._txId(requirementId, \"IMPLEMENTED_UNVERIFIED\"),\n\t\t\t\texpectedRevision: this._ledger.revision,\n\t\t\t\trequirementId,\n\t\t\t\ttoStatus: \"IMPLEMENTED_UNVERIFIED\",\n\t\t\t\treason: \"verification failed after prior satisfaction\",\n\t\t\t\tevidenceIds: [],\n\t\t\t\treportedActorType: \"system\",\n\t\t\t\treportedActorId: RUNTIME_PRINCIPAL,\n\t\t\t},\n\t\t\tthis._trustedMutation,\n\t\t\tthis._trustedValidation,\n\t\t);\n\t\tif (transition.ok) {\n\t\t\tthis._ledger = transition.value!;\n\t\t}\n\t}\n\n\tprivate _nextTowardSatisfied(status: RequirementEvaluationStatus): RequirementEvaluationStatus | undefined {\n\t\tswitch (status) {\n\t\t\tcase \"UNASSESSED\":\n\t\t\tcase \"PENDING\":\n\t\t\tcase \"IN_PROGRESS\":\n\t\t\t\treturn \"IMPLEMENTED_UNVERIFIED\";\n\t\t\tcase \"IMPLEMENTED_UNVERIFIED\":\n\t\t\t\treturn \"SATISFIED\";\n\t\t\tcase \"BLOCKED\":\n\t\t\tcase \"FAILED\":\n\t\t\t\treturn \"IN_PROGRESS\";\n\t\t\tcase \"NOT_APPLICABLE\":\n\t\t\t\treturn \"PENDING\";\n\t\t\tdefault:\n\t\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate _txId(requirementId: string, toStatus: string): string {\n\t\treturn `tx_${requirementId}_${this._ledger.revision + 1}_${toStatus}`;\n\t}\n\n\t// =========================================================================\n\t// Finalization\n\t// =========================================================================\n\n\tproposeFinalCandidate(): CompletionGateResult {\n\t\tthis._recorder.record(\"finalization_proposed\", { phase: this.phase });\n\t\tconst gate = evaluateCompletionGate(this._contract, this._ledger, this._trustedValidation);\n\t\tif (gate.decision === \"reject\") {\n\t\t\tthis._recorder.record(\"finalization_rejected\", { missingCriterionIds: gate.missingCriterionIds });\n\t\t\tthis._recordFailure(\n\t\t\t\t\"FINALIZATION_REJECTED\",\n\t\t\t\t`Unverified acceptance criteria: ${gate.missingCriterionIds.join(\", \") || \"(none)\"}`,\n\t\t\t\ttrue,\n\t\t\t\t{ missingCriterionIds: gate.missingCriterionIds },\n\t\t\t);\n\t\t}\n\t\tthis._touch();\n\t\treturn gate;\n\t}\n\n\t/** Transition the execution state machine by kind. */\n\ttransition(kind: MissionExecutionTransitionKind): { ok: boolean; error?: string } {\n\t\tconst result = applyMissionExecutionTransition(this._contract, this._execution, {\n\t\t\ttransitionId: `exec_${this._execution.revision + 1}_${kind}`,\n\t\t\texpectedRevision: this._execution.revision,\n\t\t\tkind,\n\t\t});\n\t\tif (!result.ok) {\n\t\t\treturn { ok: false, error: result.error };\n\t\t}\n\t\tthis._execution = result.record;\n\t\tthis._touch();\n\t\treturn { ok: true };\n\t}\n\n\t/** Approve completion through the execution state machine (COMPLETED). */\n\tapproveCompletion(): { ok: boolean; error?: string } {\n\t\tconst gate = evaluateCompletionGate(this._contract, this._ledger, this._trustedValidation);\n\t\tif (gate.decision === \"reject\") {\n\t\t\treturn { ok: false, error: `completion gate rejected: ${gate.reasons.join(\"; \")}` };\n\t\t}\n\t\tconst result = applyMissionExecutionTransition(\n\t\t\tthis._contract,\n\t\t\tthis._execution,\n\t\t\t{\n\t\t\t\ttransitionId: `exec_${this._execution.revision + 1}_APPROVE_COMPLETION`,\n\t\t\t\texpectedRevision: this._execution.revision,\n\t\t\t\tkind: \"APPROVE_COMPLETION\",\n\t\t\t},\n\t\t\t{ trustedValidationContext: this._trustedValidation },\n\t\t);\n\t\tif (!result.ok) {\n\t\t\treturn { ok: false, error: result.error };\n\t\t}\n\t\tthis._execution = result.record;\n\t\tthis._recorder.record(\"mission_completed\", { phase: \"COMPLETED\" });\n\t\tthis._touch();\n\t\treturn { ok: true };\n\t}\n\n\tblock(reason: string): { ok: boolean; error?: string } {\n\t\tconst result = applyMissionExecutionTransition(this._contract, this._execution, {\n\t\t\ttransitionId: `exec_${this._execution.revision + 1}_BLOCK`,\n\t\t\texpectedRevision: this._execution.revision,\n\t\t\tkind: \"BLOCK\",\n\t\t});\n\t\tif (!result.ok) {\n\t\t\treturn { ok: false, error: result.error };\n\t\t}\n\t\tthis._execution = result.record;\n\t\tthis._recorder.record(\"mission_blocked\", { reason });\n\t\tthis._recordFailure(\"CONTEXT_REQUIRED\", reason, true);\n\t\tthis._touch();\n\t\treturn { ok: true };\n\t}\n\n\t// =========================================================================\n\t// Context presentation\n\t// =========================================================================\n\n\t/** Compact, token-disciplined mission state for the model context. */\n\tsummarizeForModel(): string {\n\t\tconst criteria = this.criterionView();\n\t\tconst lines: string[] = [];\n\t\tlines.push(\"MISSION\");\n\t\tlines.push(`Goal: ${this.goal}`);\n\t\tlines.push(`Status: ${this.phase}`);\n\t\tif (this._constraints.length > 0) {\n\t\t\tlines.push(\"Required constraints:\");\n\t\t\tfor (const c of this._constraints) lines.push(`- ${c.id}: ${c.statement}`);\n\t\t}\n\t\tlines.push(\"Acceptance criteria:\");\n\t\tfor (const c of criteria) {\n\t\t\tconst mark = c.status === \"passed\" ? \"✓\" : c.status === \"failed\" ? \"✗\" : \"○\";\n\t\t\tlines.push(`${mark} ${c.id} — ${c.description}`);\n\t\t}\n\t\tlines.push(\"Next responsibility: propose actions; Jensen validates and verifies completion.\");\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\t// =========================================================================\n\t// Durable serialization\n\t// =========================================================================\n\n\tserialize(): MissionRuntimeDocumentV1 {\n\t\treturn {\n\t\t\tschemaVersion: MISSION_RUNTIME_SCHEMA_VERSION,\n\t\t\tmissionId: this._contract.missionId,\n\t\t\tgoal: this._contract.objective,\n\t\t\tcontract: this._contract,\n\t\t\tledger: this._ledger,\n\t\t\texecution: this._execution,\n\t\t\tcriteria: this._criteria.map((c) => ({ ...c })),\n\t\t\tconstraints: this._constraints,\n\t\t\tcreatedAtMs: this._createdAtMs,\n\t\t\tupdatedAtMs: this._updatedAtMs,\n\t\t};\n\t}\n\n\ttoJSON(): string {\n\t\treturn JSON.stringify(this.serialize());\n\t}\n\n\tprivate _touch(): void {\n\t\tthis._updatedAtMs = Date.now();\n\t}\n\n\tprivate _recordFailure(\n\t\tcategory: FailureEvent[\"category\"],\n\t\tmessage: string,\n\t\trecoverable: boolean,\n\t\tdetails?: unknown,\n\t): void {\n\t\tthis._failures.push({\n\t\t\tcategory,\n\t\t\tmessage,\n\t\t\trecoverable,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tdetails,\n\t\t});\n\t}\n}\n\n/** Convenience: new mission id. */\nexport function newMissionId(): string {\n\treturn `mission_${randomUUID()}`;\n}\n"]}