"use strict";
/**
 * Producer registry — the single canonical home for everything that
 * turns analyzer output into `BaselineEntry`s.
 *
 * # Why this exists (CLAUDE.md Rule 10)
 *
 * The baseline file is the durable contract the guardrail check
 * reads. Every analyzer that surfaces per-finding output MUST flow
 * through a registered producer so guardrails don't silently miss
 * its findings. Without the registry, adding a new analyzer means
 * remembering to also edit `create.ts` orchestration — easy to
 * forget, and the bug is invisible (the guardrail check passes even
 * when a new finding kind is silently bypassed).
 *
 * With the registry:
 *   - Adding a new analyzer is a one-line `PRODUCERS.push(...)`.
 *   - The orchestrator iterates the registry — no per-producer
 *     `findings.push(...)` calls to forget.
 *   - A contract test asserts every `IdentityInput` discriminant
 *     kind is either contributed by a registered producer OR
 *     listed in `DEFERRED_KINDS` with explicit rationale.
 *   - A synthetic-producer playbook test asserts the orchestrator
 *     stays registry-driven (adding a fake producer to the
 *     registry makes its entries appear in the baseline file
 *     without any edits to the orchestrator).
 *
 * # Producer contract
 *
 * Each producer:
 *   1. Declares the identity kinds it contributes via `contributes`.
 *   2. Reads from the shared `ProducerContext` (gathered once by
 *      the orchestrator so multiple producers don't re-shell the
 *      same analyzer).
 *   3. Returns `BaselineEntry[]` — pure or near-pure, depending on
 *      whether content-hash stamping is needed.
 *
 * # Adding a new identity kind
 *
 *   1. Add the discriminant to `IdentityInput` in `types.ts`.
 *   2. Add the case branch in `identityFor`.
 *   3. EITHER add a new producer here (or extend an existing one)
 *      so `contributes` covers the new kind, OR add the kind to
 *      `DEFERRED_KINDS` with rationale + landing phase.
 *   4. Add a fixture row in `test/baseline/finding-identity.test.ts`
 *      (Rule 9 / per-kind fixture contract).
 *
 * The contract test enforces steps 3 + 4 at runtime; the
 * exhaustive switch in `identityFor` enforces step 2 at compile
 * time. The result: no new identity kind can land in a way that
 * silently bypasses guardrails.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.PRODUCERS = exports.DEFERRED_KINDS = void 0;
exports.runProducers = runProducers;
exports.wiredKinds = wiredKinds;
const health_1 = require("./health");
const quality_1 = require("./quality");
const secret_hmac_1 = require("./secret-hmac");
const security_1 = require("./security");
const stale_allow_1 = require("./stale-allow");
const tests_1 = require("./tests");
/**
 * Identity kinds declared in `IdentityInput` but not yet wired by
 * any producer. Each entry MUST carry a `reason` (what blocks the
 * producer today) and `landingPhase` (when we intend to wire it).
 * The contract test asserts:
 *
 *   - Every kind appearing here is NOT contributed by any
 *     registered producer (no double-counting).
 *   - Every `IdentityKind` is either contributed OR in this map.
 *
 * Adding a new identity kind without wiring a producer requires
 * adding an entry here — the deferral becomes architecturally
 * explicit rather than silently invisible.
 */
