{"version":3,"file":"evidence-retrieval.d.ts","sourceRoot":"","sources":["../../../src/core/context-runtime/evidence-retrieval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAe,MAAM,uBAAuB,CAAC;AAE/F,oFAAoF;AACpF,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAEhD,qFAAqF;AACrF,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAE5C,MAAM,MAAM,uBAAuB,GAAG,IAAI,GAAG,WAAW,GAAG,SAAS,GAAG,eAAe,CAAC;AAEvF,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,YAAY,CAAC;AAE1D,MAAM,WAAW,yBAAyB;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,GAAG,EAAE,MAAM,CAAC;IACZ,8CAA8C;IAC9C,cAAc,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,SAAS,EAAE,kBAAkB,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACvC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,uBAAuB,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IACrC,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACxC,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iHAAiH;IACjH,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,uGAAuG;AACvG,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGxE;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,eAAe,EACxB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,wBAA6B,GACpC,OAAO,CAAC,uBAAuB,CAAC,CAyDlC","sourcesContent":["/**\n * Model-facing evidence retrieval (2.5.0 extension).\n *\n * Bridges a deterministic evidence reference (the id embedded in virtualized\n * tool results and checkpoint preambles) back to its authoritative cold\n * artifact. Retrieval is:\n *   - read-only: it returns DATA, never privileged instructions\n *   - bounded: a hard page cap so a single call can never re-inflate the model\n *     context beyond the Context Governor's budget\n *   - integrity-checked: content is rehashed against the stored contentHash and\n *     fails closed on mismatch (never a synopsis, never fabricated content)\n *   - deterministic: character-range paging so the model can page the same\n *     artifact repeatedly and reconstruct it exactly\n *\n * Retrieval does NOT move completion authority. Merely fetching an archived\n * `node --test` output never means \"tests verified\"; the Reliability Kernel /\n * Completion Gate remain the sole authority for mission completion.\n */\n\nimport { type EvidenceArchive, type EvidenceRecord, hashContent } from \"./evidence-archive.js\";\n\n/** Default characters returned per page when the model does not specify a limit. */\nexport const DEFAULT_EVIDENCE_PAGE_CHARS = 4000;\n\n/** Hard maximum characters returned by a single retrieval (provider-independent). */\nexport const MAX_EVIDENCE_PAGE_CHARS = 8000;\n\nexport type EvidenceRetrievalStatus = \"ok\" | \"not-found\" | \"corrupt\" | \"invalid-range\";\n\nexport type EvidenceIntegrity = \"verified\" | \"unverified\";\n\nexport interface EvidenceRetrievalMetadata {\n\tevidenceId: string;\n\tkind: EvidenceRecord[\"kind\"];\n\tsource: string;\n\tcontentHash: string;\n\tintegrity: EvidenceIntegrity;\n\ttotalBytes: number;\n\ttotalChars: number;\n\t/** Inclusive start character index of the returned page. */\n\tstart: number;\n\t/** Exclusive end character index of the returned page. */\n\tend: number;\n\t/** Number of characters actually returned. */\n\tretrievedChars: number;\n\t/** True when more content exists after this page. */\n\thasMore: boolean;\n\t/**\n\t * The archive always stores the redacted representation, so retrieval only\n\t * ever returns the safe authoritative stored form — never the pre-redaction\n\t * secret material that was scrubbed at archive time.\n\t */\n\tredaction: \"archive-scrubbed\";\n}\n\nexport interface EvidenceRetrievalResult {\n\tok: boolean;\n\tstatus: EvidenceRetrievalStatus;\n\tevidenceId: string;\n\t/** Present only when status === \"ok\". */\n\tcontent?: string;\n\t/** Present only when status === \"ok\". */\n\tmetadata?: EvidenceRetrievalMetadata;\n\t/** Human/LLM-readable reason for non-ok results. */\n\treason?: string;\n}\n\nexport interface EvidenceRetrievalOptions {\n\t/** 0-based character offset. Default 0. */\n\toffset?: number;\n\t/** Maximum characters to return. Default DEFAULT_EVIDENCE_PAGE_CHARS, hard-capped at MAX_EVIDENCE_PAGE_CHARS. */\n\tlimit?: number;\n}\n\n/** Clamp a requested page limit to [1, MAX_EVIDENCE_PAGE_CHARS], defaulting to the bounded default. */\nexport function clampEvidencePageLimit(limit: number | undefined): number {\n\tif (limit === undefined || !Number.isFinite(limit) || limit <= 0) return DEFAULT_EVIDENCE_PAGE_CHARS;\n\treturn Math.max(1, Math.min(Math.floor(limit), MAX_EVIDENCE_PAGE_CHARS));\n}\n\n/**\n * Retrieve a bounded, integrity-verified page of an archived evidence artifact.\n *\n * Fails closed:\n *   - unknown id      -> status \"not-found\"\n *   - hash mismatch   -> status \"corrupt\" (no content returned)\n *   - offset out of   -> status \"invalid-range\"\n */\nexport async function retrieveEvidencePage(\n\tarchive: EvidenceArchive,\n\tevidenceId: string,\n\toptions: EvidenceRetrievalOptions = {},\n): Promise<EvidenceRetrievalResult> {\n\tconst record = await archive.load(evidenceId);\n\tif (!record) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tstatus: \"not-found\",\n\t\t\tevidenceId,\n\t\t\treason: `No archived evidence found for id \"${evidenceId}\".`,\n\t\t};\n\t}\n\n\tconst integrity: EvidenceIntegrity = hashContent(record.content) === record.contentHash ? \"verified\" : \"unverified\";\n\tif (integrity !== \"verified\") {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tstatus: \"corrupt\",\n\t\t\tevidenceId,\n\t\t\treason: `Integrity check failed for evidence \"${evidenceId}\": stored contentHash does not match the artifact.`,\n\t\t};\n\t}\n\n\tconst totalChars = record.content.length;\n\tconst offset = options.offset !== undefined && Number.isFinite(options.offset) ? Math.floor(options.offset) : 0;\n\tif (offset < 0 || offset >= totalChars) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tstatus: \"invalid-range\",\n\t\t\tevidenceId,\n\t\t\treason: `Offset ${offset} is outside artifact \"${evidenceId}\" (${totalChars} chars).`,\n\t\t};\n\t}\n\n\tconst limit = clampEvidencePageLimit(options.limit);\n\tconst start = offset;\n\tconst end = Math.min(totalChars, start + limit);\n\tconst page = record.content.slice(start, end);\n\n\treturn {\n\t\tok: true,\n\t\tstatus: \"ok\",\n\t\tevidenceId,\n\t\tcontent: page,\n\t\tmetadata: {\n\t\t\tevidenceId,\n\t\t\tkind: record.kind,\n\t\t\tsource: record.source,\n\t\t\tcontentHash: record.contentHash,\n\t\t\tintegrity,\n\t\t\ttotalBytes: record.contentBytes,\n\t\t\ttotalChars,\n\t\t\tstart,\n\t\t\tend,\n\t\t\tretrievedChars: page.length,\n\t\t\thasMore: end < totalChars,\n\t\t\tredaction: \"archive-scrubbed\",\n\t\t},\n\t};\n}\n"]}