Skip to main content

Cookpit v3.2 — Validation Criteria

The criteria a candidate v3.2 JSON-LD file must pass to be considered conformant. Each criterion references a rule from rules.md (or the v3.2 JSON Schema), declares severity, and describes the check.

The bundle accepts output from any LLM. Validation is the gate that tempers their enthusiasm: a file is accepted if and only if it passes the hard criteria below, regardless of which model produced it.

A file is valid v3.2 if and only if every criterion at severity hard passes. soft criteria are advisory: they surface in the validator report so the operator can decide whether to refine the prompt or accept the output. There is no third state.


How validation runs

Validation is stage 2 of the v3.2 lifecycle (see rules.md A0). The candidate file at the input is the AI Chef's stage-1 output: an unauthenticated (U) file carrying cookpit.attestation.status: "unauthenticated". Validation produces a verdict, not a transformed file. When the verdict is pass, the validator's stage-3 attestation step (see rules.md R) consumes the same file to produce the authenticated (A) form. Validation and attestation are conceptually distinct: the former checks, the latter certifies. A stage-1 input that already claims status: "authenticated" is malformed and is rejected at V-LIFECYCLE-AI-EMITS-U.

The validator executes the following phases in order. The first failure in phases 1–5 terminates the run and reports the failing criterion. Phase 6 collects soft findings without terminating.

  1. Parse. The candidate output is parsed as JSON.
  2. Schema. The parsed object is validated against schema/cookpit-cooking-file-v3.2.json.
  3. Lifecycle gating. The candidate's cookpit.attestation block is inspected. The block must be the unauthenticated form per rules.md R2. The filename's <status> segment must be U and must agree with the internal status (V-LIFECYCLE-AI-EMITS-U, V-ATTESTATION-CONSISTENCY).
  4. Hard rule checks. Every criterion of severity hard below is run.
  5. Source-faithfulness. The strict quantitative fingerprint is computed from the source recipe and compared against the file's cookpit.quantitativeFingerprint (V-FINGERPRINT-B). This is the stage-1 → stage-2 integrity check across the source-faithfulness boundary.
  6. Soft findings. Advisory checks run and are collected into the report.

The validator never modifies the file during validation. A repair loop may take the validator's report and re-prompt the AI Chef with "Fix only the following criteria: …", but repair is a separate concern from validation.

When every hard criterion in phases 1–5 passes, the validator's stage-3 attestation step runs:

  • Canonicalise the file body with cookpit.attestation.signature cleared per rules.md R5.
  • Compute the lowercase 64-hex SHA-256 file fingerprint.
  • Replace cookpit.attestation with the authenticated form (status, issuer, validatorVersion, issuedAt, canonicalization, keyId, fileFingerprint, audit summary, signature).
  • Sign the canonical bytes with the validator's private key.
  • Rename the file's <status> segment from U to A.
  • Return the authenticated file alongside the validation report.

Stage 3 is governed by the V-FILE-FINGERPRINT and V-SIGNATURE self-checks below: before returning, the validator re-verifies that the file it is about to emit verifies under R6. This guards against bugs in the stamping pipeline.


Severity

SeverityMeaning
hardMust pass for the file to be conformant v3.2.
softAdvisory; the file is still conformant if it fails, but the operator should review.

Statuses

Every criterion produces one of the following statuses. Hard criteria use the first five; soft criteria use pass, warn and info.

StatusSeverity (where used)Meaning
passhard, softCriterion ran and passed.
failhardCriterion ran and failed. Verdict → FAIL.
warnsoftSoft criterion produced a warning. Verdict unchanged.
infosoftSoft criterion produced informational data. Verdict unchanged.
deferredhardCriterion's productised implementation is not yet shipped. The validator cannot perform the check today; a future PR will. Distinct from skipped.
skippedhardCriterion needs an input the user did not supply (e.g. --source <pdf> for V-FINGERPRINT-B; --pub-key for V-SIGNATURE in default mode). Re-run with the input to clear.
n/ahardCriterion does not apply to this file at this lifecycle stage (e.g. V-FILE-FINGERPRINT on a U file; V-INGREDIENT-ALTERNATIVE when no alternatives are declared).

