/**
 * Tool Policy Provenance (M8 — see `.cursor/plans/m8-design.md` § 4).
 *
 * Tracks decisions from every Pass-1 contributor: host placement, host policy,
 * provider veto, PNP/profile gates, and custom policy sources.
 */
/**
 * Rule vocabulary for tool policy decisions.
 */
export type ToolPolicyDecisionRule = "district-block" | "test-admin-override" | "item-restriction" | "item-requirement" | "district-requirement" | "pnp-support" | "pnp-prohibited" | "placement-membership" | "provider-disabled" | "host-allowlist" | "host-blocked" | "required-tool-blocked" | "custom-source" | "system-default";
export type ToolPolicySourceType = "organization" | "assessment" | "section" | "item" | "student" | "system" | "host" | "custom";
export interface ToolPolicyResolutionDecision {
    /** Monotonic step index across the entire decision log. */
    step: number;
    /**
     * Precedence level. PNP/profile rules use `1`–`6`; non-profile rules use `0`
     * for host-side gates or `7+` for custom sources that run after PNP/profile policy.
     */
    precedence: number;
    rule: ToolPolicyDecisionRule;
    /** Tool ID being resolved (post-PNP-support-mapping where applicable). */
    featureId: string;
    action: "block" | "enable" | "skip" | "advisory";
    source: {
        type: ToolPolicySourceType;
        id?: string;
        name?: string;
    };
    reason: string;
    value?: unknown;
    timestamp: Date;
}
export interface ToolPolicyFeatureTrail {
    featureId: string;
    finalState: "enabled" | "blocked" | "not-configured" | "advisory-only";
    winningDecision?: ToolPolicyResolutionDecision;
    allDecisions: ToolPolicyResolutionDecision[];
    explanation: string;
}
export interface ToolPolicyProvenance {
    contextId: string;
    resolvedAt: Date;
    sources: {
        organization?: {
            id: string;
            name: string;
            pnpDefaults?: unknown;
        };
        assessment?: {
            id: string;
            name: string;
            settings?: unknown;
        };
        section?: {
            id: string;
            title?: string;
            settings?: unknown;
        };
        item?: {
            id: string;
            name?: string;
            settings?: unknown;
        };
        student?: {
            id: string;
            pnpProfile?: unknown;
        };
        host?: {
            id: string;
            config?: unknown;
        };
    };
    features: Map<string, ToolPolicyFeatureTrail>;
    decisionLog: ToolPolicyResolutionDecision[];
    summary: {
        totalFeatures: number;
        enabled: number;
        blocked: number;
        notConfigured: number;
        bySource: Record<string, number>;
        byRule: Record<string, number>;
    };
}
interface AddDecisionParams {
    precedence: number;
    rule: ToolPolicyDecisionRule;
    featureId: string;
    action: ToolPolicyResolutionDecision["action"];
    sourceType: ToolPolicySourceType;
    sourceId?: string;
    sourceName?: string;
    reason: string;
    value?: unknown;
}
/**
 * Builder for `ToolPolicyProvenance`.
 */
export declare class ToolPolicyProvenanceBuilder {
    private provenance;
    private stepCounter;
    constructor(contextId: string);
    addSource(type: keyof ToolPolicyProvenance["sources"], data: {
        id: string;
        name?: string;
        config?: unknown;
    }): this;
    addDecision(params: AddDecisionParams): this;
    /**
     * Reconcile every feature's `finalState` against the post-pipeline
     * candidate set.
     *
     * The eager `finalState` updates inside `addDecision` track the
     * highest-precedence non-skip decision per feature, but a tool's
     * *actual* visibility is only known after step 6 of the
     * composition pipeline — earlier decisions can be reversed by
     * later host gates, PNP/profile gates, or custom sources. This method
     * walks every feature trail and rewrites `finalState` from the
     * final candidate set so callers can rely on
     * `provenance.features.get(toolId)?.finalState` as the canonical
     * "is this tool visible right now?" answer (M8 design § 4 + § 12).
     *
     * Semantics applied per feature:
     *   - In `survivingIds`                                 → "enabled"
     *   - Not in `survivingIds`, has any non-skip decision  → "blocked"
     *   - Not in `survivingIds`, only advisory decisions    → "advisory-only"
     *   - Otherwise                                         → "not-configured"
     *
     * Surviving features without any logged decisions get a synthetic
     * "enabled" trail so the provenance is dense enough for hosts that
     * iterate `provenance.features` to find the visible set.
     */
    reconcileFinalStates(survivingIds: ReadonlySet<string>): this;
    build(): ToolPolicyProvenance;
}
export {};
