import { z } from 'zod'; /** * Stage 4 outcome literals serialized into `.totem/verification-outcomes.json` * (mmnto-ai/totem#1684, ADR-091 § Bootstrap CI-first). Mirrors the * `Stage4Outcome` type from `stage4-verifier.ts` exactly so the storage * vocabulary matches the runtime type and we avoid a translation layer that * would drift on Stage 4 evolution. * * The `_OutcomeAlignment` type below enforces the mirror at compile time — * if either side adds, drops, or renames a literal, the assertion below * fails the build before drift can land in the corpus. */ export declare const Stage4OutcomeStored: z.ZodEnum<["no-matches", "out-of-scope", "in-scope-bad-example", "candidate-debt"]>; /** * One verification record per pack-installed rule (keyed by `lessonHash` in * the file-level record). Persisted across lint runs so subsequent passes * skip re-verification when the rule's content hash matches a recorded * outcome. */ export declare const VerificationOutcomeEntrySchema: z.ZodObject<{ /** * `lessonHash` of the rule the outcome was recorded against. Persisted * inside the entry as well as serving as the file-level record key so a * tampered key (key/value mismatch) can be detected on read. */ ruleHash: z.ZodString; /** ISO-8601 timestamp of when the verifier produced the outcome. */ verifiedAt: z.ZodString; /** The terminal Stage 4 outcome that was recorded. */ outcome: z.ZodEnum<["no-matches", "out-of-scope", "in-scope-bad-example", "candidate-debt"]>; /** Repo-relative paths of baseline-scoped files where the rule fired. */ baselineMatches: z.ZodDefault>; /** Repo-relative paths of in-scope files where the rule fired. */ inScopeMatches: z.ZodDefault>; /** * In-scope match lines that did not match the `badExample` shape — the * Candidate Debt evidence carried forward to the `totem doctor` UX * surface in mmnto-ai/totem#1685. Empty unless `outcome === 'candidate-debt'`. */ candidateDebtLines: z.ZodDefault>; }, "strip", z.ZodTypeAny, { ruleHash: string; outcome: "out-of-scope" | "no-matches" | "in-scope-bad-example" | "candidate-debt"; baselineMatches: string[]; inScopeMatches: string[]; candidateDebtLines: string[]; verifiedAt: string; }, { ruleHash: string; outcome: "out-of-scope" | "no-matches" | "in-scope-bad-example" | "candidate-debt"; verifiedAt: string; baselineMatches?: string[] | undefined; inScopeMatches?: string[] | undefined; candidateDebtLines?: string[] | undefined; }>; /** * The on-disk shape of `.totem/verification-outcomes.json`. Wraps the * per-rule record in a versioned envelope so structural changes can break * the file forward without silent migration: a loader that sees an unknown * `version` treats the file as empty and re-verifies, instead of risking a * partial parse against a newer schema. */ export declare const VerificationOutcomesFileSchema: z.ZodObject<{ version: z.ZodDefault>; outcomes: z.ZodRecord; /** Repo-relative paths of baseline-scoped files where the rule fired. */ baselineMatches: z.ZodDefault>; /** Repo-relative paths of in-scope files where the rule fired. */ inScopeMatches: z.ZodDefault>; /** * In-scope match lines that did not match the `badExample` shape — the * Candidate Debt evidence carried forward to the `totem doctor` UX * surface in mmnto-ai/totem#1685. Empty unless `outcome === 'candidate-debt'`. */ candidateDebtLines: z.ZodDefault>; }, "strip", z.ZodTypeAny, { ruleHash: string; outcome: "out-of-scope" | "no-matches" | "in-scope-bad-example" | "candidate-debt"; baselineMatches: string[]; inScopeMatches: string[]; candidateDebtLines: string[]; verifiedAt: string; }, { ruleHash: string; outcome: "out-of-scope" | "no-matches" | "in-scope-bad-example" | "candidate-debt"; verifiedAt: string; baselineMatches?: string[] | undefined; inScopeMatches?: string[] | undefined; candidateDebtLines?: string[] | undefined; }>>; }, "strip", z.ZodTypeAny, { version: 1; outcomes: Record; }, { outcomes: Record; version?: 1 | undefined; }>; export type Stage4OutcomeStoredValue = z.infer; export type VerificationOutcomeEntry = z.infer; export type VerificationOutcomesFile = z.infer; /** * Convenience alias for the in-memory mapping of `lessonHash` to its recorded * verification outcome. The file-level wrapper holds the same record under * `outcomes`; this alias exists so call sites that operate on the mapping * directly (the first-lint promotion interceptor in particular) can carry * a focused type without re-derivation. Reserved by mmnto-ai/totem#1684 § * "Vocabulary alignment" — `VerificationOutcomesStore` is the canonical name * for the in-memory mapping. */ export type VerificationOutcomesStore = VerificationOutcomesFile['outcomes']; /** * Load the per-rule verification outcomes from a `verification-outcomes.json` * file. Returns an empty store when the file is missing, contains malformed * JSON, or fails schema validation — the corpus self-heals on the next * write. The interceptor that wrote the corrupt file (or a future pass with * a refreshed schema) will overwrite it on the next promotion run, so the * cache state cannot wedge. * * Invariant: schema-version mismatch is treated as "no outcomes recorded" * rather than attempted migration. A v2 file read by a v1 loader returns * an empty store and warns; the next write produces a valid v1 file. */ export declare function readVerificationOutcomes(filePath: string, onWarn?: (msg: string) => void): VerificationOutcomesStore; /** * Persist the per-rule verification outcomes to disk via temp-file + * atomic rename, so a concurrent CI lint pass that interrupts mid-write * leaves the prior valid file intact rather than producing a truncated * partial-write that the next loader would reject. * * Output is canonicalized (recursive object-key sort) before serialization * so two lint passes that produce the same outcomes write byte-identical * files — Invariant #11 in the design doc, which keeps consumer repos * from seeing phantom diffs on every CI run. */ export declare function writeVerificationOutcomes(filePath: string, outcomes: VerificationOutcomesStore): void; //# sourceMappingURL=verification-outcomes.d.ts.map