{"version":3,"file":"ledger-reducer.d.ts","sourceRoot":"","sources":["../../../src/core/long-horizon/ledger-reducer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,GAAG,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAoBzG;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAsC7E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,mBAAmB,EAC3B,aAAa,EAAE,MAAM,GACnB,2BAA2B,GAAG,SAAS,CAGzC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,2BAA2B,GAAG,OAAO,CAE5E","sourcesContent":["/**\n * Ledger Reducer — derive current state from transition history.\n *\n * Replays the full transition log to compute current requirement status.\n * Provides a cross-check that ledger.requirements matches the transition\n * history.\n */\n\nimport type { RequirementEvaluationStatus } from \"./domain-types.js\";\nimport type { RequirementLedgerV1 } from \"./types.js\";\n\n/**\n * Replay transitions to derive current requirement states.\n * Returns the computed state map for verification.\n */\nexport function deriveCurrentStates(ledger: RequirementLedgerV1): Map<string, RequirementEvaluationStatus> {\n\tconst stateMap = new Map<string, RequirementEvaluationStatus>();\n\n\t// Initialize from ledger entries (assuming they start at initialState)\n\tfor (const entry of ledger.requirements) {\n\t\tstateMap.set(entry.requirementId, entry.status);\n\t}\n\n\t// Replay transitions in order\n\tfor (const tx of ledger.transitions) {\n\t\tconst current = stateMap.get(tx.requirementId);\n\t\tif (current !== undefined && current === tx.fromStatus) {\n\t\t\tstateMap.set(tx.requirementId, tx.toStatus);\n\t\t}\n\t}\n\n\t// Walk back: for the purposes of consistency checking with the\n\t// actual ledger.requirements, we just trust the ledger entries\n\t// and validate transitions against the atomic from-state.\n\treturn stateMap;\n}\n\n/**\n * Verify that ledger requirement entries are consistent with\n * the transition history.\n *\n * Returns list of mismatches, if any.\n */\nexport function verifyLedgerConsistency(ledger: RequirementLedgerV1): string[] {\n\tconst errors: string[] = [];\n\n\t// Track state per requirement via transition replay\n\tconst computed = new Map<string, RequirementEvaluationStatus>();\n\n\t// Start from initial state based on contract initialization\n\tfor (const entry of ledger.requirements) {\n\t\t// Determine initial state\n\t\tconst initStatus: RequirementEvaluationStatus = entry.initialNotApplicable ? \"NOT_APPLICABLE\" : \"UNASSESSED\";\n\t\tcomputed.set(entry.requirementId, initStatus);\n\t}\n\n\t// Replay all transitions\n\tfor (const tx of ledger.transitions) {\n\t\tconst current = computed.get(tx.requirementId);\n\t\tif (current === undefined) {\n\t\t\terrors.push(`Transition ${tx.id} references unknown requirement ${tx.requirementId}`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (tx.fromStatus !== current) {\n\t\t\terrors.push(\n\t\t\t\t`Transition ${tx.id}: expected fromStatus ${current} for ${tx.requirementId}, got ${tx.fromStatus}`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tcomputed.set(tx.requirementId, tx.toStatus);\n\t}\n\n\t// Verify ledger.requirements matches computed state\n\tfor (const entry of ledger.requirements) {\n\t\tconst computedStatus = computed.get(entry.requirementId);\n\t\tif (computedStatus !== undefined && computedStatus !== entry.status) {\n\t\t\terrors.push(`Requirement ${entry.requirementId}: ledger has ${entry.status}, computed has ${computedStatus}`);\n\t\t}\n\t}\n\n\treturn errors;\n}\n\n/**\n * Get the current status of a requirement from the ledger.\n */\nexport function getRequirementStatus(\n\tledger: RequirementLedgerV1,\n\trequirementId: string,\n): RequirementEvaluationStatus | undefined {\n\tconst entry = ledger.requirements.find((r) => r.requirementId === requirementId);\n\treturn entry?.status;\n}\n\n/**\n * Check if a requirement is in a terminal state (SATISFIED or NOT_APPLICABLE).\n */\nexport function isTerminalState(status: RequirementEvaluationStatus): boolean {\n\treturn status === \"SATISFIED\" || status === \"NOT_APPLICABLE\";\n}\n"]}