Skip to content

feat(X402-47): fixture-consumption infrastructure + 3 hand-rolled D.x captures#82

Merged
fardinvahdat merged 2 commits into
mainfrom
feat/X402-47-fixture-consumption
May 22, 2026
Merged

feat(X402-47): fixture-consumption infrastructure + 3 hand-rolled D.x captures#82
fardinvahdat merged 2 commits into
mainfrom
feat/X402-47-fixture-consumption

Conversation

@fardinvahdat
Copy link
Copy Markdown
Owner

Summary

X402-47 — closes the v0.3.2 audit-gate gap on D.2 / D.3 / D.5 verdict-synthesis paths. Ships fixture-consumption infrastructure + 3 hand-rolled captured-response fixtures covering one v0.3.2 D.x failure mode each. Hermetic, no live HTTP, no service-up dependencies.

What this PR adds

New directory: tests/fixtures/bazaar/captured-responses/

Three self-describing JSON fixtures, each capturing the three mock responses (well-known + challenge + discovery) needed to exercise one D.x verdict-synthesis path through runBazaarCheck end-to-end:

Fixture Exercises Models
d2-missing-propagation.json metadata_propagation: missingupstream_issue @zev / TheRoosters / GM pattern
d3-processing-stuck.json indexer_state: processingupstream_stuck Max's polyodds.bet (canonical #2207)
d5-body-discovery.json BodyDiscoveryExtension shape → looks_correct (no false-positive) AsaiShota test-echo-cdp + @0xdespot hyperD

Schema (self-describing)

{
  "$comment": "...",
  "scenario": "<slug>",                          // matches file basename
  "input": { "serviceUrl": "...", "chain": "base-sepolia" },
  "mocks": {
    "well-known": { "status": 200, "body": {...} },
    "challenge":  { "status": 402, "body": {...} },
    "discovery":  { "status": 200, "body": {...} }
  },
  "expected": {
    "verdict": "upstream_stuck",
    "exitCode": 3,
    "facets": { "indexing.indexer_state": "processing" }
  }
}

New integration test: tests/integration/bazaar-check-captured-responses.test.ts

Auto-discovers every .json in the fixture directory. For each fixture:

  • Builds a mock fetcher dispatching by URL pattern (well-known / discovery / challenge fallback)
  • Runs runBazaarCheck end-to-end
  • Asserts the top-level verdict (kind + exitCode) match expected
  • Asserts every per-check detail facet via dotted-path extraction (e.g., "indexing.indexer_state")
  • Schema-checks the fixture itself (well-formed JSON, has all required keys)

Adding a new fixture is one JSON file — the harness picks it up automatically (no test code change required for new scenarios that fit the existing schema).

Scope cut vs original X402-47 AC

The original ticket called for consuming 6 named contributor fixtures:

Reality: only TomSmart's first fixture is in the repo. The other 5 are pre-committed but not yet delivered (TomSmart's Sunday drop is ~24h out as of writing; the others are rolling).

This PR ships the infrastructure NOW with synthetic hand-rolled captures so the v0.3.2 audit gate has D.x coverage; real contributor fixtures wire in via the same harness as they arrive. The synthetic fixtures and the real ones coexist — no migration needed when contributor fixtures land.