exports.DEFERRED_KINDS = Object.freeze({
    'god-file': {
        reason: 'graphify Python script does not yet surface per-file complexity offenders; ' +
            'QualityMetrics.topGodFiles is forward-declared but unpopulated. ' +
            'Substitute: large-file (>500 lines) overlaps the same files ~80%+ of the time.',
        landingPhase: '2.6 / Phase 10s.2 (graphify-symbols expansion)',
    },
    hygiene: {
        reason: 'gatherHygieneMarkers emits aggregate counts, not per-occurrence positions; ' +
            'extending to surface Array<{file, line, marker}> is a small gather refactor. ' +
            'Substitute: aggregate counts feed the Quality dimension score; ' +
            'newSevereQualityIssueInChangedFiles block rule catches high-severity overlap.',
        landingPhase: 'Phase 5 (pre-launch polish)',
    },
    'coverage-gap': {
        reason: 'per-pack coverage adapters do not yet surface uncovered symbol ranges. ' +
            'Five of eight packs (typescript / java / kotlin / ruby / go) land in ' +
            'Phase 3.5 inside 2.5; remaining three (python / csharp / rust) decided ' +
            'mid-Phase-3.5 based on adapter complexity. ' +
            'Substitute: test-gap covers file-level untested; new uncovered functions ' +
            'inside an already-tested file remain invisible until Phase 3.5 lands.',
        landingPhase: 'Phase 3.5 (5 packs) / 2.6 (remaining)',
    },
});
// ─── Producer module wrappers ─────────────────────────────────────────────
// Each wraps a producer module's pure function with the registry's
// `BaselineProducer` shape. Kept in this file (rather than alongside
// each producer module) so the registry stays the single discovery
// surface — readers see every wired producer + every deferral in
// one place.
const SECURITY_PRODUCER = {
    name: 'security',
    contributes: ['secret', 'code', 'config', 'dep-vuln'],
    produce(ctx) {
        const aggregate = ctx.analysisResult.capabilities.securityAggregate;
        if (!aggregate)
            return [];
        return (0, security_1.securityAggregateToBaselineEntries)(aggregate, {
            cwd: ctx.cwd,
            commitSha: ctx.commitSha || undefined,
        });
    },
};
const SECRET_HMAC_PRODUCER = {
    name: 'secret-hmac',
    contributes: ['secret-hmac'],
    produce(ctx) {
        return (0, secret_hmac_1.rawSecretsToBaselineEntries)({ rawSecrets: ctx.rawSecrets, salt: ctx.salt });
    },
};
const QUALITY_PRODUCER = {
    name: 'quality',
    contributes: ['duplication', 'stale-file'],
    produce(ctx) {
        return [
            ...(0, quality_1.duplicationToBaselineEntries)(ctx.analysisResult.capabilities.duplication),
            ...(0, quality_1.staleFilesToBaselineEntries)(ctx.hygiene.staleFiles),
        ];
    },
};
const HEALTH_PRODUCER = {
    name: 'health',
    contributes: ['large-file'],
    produce(ctx) {
        return (0, health_1.largeFilesToBaselineEntries)(ctx.analysisResult.metrics);
    },
};
const TESTS_PRODUCER = {
    name: 'tests',
    contributes: ['test-gap', 'test-file-degradation'],
    produce(ctx) {
        return (0, tests_1.testGapsToBaselineEntries)(ctx.testGapsReport);
    },
};
const STALE_ALLOW_PRODUCER = {
    name: 'stale-allow',
    contributes: ['stale-allow'],
    produce(ctx) {
        return (0, stale_allow_1.staleAllowToBaselineEntries)({
            annotations: ctx.inlineAllowlistAnnotations,
            aggregate: ctx.analysisResult.capabilities.securityAggregate ?? null,
        });
    },
};
/**
 * The canonical producer list. Order is preserved in baseline-file
 * output for deterministic diffs; adding a new producer appends
 * here and updates the contract-test expectations.
 *
 * Mutable for the synthetic-producer playbook test: the test
 * substitutes a wrapped registry rather than mutating PRODUCERS
 * directly. Callers MUST treat this as immutable.
 */
exports.PRODUCERS = Object.freeze([
    SECURITY_PRODUCER,
    SECRET_HMAC_PRODUCER,
    QUALITY_PRODUCER,
    HEALTH_PRODUCER,
    TESTS_PRODUCER,
    STALE_ALLOW_PRODUCER,
]);
/**
 * Run every producer in `producers` against the shared context and
 * flatten the result. The orchestrator calls this with `PRODUCERS`
 * for production use; the playbook test calls it with an extended
 * list to verify synthetic producers flow through.
 */
function runProducers(ctx, producers = exports.PRODUCERS) {
    const out = [];
    for (const producer of producers) {
        out.push(...producer.produce(ctx));
    }
    return out;
}
/**
 * Every kind currently contributed by some producer in `producers`.
 * Convenience used by the contract test + by the orchestrator for
 * logging "this run produced entries across N kinds."
 */
function wiredKinds(producers = exports.PRODUCERS) {
    const out = new Set();
    for (const p of producers)
        for (const k of p.contributes)
            out.add(k);
    return out;
}
//# sourceMappingURL=index.js.map