<?xml version="1.0" encoding="UTF-8"?>
<spec xmlns="https://vibevm.org/spec/1">
  <title id="root">CARD: scaffold-d-differential-oracle — Differential / Characterization Oracle</title>
  <status stage="spec" state="done"/>
  <p p="1"><fact id="reference-instance-note" status="impl/done">*Reference instance of the AI-Native Pattern Card format.*</fact></p>
  <p p="2"><fact id="demonstrates-all-three-bands" status="impl/done">*Demonstrates all three bands, especially the operational Band 3.*</fact></p>
  <p p="3"><fact id="card-is-beta" status="impl/done">*This card is itself BETA: its oracle-presence half ships (`cell-has-oracle`, mounted in `rust-ai-native-conform`), and its replacement-time checker `replacement-has-oracle` is specified and not yet implemented — see the @fact:CHECKER row.*</fact></p>
  <section id="band-one-identity" title="Band 1 — Identity &amp; Recognition">
    <p p="4"><fact id="CLASSIFICATION" status="impl/done">**Classification:** layer = E (Verification coupling); mechanism = scaffold class D.</fact></p>
    <p p="5"><fact id="INTENT" status="impl/done">**Intent:** When code is replaced or refactored, pin its observable behavior with a runnable check that compares the new implementation against the old one (differential) or against a captured baseline (characterization), so that a reader — especially a weak one — can change code freely and receive a pass/fail signal on whether behavior moved.</fact></p>
    <p p="6"><fact id="ALSO-KNOWN-AS" status="spec/done">**Also Known As:** golden test; snapshot test; characterization test (Feathers); approval test; back-to-back test; differential testing; oracle test.</fact></p>
    <p p="7"><fact id="applicability-recognition-lead" status="impl/done">**Applicability / Recognition:** Apply when ANY of these signals are present —</fact></p>
    <list ordered="false" p="8">
      <item><fact id="SIGNAL-CELL-IS-BEING-REPLACED" status="impl/done">a cell is being *replaced* or its internals *rewritten* while its contract is meant to stay fixed (the replacement protocol, R-040);</fact></item>
      <item><fact id="SIGNAL-LEGACY-BEHAVIOR-IS-UNDERSTOOD-BY-NOBODY" status="impl/done">legacy behavior exists that nobody fully understands but must be preserved (no spec, only observed behavior);</fact></item>
      <item><fact id="SIGNAL-REFACTOR-SPANS-MULTIPLE-FILES" status="impl/done">a refactor spans multiple files and the reader cannot prove by inspection that behavior is unchanged (the Rust multi-file-edit failure mode, R2C-006);</fact></item>
      <item><fact id="SIGNAL-WEAK-AGENT-NEEDS-A-SAFETY-NET" status="impl/done">a weak agent is assigned a modification task and needs a safety net it cannot derive itself.</fact></item>
    </list>
    <p p="9"><fact id="DETECTOR-SEED" status="impl/done">*Detector seed:* a diff that modifies the body of an item carrying `#[spec(implements …)]` without a corresponding oracle artifact in the cell's test module → recognition fires.</fact></p>
  </section>
  <section id="band-two-justification" title="Band 2 — Justification &amp; Tradeoffs">
    <p p="10"><fact id="MOTIVATION" status="spec/done">**Motivation:** A Qwen-32B-class agent is asked to optimize a parser cell authored by Opus. It rewrites the hot loop. By inspection, neither the agent nor a fast human reviewer can be sure the 200-line change preserved behavior across edge cases. With a differential oracle — proptest feeding identical random inputs to `old_parse` and `new_parse` and asserting equal outputs — the agent gets an immediate, mechanical verdict: behavior held, or here is a minimized counterexample. The expensive cognition ("what are all the edge cases?") was materialized once, by the author, as a runnable harness; the weak agent consumes the verdict instead of re-deriving the edge-case analysis.</fact></p>
    <p p="11"><fact id="structure-and-participants-lead" status="impl/done">**Structure &amp; Participants:**</fact></p>
    <list ordered="false" p="12">
      <item><fact id="PARTICIPANT-SUBJECT-OLD" status="impl/done">*Subject-old* — the prior implementation (kept temporarily, or captured as goldens).</fact></item>
      <item><fact id="PARTICIPANT-SUBJECT-NEW" status="impl/done">*Subject-new* — the replacement.</fact></item>
      <item><fact id="PARTICIPANT-INPUT-SOURCE" status="impl/done">*Input source* — a proptest strategy, a fuzz corpus, or a recorded production-input set.</fact></item>
      <item><fact id="PARTICIPANT-COMPARATOR" status="impl/done">*Comparator* — the equality/equivalence predicate (exact, or domain-specific tolerance).</fact></item>
      <item><fact id="PARTICIPANT-ORACLE-HARNESS" status="impl/done">*Oracle harness* — the runnable test binding these, living in the cell's test module.</fact></item>
    </list>
    <p p="13"><fact id="COLLABORATIONS" status="impl/done">**Collaborations:** Pairs with Class B (typed builders shrink the input space the oracle must cover) and Class C (contracts define what "equivalent" means). Consumes Class E (the per-cell fast loop runs the oracle). Emits Class F diagnostics (a failure cites the violated REQ + the minimized counterexample). In a raid (§3 of the format), this card is the *differential-safety* gate that every behavior-changing card application must pass.</fact></p>
    <p p="14"><fact id="goals-and-non-goals-lead" status="impl/done">**Goals / Non-Goals:**</fact></p>
    <list ordered="false" p="15">
      <item><fact id="GOALS" status="impl/done">*Goals:* detect unintended behavior change during replacement/refactor; give weak readers a modification safety net; make "behavior preserved" a machine fact, not a claim.</fact></item>
      <item><fact id="NON-GOALS" status="impl/done">*Non-Goals:* NOT a correctness proof (it checks new-vs-old agreement, so it inherits any bug the old code had); NOT a substitute for the spec (it pins behavior, it does not justify it); NOT for greenfield code with no prior behavior to differ against.</fact></item>
    </list>
    <p p="16"><fact id="consequences-lead" status="impl/done">**Consequences:**</fact></p>
    <list ordered="false" p="17">
      <item><fact id="CONSEQUENCE-REFACTORING-BECOMES-SAFE" status="spec/done">(+) The reader can refactor aggressively; the net catches behavior drift mechanically.</fact></item>
      <item><fact id="CONSEQUENCE-IMPLEMENTATION-AND-CONTRACT-VARY-INDEPENDENTLY" status="spec/done">(+) Decouples "change the implementation" from "preserve the contract" — they vary independently.</fact></item>
      <item><fact id="CONSEQUENCE-STRATEGY-AND-COMPARATOR-COST-EFFORT" status="spec/done">(−) Cost: authoring the input strategy and comparator; maintaining goldens (which can rot — they must fail loudly when stale, never auto-update silently).</fact></item>
      <item><fact id="CONSEQUENCE-CHARACTERIZATION-ENSHRINES-CURRENT-BEHAVIOR" status="spec/done">(−) Characterization variant *enshrines current behavior including its bugs* — must be paired with a spec edge that says which behaviors are intentional vs incidental.</fact></item>
    </list>
    <p p="18"><fact id="alternatives-lead" status="impl/done">**Alternatives:**</fact></p>
    <list ordered="false" p="19">
      <item><fact id="ALTERNATIVE-FORMAL-PROOF" status="spec/done">*Full formal proof* (Kani/Creusot): stronger, but far costlier and not always tractable; choose for safety-critical invariants, not routine refactors.</fact></item>
      <item><fact id="ALTERNATIVE-MANUAL-REVIEW" status="spec/done">*Manual review:* the status quo; fails exactly where we need it (large multi-file Rust edits, weak readers).</fact></item>
      <item><fact id="ALTERNATIVE-FRESH-UNIT-TESTS" status="spec/done">*Unit tests written fresh:* test what the author thought to test; the differential oracle tests behavior the author never enumerated. Prefer differential when preserving opaque legacy behavior.</fact></item>
    </list>
    <p p="20"><fact id="risks-and-assumptions-lead" status="impl/done">**Risks &amp; Assumptions:**</fact></p>
    <list ordered="false" p="21">
      <item><fact id="RISK-OLD-IMPLEMENTATION-IS-AVAILABLE" status="spec/done">Assumes the old implementation is available or its behavior is capturable.</fact></item>
      <item><fact id="RISK-INPUTS-ARE-GENERATABLE-WITH-COVERAGE" status="spec/done">Assumes inputs are *generatable* with enough coverage; a weak input strategy gives false confidence.</fact></item>
      <item><fact id="RISK-SUNSET" status="spec/done">*Sunset condition:* if generation-time tools (`vibe-tcg`) plus full contracts ever make behavior-preservation statically provable for a class of cells, the differential oracle becomes redundant for that class and retires there.</fact></item>
      <item><fact id="RISK-TRANSFER" status="spec/done">Transfer risk: the value of executable scaffolds for *modification* (vs generation) is [E-mid], not yet measured on our codebase — this card is a prime R4 validation target.</fact></item>
    </list>
    <p p="22"><fact id="EVIDENCE-AND-TRANSFER-STRENGTH" status="spec/done">**Evidence &amp; Transfer-strength:** findings R-040 (replacement protocol, production), R2C-008 (+Lib executable scaffolds transformative for weak agents, benchmark), Feathers characterization method (production). Evidence class: production + benchmark. Transfer tag: **[E-mid]** (executable-scaffold value shown for generation; modification transfer to be validated in R4).</fact></p>
  </section>
  <section id="band-three-operation" title="Band 3 — Operation">
    <p p="23"><fact id="TRIGGER" status="impl/done">**Trigger:** WHEN a diff modifies the body of an item bearing `#[spec(implements …)]`, OR a cell is marked for replacement, OR a refactor touches &gt; 1 file in a cell whose contract is unchanged — THEN apply this card before merge.</fact></p>
    <p p="24"><fact id="MODE" status="impl/done">**Mode:** gate (runs at the cell's verification gate, not per keystroke).</fact></p>
    <p p="25"><fact id="routine-lead" status="impl/done">**Routine** (≤7 steps, each verifiable):</fact></p>
    <list ordered="true" p="26">
      <item><fact id="ROUTINE-IDENTIFY-THE-BEHAVIORAL-SURFACE" status="impl/done">Identify the behavioral surface to preserve (the seam's public functions).</fact></item>
      <item><fact id="ROUTINE-KEEP-OLD-REACHABLE" status="impl/done">Keep `old` reachable (rename to `old_*`, or capture goldens from it on a fixed input set).</fact></item>
      <item><fact id="ROUTINE-WRITE-THE-STRATEGY" status="impl/done">Write/extend a proptest strategy generating representative inputs for that surface.</fact></item>
      <item><fact id="ROUTINE-BIND-OLD-VS-NEW" status="impl/done">Bind `old` vs `new` (or `golden` vs `new`) under an equality/equivalence comparator.</fact></item>
      <item><fact id="ROUTINE-RUN-IN-THE-LOOP" status="impl/done">Run under the per-cell loop; on counterexample, fix `new` (NOT the oracle) until green.</fact></item>
      <item><fact id="ROUTINE-REMOVE-OLD-ONCE-GREEN" status="impl/done">Once green, remove `old` (or commit the goldens) and leave the oracle in the test module.</fact></item>
      <item><fact id="ROUTINE-CITE-THE-ORACLE" status="impl/done">Cite the oracle from the replacement's `#[spec(verifies …)]` edge.</fact></item>
    </list>
    <p p="27"><fact id="CHECKER" status="spec/done">**Checker:** conform T-sem rule `replacement-has-oracle` — flags any modification of a `#[spec(implements)]` item body whose cell lacks a differential/characterization test referencing it. Backed by `cargo test -p &lt;cell&gt;` running the oracle. *(Status: specified, NOT yet implemented in pilot → this card is BETA.)*</fact></p>
    <p p="28"><fact id="RAID-ROLE" status="impl/done">**Raid role:** layer = *behavior-preserving* phase (runs in any raid that rewrites implementations); order = applied AS A GATE around every other behavior-changing card (no ordering dependency of its own, but nothing that changes behavior may merge in a raid without it); batch = per-cell.</fact></p>
    <p p="29"><fact id="BUDGET" status="impl/done">**Budget:** competes with few rules (it is gate-time, not inline, so it does not crowd the edit-time active set); first-signal latency = one per-cell proptest run (target &lt; 60s; tune case count to stay in budget).</fact></p>
  </section>
</spec>
