/** * Memoire Policy — one committed, versioned file (memoire.policy.json at the * repo root) that pins how strict every checker is, so a team's gate is * reproducible: same code + same policy = same findings, byte for byte. * * The policy hash is stamped into every report/diagnosis so a score is always * traceable to the thresholds that produced it — trend comparisons are only * meaningful between runs with the same policy hash. */ import type { AppQualityIssue, AppQualitySeverity } from "./engine.js"; export type PolicyPreset = "memi-recommended" | "strict" | "lenient"; export type FailOnSeverity = "critical" | "high" | "medium" | "low" | "none"; /** Tunable thresholds for the 13 deterministic app-quality rules. */ export interface PolicyThresholds { /** Below this many CSS variables (with real UI present) → system.tokens.missing. */ minCssVariables: number; /** More than this many unique raw hex colors promotes color.raw-hex from medium to high. */ rawHexHighThreshold: number; /** More than this many unique color utilities → color.scale-wide. */ maxColorUtilities: number; /** More than this many text size utilities → type.scale-wide. */ maxTextSizes: number; /** More than this many spacing utilities → spacing.scale-wide. */ maxSpacingUtilities: number; /** More than this many radius utilities → shape.radius-drift. */ maxRadiusUtilities: number; /** More than this many shadow utilities → depth.shadow-drift. */ maxShadowUtilities: number; /** More than this many arbitrary Tailwind values → maintainability.arbitrary-tailwind. */ maxArbitraryValues: number; } export interface PolicyRuleOverride { enabled?: boolean; severity?: AppQualitySeverity; } export interface PolicyGates { /** Severity threshold for exit-1 gating. CLI flags override this. */ failOn?: FailOnSeverity; /** Fail when the overall score drops below this. */ minScore?: number; /** Fail when the overall score drops more than this vs the last comparable run (used by --fail-on-regression). */ regressionBudget?: number; } /** Shape of memoire.policy.json as written by teams. All fields optional except schemaVersion. */ export interface MemoirePolicyFile { schemaVersion: 1; preset?: PolicyPreset; rules?: Record; thresholds?: Partial; gates?: PolicyGates; /** Severity for skill-compliance findings in the codegen gate: "critical" blocks, "warning" advises. */ skillComplianceSeverity?: "critical" | "warning"; } /** Fully-resolved policy every checker consumes. */ export interface ResolvedPolicy { schemaVersion: 1; preset: PolicyPreset; thresholds: PolicyThresholds; rules: Record; gates: Required> & Omit; skillComplianceSeverity: "critical" | "warning"; /** sha256 of the canonicalized resolved policy — stamped into reports. */ policyHash: string; /** Where this policy came from. */ source: "default" | "file"; path?: string; } export declare const POLICY_FILE_NAME = "memoire.policy.json"; export declare const DEFAULT_THRESHOLDS: PolicyThresholds; /** Resolve the default policy (no file present). */ export declare function defaultPolicy(): ResolvedPolicy; /** * Load memoire.policy.json from the project root, falling back to the default * policy when absent. A malformed policy file is an ERROR, not a silent * fallback — a team that committed a policy must never be silently ungated. */ export declare function loadPolicy(projectRoot: string): Promise; /** * Apply per-rule enablement and severity overrides to issues after they're * built. Disabled rules are removed; overridden severities replace the * engine's defaults. */ export declare function applyPolicyToIssues(issues: AppQualityIssue[], policy: ResolvedPolicy): AppQualityIssue[];