/** * Parity-manifest parser + config-path resolver (mmnto-ai/totem-strategy#448). * * The strategy repo owns `doctrine/parity-manifest.yaml` — the canonical, * machine-readable enumeration of cohort parity dimensions the `totem doctor * --parity` sensor checks for drift. This module is the SKELETON foundation: * it resolves the consumer-configured config-path to the manifest, parses + * Zod-validates the manifest at the system boundary, and maps the YAML * kebab-case keys to camelCase type fields. Per-contract drift detection * (per-dimension semantics against populated deps contracts) is OUT OF SCOPE * for this skeleton and lives in a follow-on. * * Design invariants: * - **Honest-absent (Tenet 14):** absence is never an error. Unconfigured → * a `not-configured` signal; configured-but-missing → a distinct * `not-found` signal. The resolver and parser NEVER throw for absence. * - **Zod at the boundary only:** the manifest is untrusted on-disk input; * Zod validates it once at the parse boundary, then callers work with * typed values. * - **schema-version gate:** the supported schema version is `1`. An * unsupported version does NOT parse contracts — the parser returns an * `unsupported-schema` signal so the doctor can refuse an incompatible * future shape (per the manifest's own header contract). * - **Pure:** no caching, no logging, no process state. Each call reads from * scratch. */ import { z } from 'zod'; /** * The single parity-manifest schema version this doctor build understands. * The manifest carries `schema-version: 1` as top-level lifecycle DATA so the * doctor can refuse to parse an incompatible future shape rather than * silently misread it. Bump in lockstep with a schema migration. */ export declare const SUPPORTED_PARITY_SCHEMA_VERSION = 1; /** * Tractability bounds what the doctor may assert about a contract (the * honest-absent rule): * - `mechanical` file-content / structural equality; doctor may * pass/warn/fail. * - `version-pinned` consumer pins a canonical version/SHA; doctor checks * pin currency only, never semantic content. * - `manual-attestation` genuinely semantic, no mechanical sensor; doctor * surfaces staleness only, NEVER fails. */ export declare const ParityTractabilitySchema: z.ZodEnum<["mechanical", "version-pinned", "manual-attestation"]>; export type ParityTractability = z.infer; /** * The §6(a)2 manifestation-ladder rungs THIS doctor build recognizes (best → * weakest). Deliberately NOT a Zod enum at the parse boundary: a closed enum * would fail validation MANIFEST-WIDE on one future rung value — the exact * total-outage class the 296 settlement (strategy#605) ruled additive fields * around (and the `last-attested` format-unvalidation precedent). Routing * narrows against this list; an unrecognized value stays verbatim on the row * and surfaces as a per-row line, never a dark manifest. */ export declare const PARITY_MANIFESTATIONS: readonly ["correct-by-construction", "managed-block", "version-pin", "value-equality", "content-hash", "attestation", "capability-probe", "declared"]; export type ParityManifestation = (typeof PARITY_MANIFESTATIONS)[number]; /** * The §6(a)3 sensed-state scale (post-#605: `declared` is the floor — the * minVersion-fallback honesty level). Ordered weakest → strongest so the * probe-vs-declared comparison (the green-halo cap, mmnto-ai/totem#2140) can * index into it. Same not-a-Zod-enum rationale as {@link PARITY_MANIFESTATIONS}. */ export declare const PARITY_SENSES: readonly ["declared", "present", "loaded", "usable"]; export type ParitySense = (typeof PARITY_SENSES)[number]; /** * One parsed parity contract — the camelCase public shape. Mirrors the #508 * manifest schema exactly. `blocking` is parsed but UNUSED in the skeleton * (per-contract gating is post-skeleton). `consumers` (absent = applies to all * cohort repos) supports ADR-102 per-consumer applicability so the doctor can * later distinguish drift from cohort-permits-absence. */ export interface ParityContract { id: string; dimension: string; /** `null` = no external canonical source. The ONLY ref the resolver touches. */ canonicalSource: string | null; /** Human-only context for `canonicalSource`. NEVER parsed as a ref. */ sourceNote?: string; detectionMethod: string; expectedValueOrDerivation: string; tractability: ParityTractability; trackingIssue: string; /** Optional human-readable title. */ title?: string; /** * Optional doctor exit-code policy flag. Parsed but UNUSED in the skeleton — * per-contract gating is deferred to a follow-on. */ blocking?: boolean; /** * Optional cohort applicability (which repos carry this contract). Absent = * applies to all cohort repos (ADR-102 per-consumer applicability). */ consumers?: string[]; /** * Optional explicit package identifier (mmnto-ai/totem-strategy#517) — the * machine-parseable `@mmnto/*` (or vendor) package name a version/vendor * contract pins. Preferred over the id-convention guess when present. */ package?: string; /** * Optional attestation marker (strategy#540 / mmnto-ai/totem#2125), present * on manual-attestation rows whose claim was actually reviewed. An * UNVALIDATED string carrying an intended ISO-8601 date — format is * deliberately not enforced at the schema boundary (see the raw-schema note: * rejection there is manifest-wide), so consumers must treat it as * render-only text. Absent = no citable attestation event (honest-absent — * the doctor renders "last attested: not recorded", never fabricates a date). */ lastAttested?: string; /** * Optional §6(a)2 manifestation-ladder rung (promoted field, strategy#606). * An open string, NOT `ParityManifestation` — recognized values are narrowed * at the ROUTING edge against {@link PARITY_MANIFESTATIONS}; an unrecognized * value rides verbatim so the router can surface it loudly per-row. */ manifestation?: string; /** * Optional §6(a)3 sensed-state level the row's detection-method probes BY * DESIGN (`declared|present|loaded|usable`). Open string for the same * reason as `manifestation`. Runtime degradation below this level is a * verdict-format concern (the declared-floor rendering), never a parse one. */ senses?: string; /** * Optional vendor surfaces this row manifests through (promoted field). * Normalized to an array — the manifest authors both `[claude, gemini]` * lists and bare strings. */ vendorAdapter?: string[]; /** Optional one-line legitimate role-based manifestation difference (§6(c)). */ repoRoleVariance?: string; /** * Optional Prop 296 §14 probe sub-class tag (`network-read-only`) on a * capability-probe row. Open string for the same manifest-wide-outage reason * as {@link manifestation}: an unrecognized value rides verbatim, never a * dark manifest. Forward-compat metadata — routing narrows on the contract-id * registry (CLI edge), not on this field. */ probeClass?: string; /** * Optional STRUCTURED canonical option sets on a `gh-project-vocabulary` row * (mmnto-ai/totem#2791): field name → its canonical option names, e.g. * `{ Status: [...], Priority: [...] }`. When present the detector reads the * canon from here; when absent it parses `expectedValueOrDerivation`'s prose * (`Field = a | b; …`). Narrowed per-row: every key non-empty, every value a * non-empty list of non-empty strings, else absent on that row. */ expectedOptionSets?: Record; } /** A fully parsed + validated parity manifest. */ export interface ParityManifest { schemaVersion: number; status: string; contracts: ParityContract[]; } /** * Honest-absent resolver outcome (discriminated union): * - `not-configured` — no `orient.parityManifest` set. Sensor → `skip`. * - `not-found` — configured, but no file at the resolved path. Sensor * → `warn` (distinct, actionable). * - `resolved` — a file exists at `path` (absolute). * * Resolution NEVER throws for absence — both absent states are first-class * return values, not exceptions. */ export type ParityManifestPathStatus = { status: 'not-configured'; } | { status: 'not-found'; path: string; } | { status: 'resolved'; path: string; }; /** * Resolve the configured `orient.parityManifest` config-path to an absolute * manifest path. Relative values anchor at `root` (the config/repo root); * absolute values are normalized as-is. Mirrors `resolveStrategyRoot`'s * relative-anchoring behavior so a deep cwd doesn't mis-anchor the value. * * @param configValue The raw `orient.parityManifest` config string (or undefined). * @param root The config/repo root to anchor relative values against. */ export declare function resolveParityManifestPath(configValue: string | undefined, root: string): ParityManifestPathStatus; /** * Honest-absent parse outcome (discriminated union): * - `unparseable` — invalid YAML or Zod-schema validation failure. * Sensor → `warn` (never crash). * - `unsupported-schema` — `schema-version` ≠ the supported version. * Contracts are NOT parsed. Sensor → `warn`. * - `ok` — a fully parsed + validated manifest. * * Parsing NEVER throws — every failure is a first-class return value so the * doctor pipeline degrades to a `warn` line rather than crashing (mirrors the * `findStaleRules` best-effort fallback idiom). */ export type ParityManifestParseResult = { status: 'unparseable'; reason: string; } | { status: 'unsupported-schema'; schemaVersion: number; } | { status: 'ok'; manifest: ParityManifest; }; /** * Parse raw YAML manifest text into a validated `ParityManifest`. * * Order of operations matters: the `schema-version` gate runs BEFORE the full * contract validation so an unsupported future shape is rejected with a clear * `unsupported-schema` signal rather than a confusing Zod failure against a * v1-shaped schema. Within v1, contracts are Zod-validated and the kebab-case * YAML keys are mapped to the camelCase `ParityContract` fields. */ export declare function parseParityManifest(yamlText: string): ParityManifestParseResult; /** * Convenience: resolve the config-path, read the file, and parse it in one * call. Returns the resolver's honest-absent signals (`not-configured` / * `not-found`) directly, or the parse result. Read failures degrade to an * `unparseable` parse result (never throws), so the doctor surface has a single * exhaustive switch to render against. */ export type ParityManifestLoadResult = { status: 'not-configured'; } | { status: 'not-found'; path: string; } | { status: 'unparseable'; reason: string; path: string; } | { status: 'unsupported-schema'; schemaVersion: number; path: string; } | { status: 'ok'; manifest: ParityManifest; path: string; }; export declare function loadParityManifest(configValue: string | undefined, root: string): ParityManifestLoadResult; //# sourceMappingURL=parity-manifest.d.ts.map