/** * apis.ax conformance API. * * apis.ax is the standards body: it PUBLISHES AXP — the Agent eXperience * Protocol (../PROTOCOL.md) — and its machine-readable conformance profile. It does NOT * grade — grading is delegated to **api.qa**, the independent verifier held * outside the building fleet's write access. This module therefore does not * reimplement any verification logic; it reuses api.qa's `verifyPinnedSpec` * against the published pinned spec. Reimplementing the verifier here would * defeat verifier-independence (the whole point of the split, ADR-0008). */ import { readFileSync } from 'node:fs' import { fileURLToPath } from 'node:url' import { dirname, join } from 'node:path' // Reuse the independent verifier. Do NOT reimplement it here. import { verifyPinnedSpec } from 'autonomous-qa' /** fetch-compatible seam (mirrors api.qa's http.Fetcher) for hermetic runs. */ export type Fetcher = (url: string, init?: RequestInit) => Promise const HERE = dirname(fileURLToPath(import.meta.url)) const PKG_ROOT = join(HERE, '..') export interface VerifiedBy { verifier: 'api.qa' check?: string pinnedRequirement?: string | string[] } export interface ConformanceClause { id: string clause: number normative: 'MUST' | 'SHOULD' | 'MAY' requirement: string verifiedBy: VerifiedBy } export interface ConformanceProfile { $type: 'ConformanceProfile' standard: string protocol: string version: string verifier: 'api.qa' spec: string clauses: ConformanceClause[] } /** The published conformance profile (parsed). */ export function conformanceProfile(): ConformanceProfile { return JSON.parse(readFileSync(join(PKG_ROOT, 'conformance', 'profile.json'), 'utf8')) } /** The published pinned spec TEXT (what api.qa hashes and runs). */ export function standardSpecText(): string { return readFileSync(join(PKG_ROOT, 'conformance', 'apis-ax-standard.spec.json'), 'utf8') } /** * The RATIFIED sha256 digest of the pinned spec — the anti-Goodhart pin. * * This is the sha256 of `apis-ax-standard.spec.json` as ratified. It is passed * to api.qa's `verifyPinnedSpec` as `expectedDigest`, so if the building fleet * edits its local copy of the spec to weaken the gate, verification THROWS * before a single probe fires — the verdict is bound to the digest, not to the * file on disk. Stored in `conformance/apis-ax-standard.digest.txt` so the CLI * and the code read the SAME pin. */ export function ratifiedDigest(): string { return readFileSync(join(PKG_ROOT, 'conformance', 'apis-ax-standard.digest.txt'), 'utf8').trim() } export interface ClauseResult { id: string clause: number normative: string requirement: string verifiedBy: VerifiedBy /** Requirement ids in the api.qa report this clause resolved to. */ resolvedFrom: string[] verdict: 'pass' | 'fail' } export interface ConformanceGrade { standard: string verifier: 'api.qa' target: string /** True iff api.qa returned passed:true against the pinned spec. */ passed: boolean /** Per-clause pass/fail, each derived from an independent api.qa result. */ clauses: ClauseResult[] /** The raw api.qa PinnedVerificationReport. */ report: Awaited> } export interface GradeOpts { /** Injected loopback fetcher for hermetic runs (tests / self-check). */ fetcher?: Fetcher mode?: 'remote' | 'local' seed?: number delayMs?: number allowPrivateTargets?: boolean /** * Attested (production/catalog admission) grading (ax-7x3). When true, * gradeConformance REFUSES the in-tree `ratifiedDigest()` and requires an * out-of-band `expectedDigest` supplied from outside the building fleet's * write access. The in-tree `conformance/apis-ax-standard.digest.txt` is a * hermetic-test convenience, not the production independence property. */ attested?: boolean /** Out-of-band pin for attested grading (required when `attested` is true). */ expectedDigest?: string } /** * Grade a target against the published standard, via api.qa. Returns the raw * verifier verdict plus a per-clause breakdown mapped through the conformance * profile. The verdict itself is api.qa's, not ours. */ export async function gradeConformance(target: string, opts: GradeOpts = {}): Promise { const specText = standardSpecText() const profile = conformanceProfile() // Attested (production/catalog admission) grading refuses the in-tree pin: // the digest must be supplied out-of-band, from outside the building fleet's // write access (ax-7x3). Default (hermetic/local) grading reads the in-tree // pin, exactly as before — backward compatible. const attested = opts.attested ?? false if (attested && !opts.expectedDigest) { throw new Error( 'attested gradeConformance refuses the in-tree ratifiedDigest(): supply an out-of-band expectedDigest. ' + 'The in-tree conformance/apis-ax-standard.digest.txt is a hermetic-test convenience, not the production pin.', ) } const report = await verifyPinnedSpec(target, specText, { mode: opts.mode ?? 'local', attested, seed: opts.seed, delayMs: opts.delayMs ?? 0, fetcher: opts.fetcher, allowPrivateTargets: opts.allowPrivateTargets ?? true, // The anti-Goodhart pin: if the spec text has been tampered with, api.qa // refuses to verify (throws) before any probe. Independence property. // Hermetic default: the in-tree pin. Attested: the injected out-of-band pin ONLY. expectedDigest: attested ? opts.expectedDigest : (opts.expectedDigest ?? ratifiedDigest()), }) const byId = new Map(report.requirements.map((r) => [r.id, r.verdict])) const clauses: ClauseResult[] = profile.clauses.map((c) => { const pinned = c.verifiedBy.pinnedRequirement const ids = pinned === undefined ? [] : Array.isArray(pinned) ? pinned : [pinned] // A clause passes iff every api.qa requirement it maps to passed. const verdicts = ids.map((id) => byId.get(id)) const verdict: 'pass' | 'fail' = ids.length > 0 && verdicts.every((v) => v === 'pass') ? 'pass' : 'fail' return { id: c.id, clause: c.clause, normative: c.normative, requirement: c.requirement, verifiedBy: c.verifiedBy, resolvedFrom: ids, verdict, } }) return { standard: profile.protocol, verifier: 'api.qa', target: report.target, passed: report.passed, clauses, report, } }