The verdict line is PASS when there are zero fail statuses and FAIL otherwise. deferred and skipped statuses do NOT change the verdict, but they are surfaced in the report's footer so a reader can tell at a glance how many hard checks ran versus did not. A "PASS verdict with N hard checks deferred or skipped" is structurally different from "PASS verdict with all hard checks run and passed"; the validator's footer makes the distinction unambiguous.


Criteria

V-PARSE — JSON parse (hard)

The candidate output parses as a single JSON object. Multiple top-level values, trailing commentary, markdown code fences, or non-JSON output all fail this check.

V-SCHEMA — JSON Schema (hard)

The parsed object validates against schema/cookpit-cooking-file-v3.2.json. Schema errors are reported with their JSON pointer.

V-LIFECYCLE-AI-EMITS-U — stage-1 input shape (hard) — rules A0.1, R2, R4

The candidate file presented for validation MUST be a stage-1 AI Chef output:

  • cookpit.attestation is present.
  • cookpit.attestation.status equals "unauthenticated".
  • cookpit.attestation does NOT carry signature, fileFingerprint, issuer, keyId, validatorVersion, issuedAt or canonicalization.
  • The filename's <status> segment, when present, equals U.

A file that already claims status: "authenticated", or that carries any of the authenticated-only fields, is malformed. The validator refuses to re-validate an authenticated file; the user must strip the attestation block back to the unauthenticated form and resubmit (rules.md R8).

V-ATTESTATION-SHAPE — attestation block shape (hard) — rules R1, R2, R3

cookpit.attestation.status is one of "unauthenticated" or "authenticated". When status is "unauthenticated", the block carries no authenticated-only fields (per V-LIFECYCLE-AI-EMITS-U). When status is "authenticated", the block carries every required field listed in rules.md R3. Inconsistent or partial blocks are a hard failure.

V-ATTESTATION-CONSISTENCY — filename / status agreement (hard) — rules O1.2, R10

When the candidate is presented to the validator with a filename, the filename's <status> segment matches cookpit.attestation.status:

  • …cpt.U.jsonldstatus: "unauthenticated".
  • …cpt.A.jsonldstatus: "authenticated".

Disagreement is a hard failure. The filename remains decorative; the internal status remains the authoritative claim. The agreement check catches accidental renames and tampering attempts that flip the filename without producing a matching internal block.

V-IDENTITY-A — @type and version (hard) — rules B1, B2

@type includes both Recipe and cookpit:CookingFile, and cookpit.version equals 3.2.0.

V-IDENTITY-B — file id (hard) — rules B4, G1, G2

cookpit.id matches ^f[0-9a-f]{10}$.

V-IDENTITY-C — courses and difficulty (hard) — rules B5, B6

cookpit.courses is non-empty, has no duplicates, has at most three entries, and is a subset of [starter, main, dessert]. cookpit.difficulty is one of easy, medium, hard, expert.

V-DURATION-A — phase nominal durations (hard) — rules C2, C4, Q1, Q3

For every declared phase (cookpit.prepCook, cookpit.preCook, cookpit.liveCook), the phase's nominalDuration matches ^[0-9]{2}:[0-9]{2}:[0-9]{2}$. cookpit.liveCook is required; prepCook and preCook are optional. cookpit.orchestration.timingBasis is cookTime. prepHandling is preStartChecklist. runtimeOverruns is appOwned.

V-DURATION-B — phase-sum vs source (soft) — rule C2

When cookpit.sourceTiming.cookTime is present as ISO 8601 (PT…), the ISO duration parses to the same HH:MM:SS as the SUM of all declared phases' nominalDuration (or, for ranges in cookTimeText, to the chosen composition per C3). A mismatch suggests the phase decomposition was not source-derived.

V-LANE-MODEL — fixed lane model (hard) — rule D1

cookpit.laneModel is the fixed primary/secondary/tertiary block defined in the v3.2 spec. The block is compared by structural equivalence (lanes, seconds, scopes, roles, default sounds), not by JSON byte equality.

V-LANE-SCOPE — lane scope per course (hard) — rules D2, D3, D4

Every task on A0 has kind: "alarm". Every task on S1/S2/S3 has course: "starter". Every task on M1/M2/M3 has course: "main". Every task on D1/D2/D3 has course: "dessert". Tasks on secondary or tertiary lanes (S2/S3/M2/M3/D2/D3) appear only when at least one other task on the same course has a different lane in the same minute (i.e. there is a real parallel workstream).

V-LANE-SECONDS — seconds match lane (hard) — rule D5

For every task, the seconds component of time equals the canonical second of its lane: A0=:00, S1=:15, S2=:20, S3=:25, M1=:30, M2=:35, M3=:40, D1=:45, D2=:50, D3=:55.

V-ALARMS — required global alarms per phase (hard) — rules E1, E2, E3, E5

For each declared phase, that phase's tasks[] contains exactly one alarm at 00:00:00.A0 and exactly one alarm at the phase's nominalDuration on A0. When the phase's nominalDuration is at least 00:10:00, exactly one alarm at (nominalDuration − 10 minutes).A0 exists in that phase. Every A0 task has kind: "alarm". A0 alarms do not require timingBasis.

V-ALARM-OPTIONAL — optional 5-minute alarm (soft) — rule E4

Within a phase, at most one (nominalDuration − 5 minutes).A0 alarm exists; if present it has kind: "alarm". Multiple 5-minute alarms in a single phase are a soft fail.

V-PREP — prep is untimed (hard) — rules F1, F2, F3

No task in tasks describes prep that the source labels as prep time. Pre-start preparation appears in cookpit.prerequisites. Live "during cook" prep that the source assigns to the cook window is allowed as a normal timed task. cookpit.orchestration.startEnabledBy is allPrerequisitesConfirmed.

V-IDS-FORMAT — id pattern (hard) — rules G1, G2

Every id in the file matches ^[a-z][0-9a-f]{10}$. The leading prefix matches the entity type per G2.

V-IDS-DETERMINISTIC — id derivation (hard) — rule G3

For every id in the file, the validator recomputes the deterministic id from (entityType, canonicalContent, canonicalPosition) per the canonical generation profile and confirms it matches the id in the file. Mismatches indicate non-deterministic generation and are a hard fail.

V-IDS-UNIQUE — id uniqueness (hard) — rule G4

No two entities share the same id within the file.

V-REFS-CLOSED — resource closure (hard) — rules H1–H7, A2, Q5

Every cross-reference resolves to a declared entity of the matching type, with phase-scoping where applicable:

  • ingredientRefscookpit.ingredients[].id (must start with i);
  • equipmentRefscookpit.equipment[].id (must start with e);
  • utensilRefscookpit.utensils[].id (must start with u);
  • sundryRefscookpit.sundries[].id (must start with s);
  • task processRefs → a processes[].id declared IN THE SAME PHASE (must start with p); cross-phase processRefs are forbidden;
  • process startTask and endTask → a tasks[].id declared IN THE SAME PHASE (must start with t); cross-phase boundary tasks are forbidden;
  • hotspot taskRefs → any declared phase's tasks[].id (must start with t); hotspots are file-level metadata and may target any phase.

A reference whose target is missing, whose prefix mismatches the entity type, or which crosses a phase boundary against the rule above is a hard failure.

V-REFS-PHANTOM — no undeclared resources in actions (soft) — rule H8

Heuristic check: task action strings are scanned for mentions of common tools (thermometer, blender, scales, …) and the validator reports any mention whose corresponding declared resource list does not contain a plausible match. Heuristic only; the operator decides whether to act.

V-REFS-COVERAGE — declared resources are used (soft) — rule H9

Every declared resource is referenced by at least one task, process or prerequisite. Resources that are listed but never referenced are reported informationally.

V-TASKS-SHAPE — task required fields (hard) — rules I1, I2

Every task has id, time, kind, action. Every task whose kind is not alarm additionally has a non-empty timingBasis. kind is one of alarm, alert, update. Only alarm tasks appear on A0; alert and update tasks appear only on course lanes.

V-TASKS-TIME — task time format (hard) — rule I3

Every task time matches ^([0-9]{2}):([0-9]{2}):([0-9]{2})\.(A0|S[1-3]|M[1-3]|D[1-3])$.

V-TASKS-WITHIN — tasks fit within phase duration (hard) — rule I5

For every task, HH:MM:SS is less than or equal to its phase's nominalDuration. The single exception is the phase's time-up alarm, which equals the phase's nominalDuration exactly.

V-TASKS-ORDER — task ordering per phase (hard) — rule I6

Within each phase's tasks[], the array is sorted by time, ties broken by lane then id. Cross-phase ordering is not meaningful because each phase has its own clock.

V-TASKS-LANGUAGE — culinary language (soft) — rule I7

Task action strings do not contain UI verbs (tap, swipe, confirm, press, done, next, continue). Heuristic check; reported as soft so the operator can confirm wording quality without rejecting the file outright.

V-TIMING-BASIS — non-alarm tasks have a basis (hard) — rules I1, I8

Every non-alarm task has a timingBasis whose basis is one of sourceExactDuration, sourceRangeMinimum, sourceRangeTarget, sourceCookTimeEndpoint, sourceOrder, sourceMeanwhile, sourceOutcomeCue, sourceImpliedDeadline, canonicalProcessEstimate. The source field is a non-empty string. When basis is sourceImpliedDeadline, offsetFrom references an existing task id and offset is a negative ISO 8601 duration recording the prep duration that was deduced from the deadline.

V-TIMING-NONRANDOM — no cosmetic spacing (soft) — rules A1, I9

Heuristic check: task gaps are scanned for suspiciously regular spacing (e.g. every task placed exactly 30 seconds apart with no source-derived explanation). Suspicious patterns are reported soft so the operator can review the prompt's effectiveness.

V-PROCESSES — process consistency (hard) — rules J1, J2, J3, J4

Every process's startTask and endTask exist in the SAME phase's tasks[]. The interval between their time values, ignoring lane seconds, equals the process's duration.target parsed as ISO 8601. completion.type is one of timed, sensory, temperature, compound. Within a phase, processes are listed in the order their startTask occurs.

V-PHASES-PRESENT — phase declaration (hard) — rule Q1

cookpit.liveCook is required and is a phase block with label, nominalDuration, tasks[] and optional processes[] and completion. cookpit.prepCook and cookpit.preCook are optional; when present they have the same shape. No other phase keys are permitted.

V-PHASE-IDS — phase identity (hard) — rule Q2

cookpit.prepCook.id, when present, matches ^y[0-9a-f]{10}$. cookpit.preCook.id, when present, matches ^z[0-9a-f]{10}$. cookpit.liveCook does NOT carry an id field; its identity is the file's cookpit.id.

V-PHASE-CONTINUITY — phase shape (hard) — rule Q3

For every declared phase: label is a non-empty string, nominalDuration is HH:MM:SS, tasks[] is non-empty. processes[] (when present) lives inside the phase block — there are no top-level processes outside any phase.

V-PHASE-ORDER — phase document order (soft) — rule Q4

When more than one phase is declared, their JSON-document order in cookpit follows the fixed canonical layout: prepCook, preCook, liveCook. This is a human-readability convention, not a runtime sequencing claim — at runtime prepCook and preCook are independent (they may run concurrently or sequentially; the file does not encode that choice), and liveCook is strictly downstream of both. Out-of-order document layout is a soft warning so the file remains visually consistent with the rest of the corpus.

V-METHOD-ORDER — method order preservation (hard) — rule A1, A2

Tasks on each course lane appear in an order that is a topological extension of the source method order. The validator extracts numbered or sequential method steps from the source and confirms that the corresponding tasks in the same course do not invert the source order. Violations are hard failures.

V-SOURCE-COVERAGE — source durations covered (hard) — rule K1

Every numeric duration stated in the source method (e.g. "simmer for 20 minutes", "bake 25–30 minutes") is reflected in the plan by a process or by a task pair whose interval matches the stated duration (or its chosen range minimum per C3). Missing durations are hard failures.

V-SOURCE-TEMPS — temperatures and gas marks present (hard) — rule K1

Every temperature, oven setting, gas mark or numeric heat instruction in the source is present somewhere in the file (typically in a task action or in the relevant ingredient note). Omissions are hard failures.

V-FINGERPRINT-A — fingerprint shape (hard) — rules K3, K4, K5

cookpit.quantitativeFingerprint is present, has type: "strict", basis: "ingredients-and-method-active-numbers", normalization: "cookpit-active-number-sequence-v3.2.0", a sequence matching ^[0-9]+(-[0-9]+)*$, and a hash with algorithm: "sha256" and value matching ^[0-9a-f]{64}$.

V-FINGERPRINT-B — fingerprint matches source (hard) — rules K3–K5

The validator independently extracts the active-number sequence from the source recipe per the canonical normalization rules (canonical-fingerprint-normalisation.md, executable embodiment at scripts/lib/source_tokeniser.py) and confirms:

  • the file's sequence equals the validator's computed sequence; and
  • the file's hash.value equals the SHA-256 hex digest of that sequence.