Acceptance criteria (X402-47, satisfied at the infrastructure layer)

  • Fixture loader handles a subdirectory (captured-responses/) — extending the loader for d4-targets/ + multi-rail/ is one-line work when those land
  • At least one fixture per D.x facet captured (3 / 3 facets covered: D.2 + D.3 + D.5; D.4 covered by the pipeline test's --endpoint mode)
  • Integration tests iterate over fixtures + assert sub-check decompositions
  • AsaiShota's test-echo-cdp-shape produces looks_correct (NOT false-positive implementation_issue) under v0.3.2
  • CHANGELOG ### Added entry documenting the new infrastructure + scope cut

Strict audit gate — abbreviated (user-in-loop mode)

  • Stage 1 pre-work: branched off 6624e21 (PR feat(X402-46): D.3 indexer-state probe + upstream_stuck composite verdict #81 X402-46 + cap-bump merged); .gitignore WIP not staged
  • Stage 2 implementation: new fixture directory + 3 JSON files + 1 new integration test file + CHANGELOG entry
  • Stage 3 correctness: ✅ typecheck + lint + 511 tests pass (was 499; +12 captured-response tests) + build + check:publish-surface 102 files / 403 KB / 0 devDep imports (under both caps)
  • Stage 4 edge cases: ≥7 — fixture file with malformed JSON (JSON.parse errors at load time, fails before tests run), fixture missing required keys (schema test fires per-fixture), URL-routing fallback (challenge URL = anything-not-well-known-or-discovery), facets block optional (test skips facet assertions when absent), unicode in service URLs, multiple resources in discovery body (uses first), $comment field as documented free-text (test ignores it)
  • Stage 5 gap check: all 5 X402-47 AC items satisfied at the infrastructure layer; the 6-fixture contributor list is reframed honestly in the CHANGELOG as scope-cut + path-to-wire-in
  • Stage 6 ship: this PR

What unblocks on merge

  • X402-48 (release cut) — the only remaining v0.3.2 ticket. All D.x land + integration coverage land + JSON API stability land. Release-prep checklist can run.
  • Real contributor fixtures (TomSmart Sun, AsaiShota test-echo-cdp, etc.) wire into this directory as they arrive — no new infrastructure needed

🤖 Generated with Claude Code

fardinvahdat and others added 2 commits May 23, 2026 02:33
… captures

Closes the v0.3.2 audit-gate gap: D.2 / D.3 / D.5 verdict-synthesis
paths now have end-to-end coverage via hermetic captured-response
fixtures (no live HTTP, no service-up dependencies).

New tests/fixtures/bazaar/captured-responses/ directory with three
self-describing JSON fixtures:

- d2-missing-propagation.json — manifest correct, indexer returns
  blank resource → metadata_propagation: missing → upstream_issue.
  Models @zev / TheRoosters / GM pattern.

- d3-processing-stuck.json — CDP discovery returns 0 resources →
  indexer_state: processing → upstream_stuck verdict. Models Max's
  polyodds.bet pattern (canonical #2207 cluster).

- d5-body-discovery.json — extensions.bazaar uses BodyDiscoveryExtension
  shape (info.input/output/schema). Was false-positive implementation_issue
  pre-v0.3.2; now passes cleanly with looks_correct. Models AsaiShota
  test-echo-cdp + 0xdespot hyperD pattern.

Self-describing fixture schema: {scenario, input, mocks, expected}.
New integration test iterates over every .json in the directory,
builds a mock fetcher dispatching by URL pattern (well-known /
discovery / challenge fallback), runs runBazaarCheck end-to-end,
asserts both the top-level verdict and per-check detail facets via
dotted-path extraction (e.g., "indexing.indexer_state").

Adding a new fixture is one JSON file — the harness picks it up
automatically.

Scope cut vs original X402-47 AC: the ticket called for consuming
6 named contributor fixtures (TomSmart cdp-mature, AsaiShota
test-echo-cdp, evanatpizzarobot tensorfeed, 0xdespot hyperd,
hypeprinter007 anchor-x402 multi-rail). Only TomSmart's first
fixture is in the repo; the rest are pre-committed but not
delivered. This PR ships the infrastructure with synthetic
captures so the v0.3.2 audit gate has D.x coverage NOW; real
contributor fixtures wire in via the same harness as they land
(TomSmart Sunday drop is the next external event).

Tests: 511 pass (was 499; +12 captured-response). 105 files
(102 + 3 fixture JSON files) / 393 KB. Under both caps.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
The CHANGELOG entry was prepared but the Edit failed mid-commit
due to a concurrent linter touch on the file. Adding as a follow-up
so the v0.3.2 ### Added section captures X402-47.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
x402trace-dogfood Ready Ready Preview, Comment May 22, 2026 11:05pm

@fardinvahdat fardinvahdat merged commit b7f0408 into main May 22, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant