import type { BaselineAuthorization, BaselineVerificationResult } from "../baseline-evidence/verify.js"; import type { EffectiveOrgPolicy } from "../org-policy/effective.js"; import type { EccComponentId } from "./components.js"; import { type EccComponentProvenance } from "./materialization-receipt.js"; /** * F2: the policy's evidence-passed effective selection. * * Ruling 6 makes selection an intent stage: select, then evidence, then * install. This module is the resolver in between — it takes the org policy's * effective per-component selection (`governance.externalSelections`, carried * on `EffectiveOrgPolicy.externalSelections`) and the already-computed * evidence/vet state (`verifyBaselineComponents`'s `authorizations`/`held`), * and reports exactly which selected components are authorized to * materialize. * * A component that is selected but vet-blocked, or selected with no evidence * recorded at its pin, is never returned in `included` — the lifecycle's * input is the evidence-passed effective selection and nothing else — but it * is reported in `excluded` with its reason, so a caller can still show it: * visible and selectable, never materialized. * * `included` carries the id, authorization tuple, and provenance the * materialization engine's `EccMaterializationComponentInput` needs, copied * through unchanged. It deliberately omits `files`: mapping a component to * target-specific file content is the target adapter's job (F4), not this * resolver's, and this module never invents file content. A caller with a * target adapter attaches `files` to each entry to get a real * `EccMaterializationComponentInput`. */ export type EccSelectionExclusionReason = "vet-blocked" | "no-evidence" | "malformed-selection" | "malformed-evidence"; export interface EccSelectionExclusion { /** The raw selection id (`governance.externalSelections[].items[].id`). */ id: string; kind: string; framework: "ecc" | "superpowers"; reason: EccSelectionExclusionReason; /** Vet finding codes for a blocked component; empty for every other reason. */ findingCodes: readonly string[]; detail: string; } /** * The materialization engine's component input, minus `files` — see the * module header for why `files` is out of scope here. */ export interface EccEffectiveSelectionComponent { id: EccComponentId; authorization: BaselineAuthorization; provenance: EccComponentProvenance; } export type EccSelectionEvidence = Pick; export interface EccEffectiveSelectionResult { included: EccEffectiveSelectionComponent[]; excluded: EccSelectionExclusion[]; } /** * Resolve the policy's evidence-passed effective selection: filter * `policy.externalSelections` down to the components whose evidence/vet state * passed, carrying each one's authorization tuple and provenance through * unchanged. Everything else is reported in `excluded` with a reason — never * silently dropped and never silently materialized. * * Fails closed throughout. Three cases exclude a selected component: its * evidence is held (blocked or missing/mismatched at the pin); its evidence * state is self-contradictory (both an authorization AND a held record exist * for the same id — never resolved by guessing which is current); or the * selection entry itself cannot resolve to a component id and source path the * materialization engine accepts. An id absent from BOTH the authorized and * held evidence is treated the same as "no evidence at the pin" — evidence * that says nothing is never read as a pass. * * Accepted-with-conditions evidence (`authorization.effective === * "accepted-with-conditions"`) is included exactly like a plain pass: the * source's own vet pipeline (`verifyBaselineComponents`) already places it in * the same `authorizations` result as a pass — the raw blocked verdict stays * preserved on the authorization tuple, which this resolver carries through * unchanged — so treating it as anything other than evidence-passed here * would invent a second, stricter notion of "passed" the source data does not * express. */ export declare function resolveEccMaterializationSelection(policy: Pick, evidence: EccSelectionEvidence): EccEffectiveSelectionResult;