A mismatch on either is a hard failure (STATUS_FAIL). Without the --source <pdf|text> flag the criterion reports STATUS_SKIPPED — the validator cannot verify source faithfulness without the source. For an image-only PDF whose extracted text is empty, the criterion also reports STATUS_SKIPPED with detail explaining why.

V-NO-RUNTIME — forbidden runtime fields absent (hard) — rules L1, L2

The validator walks the entire JSON tree and confirms no field name from the forbidden list appears: urgency, priority, progress, completionState, checkboxState, actualStartTime, actualFinishTime, overdue, overdueState, focusTask, bannerColor, timerColor, overrunState, queuePosition, scrollPosition, plus any field whose name matches the heuristic pattern of runtime state (/(actual|current|live|overdue|focus|banner|timer|overrun|queue|scroll)[A-Z]/).

V-GENERATION — generation metadata (hard) — rules M1–M5

cookpit.generation is present with profile set, idPolicy = deterministic-type-prefixed-10-hex, timingPolicy = source-derived-deterministic-optimal, resourcePolicy = closed-world-declared-resources, and randomTimingAllowed = false.

V-OPTIONAL-COVERAGE — optional ingredients exempt from coverage (info) — rule N1

The soft resource-coverage check (V-REFS-COVERAGE) ignores ingredients marked optional: true. Optional ingredients with no task or process reference are reported informationally only.

V-EQUIPMENT-POWER — equipment power enum (hard) — rule N2

When present, equipment[].power is one of electric, gas, induction, none. Other values are a hard failure.

V-TASK-SOUND — task sound enum (hard) — rule N3

When present, task.sound is one of bell, klaxon, chime, tick.

V-PREREQ-LEADTIME — prerequisite leadTime is ISO 8601 (hard) — rule N4

When present, prerequisites.*[].leadTime matches an ISO 8601 duration (^P…).

V-PREREQ-INGREDIENT-REFS — prerequisite ingredient closure (hard) — rule N5

When prerequisites.*[].ingredientRefs is present, every id starts with i and exists in cookpit.ingredients[].id. Wrong-type or dangling refs are hard failures (same enforcement as V-REFS-CLOSED).

V-INGREDIENT-ALTERNATIVE — alternative shape (hard) — rule N6

When present, ingredient.alternative carries a non-empty text string and may carry quantity, unit, metricQuantity, metricUnit matching the same shapes used on the primary ingredient.

V-LEX-FORBIDDEN — forbidden lexicon terms (soft) — rule P8

Heuristic scan of every field in lexicon scope (per rule P2) for forbidden tokens drawn from lexicon.md §7.1 (hedgers), §7.2 (warmth and marketing), §7.3 (filler) and §7.4 (vague outcomes without sensory companion). Each hit is reported as a soft warning with the field path and the offending token. The validator does not strip or rewrite text.

V-LEX-IMPERATIVE — imperative form on actions (soft) — rules P3, I7

