{
  "$type": "Suite",
  "name": "apis-vin",
  "version": "3",
  "description": "The apis.vin estate API acceptance suite — one document, two natures (api.qa/vitest@1): declarative endpoint rows over the pricing faces, the 402 offer boundary, the decode and record faces, the buy composition, the F&I in-force read, the branching /listings envelope, and the key-introspection refusal (GET/HEAD only, same-origin); plus one executable tests member carrying BOTH the public-contract green core (the AXP quartet shapes, decode determinism, the envelope law, the keyless A rung, anonymous POST /keys) AND the vision acceptance ratchet (real metering, auto.dev drop-in compat, the handoff triad, persona journeys, honesty) — the ratchet is red by design until the product satisfies it, so the hosted verdict honestly fails while the completeness debt stands. Deterministic against the sandbox.",
  "environments": {
    "sandbox": {
      "vars": {
        "baseUrl": "https://apis.vin"
      },
      "sandbox": true
    }
  },
  "requirements": [
    {
      "id": "pricing-metered-truth",
      "kind": "endpoint",
      "method": "GET",
      "path": "/pricing.json",
      "expect": {
        "status": 200,
        "contentTypeIncludes": "application/json",
        "paths": [
          {
            "path": "model",
            "equals": "metered"
          },
          {
            "path": "hardCeiling",
            "gte": 1
          },
          {
            "path": "binding",
            "equals": false
          }
        ]
      }
    },
    {
      "id": "pricing-md-face",
      "kind": "endpoint",
      "method": "GET",
      "path": "/pricing.md",
      "expect": {
        "status": 200,
        "contentTypeIncludes": "text/markdown"
      }
    },
    {
      "id": "pricing-html-face-retired",
      "kind": "endpoint",
      "method": "GET",
      "path": "/pricing.html",
      "expect": {
        "status": 404,
        "contentTypeIncludes": "application/json"
      }
    },
    {
      "id": "offer-402-boundary",
      "kind": "endpoint",
      "method": "GET",
      "path": "/offer",
      "expect": {
        "status": 402,
        "paths": [
          {
            "path": "type",
            "equals": "OFFER"
          },
          {
            "path": "price",
            "exists": true
          }
        ]
      }
    },
    {
      "id": "decode-ok-envelope",
      "kind": "endpoint",
      "method": "GET",
      "path": "/decode/JM3KFBXY1S0597748",
      "expect": {
        "status": 200,
        "paths": [
          {
            "path": "type",
            "equals": "OK"
          },
          {
            "path": "decode.vin",
            "equals": "JM3KFBXY1S0597748"
          },
          {
            "path": "provenance.environment",
            "exists": true
          }
        ]
      }
    },
    {
      "id": "record-face-json",
      "kind": "endpoint",
      "method": "GET",
      "path": "/JM3KFBXY1S0597748.json",
      "expect": {
        "status": 200,
        "contentTypeIncludes": "application/json",
        "paths": [
          {
            "path": "vin",
            "equals": "JM3KFBXY1S0597748"
          },
          {
            "path": "links.buy",
            "exists": true
          }
        ]
      }
    },
    {
      "id": "record-face-md",
      "kind": "endpoint",
      "method": "GET",
      "path": "/JM3KFBXY1S0597748.md",
      "expect": {
        "status": 200,
        "contentTypeIncludes": "text/markdown"
      }
    },
    {
      "id": "buy-composition",
      "kind": "endpoint",
      "method": "GET",
      "path": "/buy/JM3KFBXY1S0597748",
      "expect": {
        "status": 200,
        "paths": [
          {
            "path": "type",
            "equals": "OK"
          },
          {
            "path": "protection.packages.0.name",
            "equals": "Good"
          },
          {
            "path": "checklist.7.key",
            "equals": "confirm-delivery"
          }
        ]
      }
    },
    {
      "id": "fi-inforce-read",
      "kind": "endpoint",
      "method": "GET",
      "path": "/fi/inforce/JM3KFBXY1S0597748",
      "expect": {
        "status": 200,
        "paths": [
          {
            "path": "type",
            "equals": "OK"
          },
          {
            "path": "source",
            "oneOf": [
              "captured",
              "sandbox-exemplar"
            ]
          },
          {
            "path": "stateRules.0.cancellationFee",
            "exists": true
          }
        ]
      }
    },
    {
      "id": "listings-keyless-ok",
      "kind": "endpoint",
      "method": "GET",
      "path": "/listings",
      "expect": {
        "status": 200,
        "paths": [
          {
            "path": "type",
            "equals": "OK"
          }
        ]
      }
    },
    {
      "id": "listings-known-empty",
      "kind": "endpoint",
      "method": "GET",
      "path": "/listings?make=none",
      "expect": {
        "status": 200,
        "paths": [
          {
            "path": "type",
            "equals": "EMPTY"
          }
        ]
      }
    },
    {
      "id": "listings-blocked-scope",
      "kind": "endpoint",
      "method": "GET",
      "path": "/listings?scope=admin",
      "expect": {
        "status": 403,
        "paths": [
          {
            "path": "type",
            "equals": "BLOCKED"
          }
        ]
      }
    },
    {
      "id": "listings-over-ceiling-offer",
      "kind": "endpoint",
      "method": "GET",
      "path": "/listings?spend=26",
      "expect": {
        "status": 402,
        "paths": [
          {
            "path": "type",
            "equals": "OFFER"
          }
        ]
      }
    },
    {
      "id": "keys-me-blocked-keyless",
      "kind": "endpoint",
      "method": "GET",
      "path": "/keys/me",
      "expect": {
        "status": 401,
        "paths": [
          {
            "path": "type",
            "equals": "BLOCKED"
          }
        ]
      }
    }
  ],
  "tests": "/**\n * apis.vin — the served executable suite: the public-contract GREEN CORE\n * (verify/index.mjs) plus the vision acceptance RATCHET\n * (verify/acceptance.mjs), combined by scripts/gen-verify.mjs into one\n * api.qa/vitest@1 module. The ratchet is RED BY DESIGN against the live\n * origin: each build wave flips its own block green, and the hosted\n * verdict honestly fails until the product satisfies the whole suite.\n * Each source module's body rides in its own block scope; the dialect\n * imports are hoisted here.\n */\nimport { describe, it, expect } from 'vitest'\nimport { origin, vars } from 'suite:env'\n\n// ———— verify/index.mjs — the public-contract green core ————\n{\n/**\n * apis.vin — the executable public-contract suite (api.qa/vitest@1 dialect).\n *\n * ONE module, two runners (AXP A.8.6.2 local==hosted by construction):\n *   - plain local vitest runs it unchanged (test/verify-vitest.test.ts is the\n *     thin wrapper; vitest.config.ts resolves the suite:env specifier);\n *   - the api.qa/vitest@1 harness runs the SAME bytes — hosted in a Worker\n *     Loader isolate, locally through the autonomous-qa CLI vitest verb —\n *     digest-pinned as the tests member of the served /suite.json document.\n *\n * Dialect discipline (A.8.6.2): specifiers are closed to vitest and suite:env;\n * describe/it/expect core matchers + async only; no node built-ins, no\n * snapshots, no mocking, no dynamic module loading. Every assertion below\n * addresses a PUBLIC door the capability card declares live, in its keyless\n * A-rung form — except the one mutating verb, POST /keys, which the pinned\n * document consents to by declaring its sandbox environment sandbox=true\n * (A.8.6.4; anonymous self-service registration is the door's whole point).\n *\n * Determinism: reads are deterministic per VIN (the sandbox doctrine); the\n * one write mints a fresh anonymous key per run, asserted by shape, never by\n * value. No wall-clock, no randomness beyond the runner's seeded generator.\n */\n\n/** The demo-corpus VIN every read pins (deterministic sandbox record) — the\n * flagship fall-back subject (founder ruling 2026-08-17, vin-2sgm). */\nconst VIN = 'JM3KFBXY1S0597748'\n\nconst get = (path, headers) => fetch(`${origin}${path}`, headers ? { headers } : undefined)\n\ndescribe('the AXP quartet', () => {\n  it('serves the capability card at /.well-known/agents.json', async () => {\n    const res = await get('/.well-known/agents.json')\n    expect(res.status).toBe(200)\n    const card = await res.json()\n    expect(card.name).toBe('apis.vin')\n    expect(Array.isArray(card.interfaces.http)).toBe(true)\n    expect(card.interfaces.http.length).toBeGreaterThanOrEqual(1)\n    expect(card.probes.keyless.url).toBeDefined()\n    expect(card.links.pricing).toBeDefined()\n  })\n\n  it('serves an OpenAPI 3.1 contract with the declared doors', async () => {\n    const res = await get('/openapi.json')\n    expect(res.status).toBe(200)\n    const doc = await res.json()\n    expect(doc.openapi).toMatch(/^3\\.1/)\n    expect(Object.keys(doc.paths).length).toBeGreaterThanOrEqual(10)\n  })\n\n  it('posts metered pricing with a hard ceiling and honest binding', async () => {\n    const res = await get('/pricing.json')\n    expect(res.status).toBe(200)\n    const pricing = await res.json()\n    expect(pricing.model).toBe('metered')\n    expect(pricing.binding).toBe(false)\n    expect(pricing.hardCeiling).toBeGreaterThanOrEqual(1)\n    expect(pricing.statement).toBeDefined()\n  })\n\n  it('serves the agent front door at /llms.txt', async () => {\n    const res = await get('/llms.txt')\n    expect(res.status).toBe(200)\n    const body = await res.text()\n    expect(body).toContain('# apis.vin')\n    expect(body).toContain('/suite.json')\n  })\n})\n\ndescribe('the decode read is deterministic', () => {\n  it('answers the same record for the same VIN, twice', async () => {\n    const first = await (await get(`/decode/${VIN}`)).json()\n    const second = await (await get(`/decode/${VIN}`)).json()\n    expect(first.type).toBe('OK')\n    expect(first.decode.vin).toBe(VIN)\n    expect(typeof first.decode.year).toBe('number')\n    expect(first.provenance.environment).toBeDefined()\n    expect(second.decode).toEqual(first.decode)\n  })\n})\n\ndescribe('the envelope law — three emptinesses never blend', () => {\n  it('answers the keyless collection with a typed OK', async () => {\n    const res = await get('/listings')\n    expect(res.status).toBe(200)\n    const body = await res.json()\n    expect(body.type).toBe('OK')\n  })\n\n  it('answers a known-empty filter with a truthful EMPTY, not bare []', async () => {\n    const res = await get('/listings?make=none')\n    expect(res.status).toBe(200)\n    const body = await res.json()\n    expect(body.type).toBe('EMPTY')\n    expect(body.message).toBeDefined()\n  })\n\n  it('answers a reserved scope with a worded 403 BLOCKED', async () => {\n    const res = await get('/listings?scope=admin')\n    expect(res.status).toBe(403)\n    const body = await res.json()\n    expect(body.type).toBe('BLOCKED')\n    expect(body.reason).toBeDefined()\n  })\n\n  it('answers over-ceiling spend with a 402 OFFER carrying a price', async () => {\n    const res = await get('/listings?spend=26')\n    expect(res.status).toBe(402)\n    const body = await res.json()\n    expect(body.type).toBe('OFFER')\n    expect(body.price).toBeDefined()\n  })\n\n  it('never answers 406 — an unnegotiable Accept still gets a face', async () => {\n    const res = await get('/', { accept: 'application/xml' })\n    expect(res.status).toBe(200)\n    expect(res.headers.get('vary')).toContain('Accept')\n  })\n\n  it('mirrors GET with HEAD on the home door', async () => {\n    const res = await fetch(`${origin}/`, { method: 'HEAD' })\n    expect(res.status).toBe(200)\n    expect(await res.text()).toBe('')\n  })\n})\n\ndescribe('the keyless A rung answers in full', () => {\n  it('serves the record face for a VIN with its door links', async () => {\n    const res = await get(`/${VIN}.json`)\n    expect(res.status).toBe(200)\n    const record = await res.json()\n    expect(record.vin).toBe(VIN)\n    expect(record.links.buy).toBeDefined()\n  })\n\n  it('refuses keyless introspection with a typed 401 BLOCKED', async () => {\n    const res = await get('/keys/me')\n    expect(res.status).toBe(401)\n    const body = await res.json()\n    expect(body.type).toBe('BLOCKED')\n    expect(body.reason).toContain('POST /keys')\n  })\n})\n\ndescribe('anonymous self-service registration', () => {\n  it('mints a sandbox key at POST /keys — no email, no approval, no CAPTCHA', async () => {\n    const res = await fetch(`${origin}/keys`, { method: 'POST' })\n    expect(res.status).toBe(201)\n    const body = await res.json()\n    expect(body.type).toBe('OK')\n    expect(body.key).toMatch(/^vk_sandbox_/)\n    expect(body.account).toMatch(/^agent_anon_/)\n    expect(body.environment).toBe('sandbox')\n    expect(body.links.pricing).toBeDefined()\n  })\n})\n}\n\n// ———— verify/acceptance.mjs — the vision acceptance ratchet ————\n{\n/**\n * apis.vin — the VISION ACCEPTANCE SUITE (api.qa/vitest@1 dialect).\n *\n * THE COMPLETENESS RATCHET, authored RED-first (the founder's TDD ruling):\n * this module encodes the FULL ultimate vision as executable acceptance\n * criteria, so a perfect score is STRUCTURALLY IMPOSSIBLE until the product\n * satisfies it. Most blocks are RED against the live origin today — that is\n * correct and required. Each wave of the build flips its own describe block\n * green without touching the others:\n *\n *   wave-2 — metering is real          (usage ledger, ceilings, 429, lifecycle)\n *   wave-3 — auto.dev drop-in compat   (13 doors, exact wire shape, superset)\n *   wave-4 — the handoff triad         (pay / authorize / sign URLs + auth.vin)\n *   persona journeys                   (developer / consumer / dealer / enterprise)\n *   honesty                            (typed 404, truthful year codes, real npm)\n *   event delivery                     (SSE by conneg + signed webhooks, echo box)\n *   refi                               (/financing/* origination, per-lender offers)\n *   workflow read model                (available[] on the deal read, guards evaluated)\n *   sdk-wire                           (generalized handoff.{kind,url}, typed problems)\n *   wave-3-adjacent                    (auto.dev field parity: range filter, door args)\n *\n * The 14-test public-contract suite (verify/index.mjs) is the GREEN CORE this\n * ratchet protects — it stays untouched and digest-pinned; this module is a\n * SEPARATE artifact the Wave-1 consolidation publishes alongside it.\n *\n * Dialect discipline (A.8.6.2): specifiers closed to vitest + suite:env;\n * describe/it/expect core matchers + async only; no node built-ins, no\n * snapshots, no mocking. Mutating verbs address the sandbox environment the\n * pinned document consents to (sandbox=true). Two doors live OFF the suite\n * origin by design and are read through vars seams with honest defaults:\n * the auth.vin device rail (vars.authOrigin) and the npm registry proof\n * (vars.npmRegistry).\n *\n * COMPAT SOURCE OF TRUTH: @auto.dev/sdk@0.1.23 (ENDPOINTS table + docs\n * bundle). The 13 auto.dev doors and their wire shapes below are transcribed\n * from that package, field by field — apis.vin is a drop-in SUPERSET: the\n * auto.dev shape verbatim, estate members (type, provenance) ADDED never\n * substituted.\n */\n\n/** The demo-corpus VIN every deterministic read pins — the flagship\n * fall-back subject (founder ruling 2026-08-17, vin-2sgm). */\nconst VIN = 'JM3KFBXY1S0597748'\n/** The e2e walk VIN (the charter's demo journey vehicle). */\nconst WALK_VIN = '7SAYGDEE9PF947496'\n\nconst AUTH_ORIGIN = vars.authOrigin ?? 'https://auth.vin'\nconst NPM_REGISTRY = vars.npmRegistry ?? 'https://registry.npmjs.org'\n\nconst get = (path, headers) => fetch(`${origin}${path}`, headers ? { headers } : undefined)\nconst post = (path, body, headers) =>\n  fetch(`${origin}${path}`, {\n    method: 'POST',\n    body: JSON.stringify(body ?? {}),\n    headers: { 'content-type': 'application/json', ...(headers ?? {}) },\n  })\nconst bearer = (key) => ({ authorization: `Bearer ${key}` })\n\n/** Mint an anonymous sandbox key; body (name/tier/hardCeiling) optional. */\nasync function mintKey(body) {\n  const res = await post('/keys', body)\n  return res.json()\n}\n\n/**\n * Walk the charter deal to CONTRACTED (open → prequal → application →\n * approved decision → desk → F&I menu/select/stage/approve/capture) — the\n * shared spine of the wave-4 handoff tests and the consumer journey.\n */\nasync function walkToContract() {\n  const opened = await (\n    await post('/buy/deals', { vin: WALK_VIN, buyer: { name: 'Grace Hopper', zip: '90210' } })\n  ).json()\n  const dealId = opened.dealId\n  await post('/credit/prequal', {\n    applicant: { firstName: 'Ava', lastName: 'Good', address: '1 Compiler Ct', city: 'Arlington', state: 'CA', zip: '94103' },\n    consent: { consentedAt: '2026-08-08T00:00:00Z', evidence: 'clickwrap acceptance-suite' },\n    dealId,\n  })\n  const application = await (await post('/credit/applications', { dealId })).json()\n  await post('/credit/decisions/simulate', { dealJacketId: application.dealJacket, decision: 'approved' })\n  await post(`/buy/deals/${dealId}/desk`, { salesPrice: 45000, downPayment: 4500, term: 60, zip: '90210', financeType: 'Loan' })\n  await post(`/fi/deals/${dealId}/menu`)\n  await post(`/fi/deals/${dealId}/menu/present`)\n  await post(`/fi/deals/${dealId}/menu/select`, { package: 'Better', disclosuresAcknowledged: true })\n  await post(`/fi/deals/${dealId}/contract/stage`)\n  await post(`/fi/deals/${dealId}/contract/approve`)\n  await post(`/fi/deals/${dealId}/contract/capture`, { fiManager: { name: 'Casey Draper', licenseNumber: 'FL-4451' } })\n  return dealId\n}\n\n/** Complete the ceremony chain the sandbox already honors (artifact-bearing). */\nasync function completeCeremonies(dealId) {\n  await post(`/buy/deals/${dealId}/esign`, { signer: { name: 'Grace Hopper' } })\n  await post(`/buy/deals/${dealId}/notarize`, { signer: { name: 'Grace Hopper' } })\n  await post(`/buy/deals/${dealId}/stips`, { stips: ['proof-of-income'] })\n  await post(`/buy/deals/${dealId}/insurance`, { policy: { policyNumber: 'POL-ACCEPT-1', carrier: 'Sandbox Mutual' } })\n}\n\n// ---------------------------------------------------------------------------\n// WAVE 2 — METERING IS REAL\n// Per-key usage is measured, reflected, and enforced — a superset of the old\n// apis package's per-key metering. Zeros-with-a-disclaimer do not satisfy.\n// ---------------------------------------------------------------------------\ndescribe('wave-2 — metering is real', () => {\n  it(\n    'GET /keys/me reflects real accumulation — numeric spendToDate, callsToday, remainingCeiling that MOVE',\n    async () => {\n      const minted = await mintKey()\n      const auth = bearer(minted.key)\n      for (let i = 0; i < 3; i++) {\n        const res = await get('/listings', auth)\n        expect(res.status).toBe(200)\n      }\n      const me = await (await get('/keys/me', auth)).json()\n      // Numbers are numbers — \"0.00\" strings with a not-yet-enforced note fail.\n      expect(typeof me.usage.spendToDate).toBe('number')\n      expect(typeof me.usage.hardCeiling).toBe('number')\n      expect(typeof me.usage.remainingCeiling).toBe('number')\n      // Three metered listings calls at the posted 0.01 USD MUST show up.\n      expect(me.usage.spendToDate).toBeGreaterThanOrEqual(0.03)\n      expect(me.usage.callsToday).toBeGreaterThanOrEqual(3)\n      // The ceiling arithmetic holds on the wire.\n      expect(me.usage.remainingCeiling).toBeCloseTo(me.usage.hardCeiling - me.usage.spendToDate, 6)\n    },\n    60_000,\n  )\n\n  it(\n    'the hard ceiling fires a 402 from ACCUMULATION — no ?spend hint, the meter itself trips',\n    async () => {\n      // A caller-scoped ceiling makes the trip reachable: 3 × 0.01 fits under\n      // 0.03; the 4th metered call must 402 with a reauthorize handoff URL.\n      const minted = await mintKey({ hardCeiling: 0.03 })\n      const auth = bearer(minted.key)\n      const me = await (await get('/keys/me', auth)).json()\n      expect(me.usage.hardCeiling).toBe(0.03)\n      let tripped = null\n      for (let i = 0; i < 4; i++) {\n        const res = await get('/listings', auth)\n        if (res.status === 402) {\n          tripped = await res.json()\n          break\n        }\n      }\n      expect(tripped).not.toBeNull()\n      expect(tripped.type).toBe('OFFER')\n      expect(typeof tripped.reauthorize.url).toBe('string')\n    },\n    60_000,\n  )\n\n  it(\n    'a burst answers a TYPED 429 carrying retry_after — the rate limit exists and speaks',\n    async () => {\n      const minted = await mintKey()\n      const auth = bearer(minted.key)\n      let limited = null\n      for (let round = 0; round < 3 && !limited; round++) {\n        const burst = await Promise.all(\n          Array.from({ length: 30 }, () => get(`/decode/${VIN}`, auth)),\n        )\n        limited = burst.find((r) => r.status === 429) ?? null\n      }\n      expect(limited).not.toBeNull()\n      const body = await limited.json()\n      expect(body.type).toBeDefined()\n      expect(typeof body.retry_after).toBe('number')\n    },\n    120_000,\n  )\n\n  it('GET /keys lists the caller’s keys (lifecycle: enumerate)', async () => {\n    const minted = await mintKey()\n    const res = await get('/keys', bearer(minted.key))\n    expect(res.status).toBe(200)\n    const body = await res.json()\n    expect(body.type).toBe('OK')\n    expect(Array.isArray(body.keys)).toBe(true)\n    expect(body.keys.length).toBeGreaterThanOrEqual(1)\n  })\n\n  it('POST /keys/rotate mints a successor and retires the old credential (lifecycle: rotate)', async () => {\n    const minted = await mintKey()\n    const res = await post('/keys/rotate', {}, bearer(minted.key))\n    expect([200, 201]).toContain(res.status)\n    const rotated = await res.json()\n    expect(typeof rotated.key).toBe('string')\n    expect(rotated.key).not.toBe(minted.key)\n    // The retired credential no longer introspects.\n    const old = await get('/keys/me', bearer(minted.key))\n    expect(old.status).toBe(401)\n  }, 30_000)\n\n  it('DELETE /keys/me revokes the credential (lifecycle: delete)', async () => {\n    const minted = await mintKey()\n    const res = await fetch(`${origin}/keys/me`, { method: 'DELETE', headers: bearer(minted.key) })\n    expect(res.status).toBe(200)\n    const gone = await get('/keys/me', bearer(minted.key))\n    expect(gone.status).toBe(401)\n  }, 30_000)\n})\n\n// ---------------------------------------------------------------------------\n// WAVE 3 — AUTO.DEV DROP-IN COMPAT\n// The 13 doors of api.auto.dev (@auto.dev/sdk@0.1.23 ENDPOINTS), exact wire\n// shape, estate members ADDED never substituted.\n// ---------------------------------------------------------------------------\ndescribe('wave-3 — auto.dev drop-in compat', () => {\n  it('GET /vin/{vin} answers the auto.dev flat decode with estate provenance ADDED', async () => {\n    const res = await get(`/vin/${VIN}`)\n    expect(res.status).toBe(200)\n    const body = await res.json()\n    // The auto.dev shape, field by field (docs example: flat top-level).\n    expect(body.vin).toBe(VIN)\n    expect(body.vinValid).toBe(true)\n    expect(typeof body.squishVin).toBe('string')\n    expect(body.checksum).toBe(true)\n    expect(body.make).toBe('Mazda')\n    expect(typeof body.model).toBe('string')\n    expect(typeof body.vehicle).toBe('object')\n    // The estate member ADDED, not substituted.\n    expect(body.provenance).toBeDefined()\n  })\n\n  it('GET /listings wears the auto.dev envelope — data[] + links.self — with estate members added', async () => {\n    const res = await get('/listings')\n    expect(res.status).toBe(200)\n    const body = await res.json()\n    expect(Array.isArray(body.data)).toBe(true)\n    expect(body.data.length).toBeGreaterThanOrEqual(1)\n    expect(typeof body.links.self).toBe('string')\n    const row = body.data[0]\n    // Nested vehicle{} / retailListing{}, numbers as numbers.\n    expect(typeof row.vin).toBe('string')\n    expect(typeof row.vehicle).toBe('object')\n    expect(typeof row.vehicle.year).toBe('number')\n    expect(typeof row.vehicle.make).toBe('string')\n    expect(typeof row.retailListing).toBe('object')\n    expect(typeof row.retailListing.price).toBe('number')\n    // Founder miles-when-present ruling: miles is a number WHEN present; absent is\n    // allowed (auto.dev real contract — new cars carry no mileage). Never fabricated.\n    for (const r of body.data) {\n      if (r.retailListing?.miles !== undefined && r.retailListing?.miles !== null) {\n        expect(typeof r.retailListing.miles).toBe('number')\n      }\n    }\n    // Estate members ADDED alongside the compat shape.\n    expect(body.type).toBe('OK')\n    expect(body.provenance).toBeDefined()\n  })\n\n  it('GET /listings?includes=total answers total as a NUMBER (the auto.dev opt-in)', async () => {\n    const body = await (await get('/listings?includes=total')).json()\n    expect(typeof body.total).toBe('number')\n  })\n\n  it('the auto.dev filter vocabulary FILTERS — vehicle.make=Honda returns only Hondas', async () => {\n    const body = await (await get('/listings?vehicle.make=Honda')).json()\n    const rows = body.data ?? body.listing ?? []\n    expect(rows.length).toBeGreaterThanOrEqual(1)\n    for (const row of rows) expect(row.vehicle.make).toBe('Honda')\n  })\n\n  it('the estate filter vocabulary keeps working — make=Honda returns only Hondas (superset, both dialects)', async () => {\n    const body = await (await get('/listings?make=Honda')).json()\n    const rows = body.data ?? body.listing ?? []\n    expect(rows.length).toBeGreaterThanOrEqual(1)\n    for (const row of rows) expect(row.vehicle.make).toBe('Honda')\n  })\n\n  it('an unknown query param NEVER silently answers everything — typed 400 naming the stranger', async () => {\n    const res = await get('/listings?frobnicate=1')\n    expect(res.status).toBe(400)\n    const body = await res.json()\n    expect(body.type).toBe('BLOCKED')\n    expect(body.reason).toContain('frobnicate')\n  })\n\n  it('GET /listings/{vin} answers the auto.dev single-listing envelope for a LISTED vin', async () => {\n    const collection = await (await get('/listings')).json()\n    const listed = (collection.data ?? collection.listing)[0].vin\n    const body = await (await get(`/listings/${listed}`)).json()\n    // data is a single listing OBJECT on the vin-addressed read (auto.dev docs).\n    expect(body.data).toBeDefined()\n    expect(Array.isArray(body.data)).toBe(false)\n    expect(body.data.vin).toBe(listed)\n    expect(typeof body.data.vehicle).toBe('object')\n    expect(body.provenance).toBeDefined()\n  })\n\n  // The remaining auto.dev doors — each answers (never a bare 404), JSON,\n  // with estate provenance ADDED. Paths transcribed from the SDK ENDPOINTS.\n  const doors = [\n    ['photos', `/photos/${VIN}`],\n    ['specs', `/specs/${VIN}`],\n    ['build', `/build/${VIN}`],\n    ['recalls', `/recalls/${VIN}`],\n    ['openRecalls', `/openrecalls/${VIN}`],\n    ['payments', `/payments/${VIN}`],\n    ['apr', `/apr/${VIN}`],\n    ['tco', `/tco/${VIN}`],\n    ['taxes', `/taxes/${VIN}`],\n    ['plate', '/plate/CA/8ABC123'],\n  ]\n  for (const [name, path] of doors) {\n    it(`the auto.dev ${name} door answers at ${path} with provenance added`, async () => {\n      const res = await get(path)\n      expect(res.status).toBe(200)\n      const body = await res.json()\n      expect(body.provenance).toBeDefined()\n    })\n  }\n\n  it('GET /usage answers the caller’s meter (the auto.dev alias of the key ledger)', async () => {\n    const minted = await mintKey()\n    const res = await get('/usage', bearer(minted.key))\n    expect(res.status).toBe(200)\n    const body = await res.json()\n    expect(body.usage).toBeDefined()\n  })\n})\n\n// ---------------------------------------------------------------------------\n// WAVE 4 — THE HANDOFF TRIAD\n// Human-authority moments hand the agent a URL for its human: pay/authorize\n// at checkout, reauthorize over the ceiling, sign at esign; auth.vin is the\n// device rail that identifies the human on the same machine.\n// ---------------------------------------------------------------------------\ndescribe('wave-4 — the handoff triad', () => {\n  it(\n    'the checkout 402 OFFER carries a URL that resolves to an AUTHORIZE action for the human',\n    async () => {\n      const dealId = await walkToContract()\n      await completeCeremonies(dealId)\n      const res = await post(`/buy/deals/${dealId}/checkout`)\n      expect(res.status).toBe(402)\n      const offer = await res.json()\n      expect(offer.type).toBe('OFFER')\n      expect(typeof offer.checkoutUrl).toBe('string')\n      // The minted URL resolves ON this origin…\n      const page = await (await fetch(offer.checkoutUrl)).json()\n      expect(page.status).toBe('open')\n      // …and the resolved document DECLARES the authorize action the human\n      // performs there (not merely a status read) — the browser-handoff seam.\n      const authorize = page.authorize ?? (page.actions ?? {}).authorize\n      expect(authorize).toBeDefined()\n      expect(typeof (authorize.url ?? authorize)).toBe('string')\n    },\n    120_000,\n  )\n\n  it('the over-ceiling 402 carries a REAUTHORIZE URL, not prose alone', async () => {\n    const res = await get('/listings?spend=26')\n    expect(res.status).toBe(402)\n    const body = await res.json()\n    expect(body.type).toBe('OFFER')\n    expect(typeof body.reauthorize.url).toBe('string')\n    expect(body.reauthorize.url).toMatch(/^https?:\\/\\//)\n  })\n\n  it(\n    'esign answers OFFER-class with a ceremonyUrl — never a silent done:true rubber stamp',\n    async () => {\n      const dealId = await walkToContract()\n      const res = await post(`/buy/deals/${dealId}/esign`, { signer: { name: 'Grace Hopper' } })\n      const body = await res.json()\n      // The signature is a human act: the door hands back the ceremony URL\n      // for the human to sign at, instead of asserting the act completed.\n      expect(body.type).toBe('OFFER')\n      expect(typeof body.ceremonyUrl).toBe('string')\n      const step = (body.checklist ?? []).find((s) => s.key === 'esign')\n      expect(step?.done).not.toBe(true)\n    },\n    120_000,\n  )\n\n  it('the auth.vin device rail answers — POST /device/code mints a user_code + verification_uri', async () => {\n    const res = await fetch(`${AUTH_ORIGIN}/device/code`, {\n      method: 'POST',\n      body: JSON.stringify({ client_id: 'apis.vin' }),\n      headers: { 'content-type': 'application/json' },\n    })\n    expect(res.status).toBe(200)\n    const body = await res.json()\n    expect(typeof body.device_code).toBe('string')\n    expect(typeof body.user_code).toBe('string')\n    expect(body.verification_uri).toContain('/device')\n    expect(typeof body.expires_in).toBe('number')\n  }, 30_000)\n\n  it('the auth.vin human page at /device answers for the browser handoff', async () => {\n    const res = await fetch(`${AUTH_ORIGIN}/device`)\n    expect(res.status).toBe(200)\n    const html = await res.text()\n    expect(html).toContain('authorize')\n  }, 30_000)\n})\n\n// ---------------------------------------------------------------------------\n// PERSONA JOURNEYS — one end-to-end acceptance per divergent persona.\n// ---------------------------------------------------------------------------\ndescribe('persona journeys', () => {\n  it(\n    'DEVELOPER — mints a key, decodes on the auto.dev door, and filters listings with the auto.dev vocabulary',\n    async () => {\n      const minted = await mintKey()\n      expect(minted.key).toMatch(/^vk_/)\n      const auth = bearer(minted.key)\n      const decode = await (await get(`/vin/${VIN}`, auth)).json()\n      expect(decode.make).toBe('Mazda')\n      expect(decode.vinValid).toBe(true)\n      const listings = await (await get('/listings?vehicle.make=Honda&includes=total', auth)).json()\n      expect(Array.isArray(listings.data)).toBe(true)\n      expect(typeof listings.total).toBe('number')\n      for (const row of listings.data) expect(row.vehicle.make).toBe('Honda')\n      expect(typeof listings.data[0].retailListing.price).toBe('number')\n    },\n    60_000,\n  )\n\n  it(\n    'CONSUMER — walks the full deal and meets BOTH human handoffs: the signing ceremony and the checkout authorization',\n    async () => {\n      const dealId = await walkToContract()\n      // Handoff one: the signature is the human's — a ceremony URL comes back.\n      const esign = await (await post(`/buy/deals/${dealId}/esign`, { signer: { name: 'Grace Hopper' } })).json()\n      expect(esign.type).toBe('OFFER')\n      expect(typeof esign.ceremonyUrl).toBe('string')\n      // The remaining ceremonies clear with their artifacts.\n      await completeCeremonies(dealId)\n      // Handoff two: the money is the human's — the 402 carries the authorize URL.\n      const checkout = await post(`/buy/deals/${dealId}/checkout`)\n      expect(checkout.status).toBe(402)\n      const offer = await checkout.json()\n      expect(offer.type).toBe('OFFER')\n      expect(typeof offer.checkoutUrl).toBe('string')\n      const page = await (await fetch(offer.checkoutUrl)).json()\n      const authorize = page.authorize ?? (page.actions ?? {}).authorize\n      expect(authorize).toBeDefined()\n    },\n    180_000,\n  )\n\n  it(\n    'DEALER — reads inventory, captures a lead, and reads the deal-side book',\n    async () => {\n      const minted = await mintKey({ name: 'acceptance-dealer' })\n      const auth = bearer(minted.key)\n      const inventory = await get('/dealer/inventory', auth)\n      expect(inventory.status).toBe(200)\n      const inv = await inventory.json()\n      expect(inv.type).toBe('OK')\n      expect(Array.isArray(inv.units ?? inv.inventory)).toBe(true)\n      const lead = await post('/dealer/leads', { vin: VIN, customer: { name: 'Lin Marta', zip: '90210' } }, auth)\n      expect([200, 201]).toContain(lead.status)\n      const leadBody = await lead.json()\n      expect(leadBody.type).toBe('OK')\n      expect(leadBody.leadId ?? leadBody.id).toBeDefined()\n      const deals = await get('/dealer/deals', auth)\n      expect(deals.status).toBe(200)\n      expect((await deals.json()).type).toBe('OK')\n    },\n    60_000,\n  )\n\n  it(\n    'ENTERPRISE — mints a NAMED key on a tier with its own ceiling, and the ledger reflects all three',\n    async () => {\n      const minted = await mintKey({ name: 'acme-fleet', tier: 'growth', hardCeiling: 100 })\n      expect(minted.name).toBe('acme-fleet')\n      expect(minted.tier).toBe('growth')\n      const me = await (await get('/keys/me', bearer(minted.key))).json()\n      expect(me.name).toBe('acme-fleet')\n      expect(me.tier).toBe('growth')\n      expect(me.usage.hardCeiling).toBe(100)\n    },\n    60_000,\n  )\n})\n\n// ---------------------------------------------------------------------------\n// HONESTY — the surface never claims what is not so, and never mumbles.\n// ---------------------------------------------------------------------------\ndescribe('honesty', () => {\n  it('an unknown path answers a TYPED 404 BLOCKED — never bare text', async () => {\n    const res = await get('/no-such-door-ever')\n    expect(res.status).toBe(404)\n    const body = await res.json()\n    expect(body.type).toBe('BLOCKED')\n    expect(body.reason).toBeDefined()\n  })\n\n  it('digit year codes decode truthfully — position-10 digits 1-9 are the 2001-2009 band', async () => {\n    const five = await (await get('/decode/1HGCM82635A004352')).json()\n    expect(five.decode.year).toBe(2005)\n    const nine = await (await get('/decode/1HGCM82639A004352')).json()\n    expect(nine.decode.year).toBe(2009)\n  })\n\n  it('the npm install path is REAL — the registry serves apis.vin with a latest dist-tag', async () => {\n    const res = await fetch(`${NPM_REGISTRY}/apis.vin`)\n    expect(res.status).toBe(200)\n    const pkg = await res.json()\n    expect(pkg['dist-tags'].latest).toMatch(/^\\d+\\.\\d+\\.\\d+/)\n  }, 30_000)\n})\n\n// ===========================================================================\n// THE TRUE-DONE EXPANSION (2026-08-08) — the Bryant-completeness ratchet.\n//\n// The founder's probes established the first 36 tests UNDER-specified done:\n// no push delivery (webhooks/SSE), no refi, no generalized workflow read\n// model, the handoff triad spelled per-endpoint only, and two auto.dev\n// field-parity gaps. The blocks below raise the debt to the TRUE number,\n// implementing docs/design/2026-08-08-estate-sdk-shape.md (§4.5 push, §5.2\n// refi, §4.3 read model, §4.4 handoff, §5.1 superset). RED-first: each\n// future wave flips its OWN block and never touches another's.\n//\n// Rulings honored: SSE rides conneg on the EXISTING /events address (no\n// /stream sibling, no WebSocket); refi lives under /financing/*; the\n// webhook-test seam is an origin-side echo box behind vars.webhookSink\n// (defaulting to the suite origin — the authOrigin pattern); watch is NOT a\n// ledger stream; api.{door}.vin alias hosts stay un-ratcheted.\n// ===========================================================================\n\n/** Decimal-string money on the wire (the kernel Money law): '31500.00'. */\nconst MONEY_STRING = /^-?\\d+\\.\\d{2}$/\n/** Decimal-string rate: '6.49' — a string, never a float. */\nconst RATE_STRING = /^\\d+\\.\\d{2,4}$/\n/** The 13 dealLifecycle@1 states, verbatim (kernel stategraph roster). */\nconst DEAL_STATES = [\n  'OPENED', 'QUOTED', 'CREDIT_PENDING', 'DESKED', 'CONTRACTED', 'FUNDED',\n  'IN_FULFILLMENT', 'DELIVERED', 'SETTLED', 'CLOSED', 'ON_HOLD', 'CANCELLED',\n  'UNWOUND',\n]\n/** The webhook sink seam — echo boxes live ON the suite origin by default. */\nconst WEBHOOK_SINK = vars.webhookSink ?? origin\n\n/** Open a deal and give it a short event history (open + prequal). */\nasync function openDealWithHistory() {\n  const opened = await (\n    await post('/buy/deals', { vin: WALK_VIN, buyer: { name: 'Push Probe', zip: '90210' } })\n  ).json()\n  await post('/credit/prequal', {\n    applicant: { firstName: 'Push', lastName: 'Probe', address: '1 Stream St', city: 'Arlington', state: 'CA', zip: '94103' },\n    consent: { consentedAt: '2026-08-08T00:00:00Z', evidence: 'clickwrap acceptance-suite' },\n    dealId: opened.dealId,\n  })\n  return opened.dealId\n}\n\n/**\n * Read an SSE answer's `id:` lines until `want` ids arrive or the deadline\n * passes, then cancel the stream. Globals only (fetch/TextDecoder/setTimeout)\n * — the dialect's closed-import law holds.\n */\nasync function readSseIds(path, { want = 1, lastEventId, timeoutMs = 10_000 } = {}) {\n  const res = await fetch(`${origin}${path}`, {\n    headers: {\n      accept: 'text/event-stream',\n      ...(lastEventId !== undefined ? { 'last-event-id': String(lastEventId) } : {}),\n    },\n  })\n  const contentType = res.headers.get('content-type') ?? ''\n  const idsOf = (text) => [...text.matchAll(/(?:^|\\n)id: ?(\\d+)/g)].map((m) => Number(m[1]))\n  if (!contentType.includes('text/event-stream') || res.body === null) {\n    return { res, contentType, ids: [], text: '' }\n  }\n  const reader = res.body.getReader()\n  const decoder = new TextDecoder()\n  let text = ''\n  const deadline = Date.now() + timeoutMs\n  while (Date.now() < deadline && idsOf(text).length < want) {\n    const chunk = await Promise.race([\n      reader.read(),\n      new Promise((resolve) => setTimeout(() => resolve({ done: true, value: undefined }), Math.max(1, deadline - Date.now()))),\n    ])\n    if (chunk.done) break\n    text += decoder.decode(chunk.value, { stream: true })\n  }\n  await reader.cancel().catch(() => {})\n  return { res, contentType, ids: idsOf(text), text }\n}\n\n// ---------------------------------------------------------------------------\n// EVENT DELIVERY — the push rail: SSE by conneg + signed webhooks.\n// One address, two faces (the conneg law): Accept: text/event-stream streams\n// the SAME /buy/deals/{id}/events the JSON pull page answers; POST /webhooks\n// subscribes a sink; the origin-side echo box proves one signed delivery.\n// ---------------------------------------------------------------------------\ndescribe('event delivery — the push rail (SSE conneg + signed webhooks)', () => {\n  it(\n    'Accept: text/event-stream on /buy/deals/{id}/events answers a live stream — id: lines carry the event seq',\n    async () => {\n      const dealId = await openDealWithHistory()\n      const stream = await readSseIds(`/buy/deals/${dealId}/events`, { want: 1 })\n      expect(stream.res.status).toBe(200)\n      expect(stream.contentType).toContain('text/event-stream')\n      expect(stream.ids.length).toBeGreaterThanOrEqual(1)\n      expect(stream.text).toContain('data:')\n    },\n    60_000,\n  )\n\n  it(\n    'the stream resumes AFTER Last-Event-ID — ids are seqs: strictly increasing, replayable from a cursor',\n    async () => {\n      const dealId = await openDealWithHistory()\n      const first = await readSseIds(`/buy/deals/${dealId}/events`, { want: 2 })\n      expect(first.ids.length).toBeGreaterThanOrEqual(2)\n      for (let i = 1; i < first.ids.length; i++) {\n        expect(first.ids[i]).toBeGreaterThan(first.ids[i - 1])\n      }\n      const cursor = first.ids[0]\n      const resumed = await readSseIds(`/buy/deals/${dealId}/events`, { want: 1, lastEventId: cursor })\n      expect(resumed.ids.length).toBeGreaterThanOrEqual(1)\n      expect(resumed.ids[0]).toBeGreaterThan(cursor)\n    },\n    60_000,\n  )\n\n  it(\n    'Accept: application/json still answers the pull page — conneg NEVER regresses the existing read',\n    async () => {\n      const opened = await (\n        await post('/buy/deals', { vin: WALK_VIN, buyer: { name: 'Pull Probe', zip: '90210' } })\n      ).json()\n      const res = await get(`/buy/deals/${opened.dealId}/events`, { accept: 'application/json' })\n      expect(res.status).toBe(200)\n      expect(res.headers.get('content-type') ?? '').toContain('application/json')\n      const body = await res.json()\n      expect(body.type).toBe('OK')\n      expect(typeof body.count).toBe('number')\n      expect(Array.isArray(body.events)).toBe(true)\n    },\n    60_000,\n  )\n\n  it('POST /webhooks subscribes {url, events} and answers {subscription: {id, secret}}', async () => {\n    const minted = await mintKey()\n    const res = await post(\n      '/webhooks',\n      { url: `${WEBHOOK_SINK}/webhooks/echo/unread-box`, events: ['Deal.opened@1'] },\n      bearer(minted.key),\n    )\n    expect([200, 201]).toContain(res.status)\n    const body = await res.json()\n    expect(body.type).toBe('OK')\n    expect(typeof body.subscription.id).toBe('string')\n    expect(typeof body.subscription.secret).toBe('string')\n  }, 30_000)\n\n  it(\n    'the echo-box round-trip — one delivery, W0-EVT envelope verbatim, vin-signature HMAC verifiable from the secret',\n    async () => {\n      const minted = await mintKey()\n      const auth = bearer(minted.key)\n      // 1 — mint a sandbox inbox on the sink (vars.webhookSink seam).\n      const boxRes = await fetch(`${WEBHOOK_SINK}/webhooks/echo`, {\n        method: 'POST',\n        body: '{}',\n        headers: { 'content-type': 'application/json', ...auth },\n      })\n      expect([200, 201]).toContain(boxRes.status)\n      const boxBody = await boxRes.json()\n      expect(typeof boxBody.box.id).toBe('string')\n      expect(typeof boxBody.box.url).toBe('string')\n      // 2 — subscribe the inbox to the deal-opened fact.\n      const sub = await (\n        await post('/webhooks', { url: boxBody.box.url, events: ['Deal.opened@1'] }, auth)\n      ).json()\n      expect(typeof sub.subscription.secret).toBe('string')\n      // 3 — drive the fact.\n      await post('/buy/deals', { vin: WALK_VIN, buyer: { name: 'Hook Probe', zip: '90210' } }, auth)\n      // 4 — read the inbox until the delivery lands (at-least-once).\n      let deliveries = []\n      const deadline = Date.now() + 20_000\n      while (Date.now() < deadline) {\n        const read = await (await fetch(`${WEBHOOK_SINK}/webhooks/echo/${boxBody.box.id}`, { headers: auth })).json()\n        deliveries = read.deliveries ?? []\n        if (deliveries.length > 0) break\n        await new Promise((resolve) => setTimeout(resolve, 500))\n      }\n      expect(deliveries.length).toBeGreaterThanOrEqual(1)\n      const delivery = deliveries[0]\n      // The body is the RAW delivered bytes — signatures verify over bytes,\n      // never over a re-serialization.\n      expect(typeof delivery.body).toBe('string')\n      const envelope = JSON.parse(delivery.body)\n      // W0-EVT verbatim: name/what/who + mandatory bitemporal when.\n      expect(envelope.name).toBe('Deal.opened@1')\n      expect(envelope.what).toBeDefined()\n      expect(envelope.who).toBeDefined()\n      expect(typeof envelope.when.occurredAt).toBe('string')\n      expect(typeof envelope.when.recordedAt).toBe('string')\n      // vin-signature: t=<unix>,v1=<hmac-sha256(secret, t + '.' + body)>.\n      const header = (delivery.headers ?? {})['vin-signature']\n      expect(typeof header).toBe('string')\n      const t = /(?:^|,)t=(\\d+)/.exec(header)?.[1]\n      const v1 = /(?:^|,)v1=([0-9a-f]{64})/.exec(header)?.[1]\n      expect(typeof t).toBe('string')\n      expect(typeof v1).toBe('string')\n      const enc = new TextEncoder()\n      const key = await crypto.subtle.importKey(\n        'raw',\n        enc.encode(sub.subscription.secret),\n        { name: 'HMAC', hash: 'SHA-256' },\n        false,\n        ['sign'],\n      )\n      const mac = await crypto.subtle.sign('HMAC', key, enc.encode(`${t}.${delivery.body}`))\n      const hex = [...new Uint8Array(mac)].map((b) => b.toString(16).padStart(2, '0')).join('')\n      expect(hex).toBe(v1)\n    },\n    60_000,\n  )\n})\n\n// ---------------------------------------------------------------------------\n// REFI — financing.vin origination (/financing/*; the recorded path-grammar\n// ruling: refinance is origination against an existing lien, so it lives\n// with its door; credit/* stays bureau/decisioning primitives).\n// ---------------------------------------------------------------------------\ndescribe('refi — financing.vin origination', () => {\n  const REFI_INPUT = {\n    vin: WALK_VIN,\n    currentBalance: '28450.00',\n    currentApr: '11.99',\n    remainingTermMonths: 54,\n  }\n\n  it('POST /financing/refinance/quotes answers a priced quote — validThrough + decimal-string money', async () => {\n    const res = await post('/financing/refinance/quotes', REFI_INPUT)\n    expect([200, 201]).toContain(res.status)\n    const body = await res.json()\n    // A priced quote is OFFER-class (quote@1 governs expiry) with provenance.\n    expect(body.type).toBe('OFFER')\n    expect(body.provenance).toBeDefined()\n    expect(body.quote.apr).toMatch(RATE_STRING)\n    expect(typeof body.quote.termMonths).toBe('number')\n    expect(body.quote.payment).toMatch(MONEY_STRING)\n    expect(body.quote.amountFinanced).toMatch(MONEY_STRING)\n    expect(Date.parse(body.quote.validThrough)).toBeGreaterThan(Date.now())\n  }, 30_000)\n\n  it('POST /financing/refinance/applications opens an application whose read carries state + available[]', async () => {\n    const opened = await post('/financing/refinance/applications', REFI_INPUT)\n    expect([200, 201]).toContain(opened.status)\n    const openedBody = await opened.json()\n    // The id member is named the way the path template spells it (dealId law).\n    expect(typeof openedBody.applicationId).toBe('string')\n    const read = await (await get(`/financing/applications/${openedBody.applicationId}`)).json()\n    expect(read.type).toBe('OK')\n    expect(typeof read.application.state).toBe('string')\n    // The generalized workflow read model: legal transitions as data.\n    expect(Array.isArray(read.application.available)).toBe(true)\n    for (const row of read.application.available) {\n      expect(typeof row.trigger).toBe('string')\n      expect(typeof row.to).toBe('string')\n    }\n  }, 30_000)\n\n  it('GET /financing/applications/{id}/offers answers per-lender rows — typed, priced, expiring', async () => {\n    const opened = await (await post('/financing/refinance/applications', REFI_INPUT)).json()\n    const body = await (await get(`/financing/applications/${opened.applicationId}/offers`)).json()\n    expect(body.provenance).toBeDefined()\n    expect(Array.isArray(body.offers)).toBe(true)\n    expect(body.offers.length).toBeGreaterThanOrEqual(1)\n    for (const row of body.offers) {\n      // {lender, apr, termMonths, payment, amountFinanced, validThrough} —\n      // decimal strings, quote@1 expiry, and NO ranking prose (attest law).\n      expect(typeof row.lender).toBe('string')\n      expect(row.apr).toMatch(RATE_STRING)\n      expect(typeof row.termMonths).toBe('number')\n      expect(row.payment).toMatch(MONEY_STRING)\n      expect(row.amountFinanced).toMatch(MONEY_STRING)\n      expect(Date.parse(row.validThrough)).toBeGreaterThan(Date.now())\n    }\n  }, 30_000)\n})\n\n// ---------------------------------------------------------------------------\n// WORKFLOW READ MODEL — /buy/deals/{id} GROWS available[] (never renames):\n// the transitions legal for THIS deal's type+state, guards evaluated,\n// derived from dealLifecycleFor — never a second state machine.\n// ---------------------------------------------------------------------------\ndescribe('workflow read model — available[] on the deal read', () => {\n  it(\n    'a FRESH deal names only the transitions legal from OPENED — and existing members stand unchanged',\n    async () => {\n      const opened = await (\n        await post('/buy/deals', { vin: WALK_VIN, buyer: { name: 'Ada Reader', zip: '90210' } })\n      ).json()\n      const body = await (await get(`/buy/deals/${opened.dealId}`)).json()\n      // Growth, never retrofit-rename: the ratcheted members stand.\n      expect(body.type).toBe('OK')\n      expect(body.state).toBe('OPENED')\n      expect(body.dealType).toBe('Concierge Buy')\n      expect(Array.isArray(body.checklist)).toBe(true)\n      // The growth: available[] rows {trigger, to} for the deal's type+state.\n      expect(Array.isArray(body.available)).toBe(true)\n      expect(body.available.length).toBeGreaterThanOrEqual(1)\n      const triggers = body.available.map((row) => row.trigger)\n      expect(triggers).toContain('quoted')\n      for (const row of body.available) {\n        expect(DEAL_STATES).toContain(row.to)\n        // From OPENED exactly quoted/cancelled/held are legal — a fresh deal\n        // NEVER offers settled (or any downstream hop).\n        expect(['quoted', 'cancelled', 'held']).toContain(row.trigger)\n      }\n    },\n    60_000,\n  )\n\n  it(\n    'a CONTRACTED deal offers its own legal hops — never settled, and never a guard-refused unwind',\n    async () => {\n      const dealId = await walkToContract()\n      const body = await (await get(`/buy/deals/${dealId}`)).json()\n      expect(body.state).toBe('CONTRACTED')\n      expect(Array.isArray(body.available)).toBe(true)\n      const triggers = body.available.map((row) => row.trigger)\n      // The rewind to the desk is unguarded and always legal here.\n      expect(triggers).toContain('redesked')\n      // settled is three states downstream — offering it would be a lie.\n      expect(triggers).not.toContain('settled')\n      // Guards are EVALUATED, not decorative: unwind requires human desk\n      // approval, which no one granted — the row must be absent.\n      expect(triggers).not.toContain('unwound')\n    },\n    120_000,\n  )\n})\n\n// ---------------------------------------------------------------------------\n// SDK STRATUM 1 ON THE WIRE — the generalized handoff affordance + typed\n// problems. Every OFFER-class answer ADDS handoff.{kind,url} ALONGSIDE its\n// ratcheted spelling (ceremonyUrl / checkoutUrl / reauthorize.url stay);\n// field-shaped refusals carry problems[] rows the SDK can lift typed.\n// ---------------------------------------------------------------------------\ndescribe('sdk-wire — the generalized handoff + typed problems', () => {\n  it('the over-ceiling 402 carries handoff {kind: reauthorize, url} ALONGSIDE reauthorize.url', async () => {\n    const res = await get('/listings?spend=26')\n    expect(res.status).toBe(402)\n    const body = await res.json()\n    expect(body.type).toBe('OFFER')\n    expect(body.handoff.kind).toBe('reauthorize')\n    expect(body.handoff.url).toMatch(/^https?:\\/\\//)\n    // The ratcheted spelling stands alongside — growth, never substitution.\n    expect(typeof body.reauthorize.url).toBe('string')\n  })\n\n  it(\n    'the esign OFFER carries handoff {kind: sign, url} ALONGSIDE ceremonyUrl',\n    async () => {\n      const dealId = await walkToContract()\n      const body = await (\n        await post(`/buy/deals/${dealId}/esign`, { signer: { name: 'Grace Hopper' } })\n      ).json()\n      expect(body.type).toBe('OFFER')\n      expect(body.handoff.kind).toBe('sign')\n      expect(typeof body.handoff.url).toBe('string')\n      expect(typeof body.ceremonyUrl).toBe('string')\n    },\n    120_000,\n  )\n\n  it(\n    'the checkout 402 carries handoff {kind: authorize, url} ALONGSIDE checkoutUrl',\n    async () => {\n      const dealId = await walkToContract()\n      await completeCeremonies(dealId)\n      const res = await post(`/buy/deals/${dealId}/checkout`)\n      expect(res.status).toBe(402)\n      const body = await res.json()\n      expect(body.type).toBe('OFFER')\n      expect(body.handoff.kind).toBe('authorize')\n      expect(typeof body.handoff.url).toBe('string')\n      expect(typeof body.checkoutUrl).toBe('string')\n    },\n    120_000,\n  )\n\n  it('a field-shaped refusal is TYPED — BLOCKED with problems[] rows {path, expected, got}', async () => {\n    const res = await post('/buy/deals', {})\n    expect(res.status).toBe(400)\n    const body = await res.json()\n    expect(body.type).toBe('BLOCKED')\n    expect(Array.isArray(body.problems)).toBe(true)\n    expect(body.problems.length).toBeGreaterThanOrEqual(1)\n    for (const problem of body.problems) {\n      expect(typeof problem.path).toBe('string')\n      expect(typeof problem.expected).toBe('string')\n      expect(typeof problem.got).toBe('string')\n    }\n  })\n})\n\n// ---------------------------------------------------------------------------\n// WAVE-3-ADJACENT — auto.dev field-parity closure. The 13-door roster is\n// closed (AC-1); these are the drop-in gaps BEYOND door existence, grounded\n// in the @auto.dev/sdk@0.1.23 README examples: the range-filter grammar and\n// the documented per-door query args (which the unknown-param law must treat\n// as vocabulary, never strangers).\n// ---------------------------------------------------------------------------\ndescribe('wave-3-adjacent — auto.dev field parity', () => {\n  it('the auto.dev RANGE filter grammar works — retailListing.price=lo-hi bounds every row', async () => {\n    // Self-calibrating: take a real price from the corpus, band around it.\n    const all = await (await get('/listings')).json()\n    const rows = all.data ?? all.listing ?? []\n    expect(rows.length).toBeGreaterThanOrEqual(1)\n    const price = rows[0].retailListing.price\n    const lo = Math.max(0, price - 500)\n    const hi = price + 500\n    const filtered = await (await get(`/listings?retailListing.price=${lo}-${hi}`)).json()\n    const hits = filtered.data ?? filtered.listing ?? []\n    expect(hits.length).toBeGreaterThanOrEqual(1)\n    for (const row of hits) {\n      expect(row.retailListing.price).toBeGreaterThanOrEqual(lo)\n      expect(row.retailListing.price).toBeLessThanOrEqual(hi)\n    }\n  }, 30_000)\n\n  it('the payments door accepts its documented args — price/zip/downPayment are vocabulary, not strangers', async () => {\n    const res = await get(`/payments/${VIN}?price=35000&zip=90210&downPayment=5000`)\n    expect(res.status).toBe(200)\n    const body = await res.json()\n    expect(body.type).not.toBe('BLOCKED')\n    expect(body.provenance).toBeDefined()\n  })\n\n  it('the tco door accepts its documented zip arg', async () => {\n    const res = await get(`/tco/${VIN}?zip=90210`)\n    expect(res.status).toBe(200)\n    const body = await res.json()\n    expect(body.type).not.toBe('BLOCKED')\n    expect(body.provenance).toBeDefined()\n  })\n})\n}\n"
}
