/**
 * PNP Policy Source for the M8 engine
 * (see `.cursor/plans/m8-design.md` § 3 step 5 and § 5).
 *
 * This source applies the PNP/profile precedence rules as a `(candidates, pnpPolicyInputs) →
 * (refinedCandidates, perToolFlags, mandates, decisions)` function the
 * engine can call once per `decide(...)` request, with all results
 * routed through the unified `ToolPolicyProvenanceBuilder`.
 */
import type { AssessmentEntity, AssessmentItemRef } from "@pie-players/pie-players-shared/types";
import type { ToolRegistry } from "../../services/ToolRegistry.js";
import type { ToolPolicyResolutionDecision, ToolPolicySourceType } from "../core/provenance.js";
import type { PnpPolicySourceRule } from "../core/policy-source-tag.js";
/** Per-tool flags PNP/profile policy may attach to a surviving entry. */
export interface PnpPolicyToolFlags {
    /** PNP/profile policy mandates this tool (item or district `requiredTools`). */
    required: boolean;
    /** Student PNP marks this tool as a support (host UI cannot toggle off). */
    alwaysAvailable: boolean;
    /** Tool-specific settings derived from item / assessment settings. */
    settings?: unknown;
    /** Which PNP/profile rule contributed the surviving verdict. */
    rule: PnpPolicySourceRule;
    /** Source attribution for `ToolPolicyEntry.sources`. */
    sourceType: ToolPolicySourceType;
}
export interface PnpPolicyApplyArgs {
    assessment?: AssessmentEntity | null;
    currentItemRef?: AssessmentItemRef;
}
/**
 * Provenance event the engine should append to its builder. Pre-baked
 * here so the source has a single allocation pattern and the engine
 * keeps a uniform `addDecision(...)` shape.
 */
export interface PnpPolicyDecisionEvent {
    precedence: 1 | 2 | 3 | 4 | 5 | 6;
    rule: "district-block" | "test-admin-override" | "item-restriction" | "item-requirement" | "district-requirement" | "pnp-support" | "pnp-prohibited";
    featureId: string;
    action: ToolPolicyResolutionDecision["action"];
    sourceType: ToolPolicySourceType;
    reason: string;
    value?: unknown;
}
export interface PnpPolicyResult {
    /**
     * Tool IDs PNP/profile policy explicitly blocked. Engine removes these from the
     * candidate set in step 5.
     */
    blockedToolIds: Set<string>;
    /**
     * Tool IDs PNP/profile policy mandates (item or district `requiredTools`). Used
     * by the engine to detect `tool-policy.requiredToolBlocked`
     * diagnostics for tools removed by host policy.
     */
    mandatedToolIds: Set<string>;
    /**
     * Per-tool flags merged into surviving `ToolPolicyEntry`s.
     */
    perToolFlags: Map<string, PnpPolicyToolFlags>;
    /**
     * Decision log entries the engine must record. Order matches the
     * order rules fired internally (highest precedence first per
     * support id).
     */
    decisions: PnpPolicyDecisionEvent[];
    /** Configuration sources the engine should attach to its provenance. */
    sources: {
        assessment?: {
            id: string;
            name: string;
            config?: unknown;
        };
        student?: {
            id: string;
            name: string;
            config?: unknown;
        };
        item?: {
            id: string;
            name: string;
            config?: unknown;
        };
    };
}
export declare class PnpPolicySource {
    readonly id = "pnp";
    private readonly toolRegistry;
    constructor(toolRegistry: ToolRegistry);
    apply(args: PnpPolicyApplyArgs): PnpPolicyResult;
    private resolveSupport;
    /**
     * Map a QTI / PNP support id (e.g. `"calculator-basic"`) to the
     * registered tool id that owns it.
     *
     * Resolution rules:
     *
     *   1. **Multiple tools register the same support id:** the
     *      *first-registered* tool wins. `ToolRegistry.getToolsByPNPSupport`
     *      returns a `Set<string>` whose iteration order matches the
     *      `register(...)` insertion order, so the result is
     *      deterministic across runs but order-sensitive at registration
     *      time. This is an unusual configuration — the typical case is
     *      one tool per support id — but it is reachable when an
     *      integrator overrides a default tool with a replacement that
     *      claims the same `pnpSupportIds`. In that case the integrator
     *      should `unregister(...)` the default before registering the
     *      replacement.
     *
     *   2. **No tool registers the support id:** the support id is
     *      returned verbatim as the `featureId` for provenance trails
     *      and `ToolPolicyEntry.toolId`. This lets hosts use raw QTI
     *      strings for tools the registry does not (yet) carry without
     *      losing them in policy evaluation.
     *
     * `tests/policy/PnpPolicySource.test.ts` locks this mapping behavior.
     */
    private mapSupportToToolId;
    /**
     * Resolve tool-specific settings, item-level taking precedence over
     * assessment-level.
     *
     * Uses `??` (nullish-coalescing). Tool config values are typed `unknown` and may legitimately
     * be `false` / `0` / `""` (e.g. a tool whose canonical "off" config
     * is the literal `false`). `||` would treat those as missing and
     * silently fall through to the assessment-level config, masking the
     * authored item-level intent. `??` only falls through on
     * `null`/`undefined`, which matches the semantic of "value not
     * provided."
     */
    private resolveToolSettings;
}