Heuristic check that every tasks[].action string and every prerequisite item carrying an active cooking action begins with an imperative verb. Strings beginning with second-person pronouns (you, your, you'll, you're) or with hedger constructions (make sure to, you'll want to, feel free to) are flagged as soft warnings.

V-LEX-SENSORY — sensory completion cues (soft) — rule P7

For every completion whose type is not timed, the cue (or each condition's cue for compound) is scanned for at least one sensory token from lexicon.md §6 or a clear synonym. Cues that contain only abstract outcomes (done, ready, right) without a sensory anchor are flagged as soft warnings.

V-LEX-PROCESS-LABEL — process-label grammar (soft) — rule P11

Heuristic check that every processes[].label reads as a short present-continuous noun phrase (e.g. ends in ing and is three to five words long, or is a recognised noun-phrase pattern). Imperative-form labels (Reduce the sauce) are flagged as soft warnings.

V-LEX-PERSONA-DRIFT — persona drift (soft) — rules P1, P8

Heuristic scan for register drift away from the rebel chef persona: brigade-formal language patterns (passive voice on cooking actions, "take care to", "in order to"), recipe-blog warmth (multiple warmth tokens in a single field), and headmaster register (make sure, you'd better, if you don't). Findings are reported as soft warnings to drive prompt refinement.

V-FILENAME — filename methodology consistency (soft) — rules O1–O8

When the candidate file is presented to the validator with a filename, the validator checks:

  • the filename matches the pattern <slug>.v3.2.cpt.<A|U>.jsonld;
  • the <slug> agrees with the slug derived from name per O2;
  • the <status> segment is A or U;
  • the <status> segment agrees with cookpit.attestation.status (this overlaps V-ATTESTATION-CONSISTENCY at hard severity; here it is reported as a soft warning when filename and content are absent or ambiguous);
  • cookpit.version starts with 3.2..

A filename without the <status> segment (legacy …cpt.jsonld form per O8) is reported as a soft warning recommending the explicit U flag, but does not prevent conformance. When no filename is available the criterion produces an info status only.

V-FILE-FINGERPRINT — file fingerprint consistency (hard, stage 3) — rule R5

For a file the validator is about to emit at stage 3, the cookpit.attestation.fileFingerprint MUST equal the SHA-256 digest of the canonicalised file body computed with both cookpit.attestation.signature AND cookpit.attestation.fileFingerprint cleared, using the canonicalisation profile named in cookpit.attestation.canonicalization.

This criterion is checked twice:

  • Pre-emit (validator self-check). Before returning a stage-3 authenticated file, the validator recomputes the fingerprint and confirms it matches the value it is about to embed. A mismatch indicates a bug in the stamping pipeline; the validator MUST refuse to emit.
  • Post-load (consumer-side). A stage-4 consumer recomputes the fingerprint on every load (R6 step 4). A mismatch indicates the file has been altered since stamping; the consumer MUST treat the file as untrusted (rules.md R7).

V-SIGNATURE — signature verification (hard, stage 3 / stage 4) — rules R3, R6

For a file claiming cookpit.attestation.status: "authenticated", the signature MUST verify under the public key identified by cookpit.attestation.keyId, over the canonical bytes produced by R5 (canonicalised file body with signature cleared).

This criterion is checked twice:

  • Pre-emit (validator self-check). Before returning a stage-3 authenticated file, the validator verifies its own signature over the canonical payload. Failure indicates a bug in the signing pipeline; the validator MUST refuse to emit.
  • Post-load (consumer-side). A stage-4 consumer verifies the signature on every load (R6 step 5) using its pinned public-key set. Verification failure is a hard rejection; the consumer MUST NOT silently downgrade the file to U semantics.

Stripping or substituting issuer, validatorVersion, issuedAt, canonicalization, keyId, fileFingerprint, or any field elsewhere in the file changes the canonical bytes and invalidates the signature.


Reporting

Each criterion produces one of:

  • pass
  • fail (with a JSON Pointer to the offending location and a one-line message)
  • warn (soft criteria only)
  • info (advisory observations the validator surfaces without judgement)

The full report is shaped as:

{
"version": "3.2.0",
"verdict": "pass | fail",
"summary": { "hardFailures": 0, "softWarnings": 0, "infos": 0 },
"criteria": [
{
"id": "V-LANE-SECONDS",
"rule": "D5",
"severity": "hard",
"status": "pass",
"details": []
}
]
}

verdict is pass if and only if every hard criterion is pass and the JSON Schema validation succeeded.


Determinism check (optional)

A determinism check is run separately from validation. It re-runs the generator with the same prompt, rules, schema and source recipe at low temperature n times (default 3) and compares the resulting files using a canonical diff. Stable runs produce byte-identical canonical output. Drift on any field other than free-form action wording is a soft warning; drift on times, ids, lanes, references, or the fingerprint is a hard failure of the determinism check (separate from per-file validation).


Conformance and authentication

A file is conformant v3.2 if and only if every hard criterion above is pass and the JSON Schema validates. soft warnings do not prevent conformance; they exist to drive prompt refinement and operator review.

A file is authenticated v3.2 if, in addition, it has been processed through stage-3 attestation (per rules.md R) by the canonical validator, verifies under V-FILE-FINGERPRINT and V-SIGNATURE against the published public key, carries cookpit.attestation.status: "authenticated", and uses the A filename flag. Authentication is a stronger property than conformance: every authenticated file is conformant, but a stage-1 AI output may be conformant (passes every hard criterion) without ever being authenticated, simply because it has not been put through the canonical validator's stage-3 stamp.