Skip to content

feat(X402-42): --endpoint <paid-url> per-route 402 probe mode (D.4)#77

Merged
fardinvahdat merged 1 commit into
mainfrom
feat/X402-42-d4-endpoint-per-route-probe
May 22, 2026
Merged

feat(X402-42): --endpoint <paid-url> per-route 402 probe mode (D.4)#77
fardinvahdat merged 1 commit into
mainfrom
feat/X402-42-d4-endpoint-per-route-probe

Conversation

@fardinvahdat
Copy link
Copy Markdown
Owner

Summary

X402-42 (D.4) — new bazaar-check --endpoint <paid-url> flag for per-route 402 probe mode. Unblocks the #2207 services that publish per-route instead of at root /.well-known/x402: @AsaiShota's test-echo-cdp, @evanatpizzarobot's TensorFeed, @0xdespot's hyperD.ai.

Why

v0.3.0/0.3.1 always probes root /.well-known/x402 first. Per-route services return 404 there → false-positive implementation_issue verdict on services whose actual implementation is correct. Three named operators on #2207 confirmed this pattern.

What changes

bazaar-check --endpoint <paid-url> (CLI flag)

When supplied:

  1. Skip the root /.well-known/x402 probe entirely — emit a pass-status well-known result with a "skipped per --endpoint (probing <url> directly instead of /.well-known/x402)" message. Preserves the 4-result envelope shape per ADR-004 Pillar 2 (JSON API stability).
  2. Fetch the 402 challenge from <paid-url> instead of <service-url>
  3. Run manifest-shape validations against the 402 body (extensions.bazaar etc.) — same logic, different data source
  4. Self-payment + indexing run unchanged — both consume the challenge body's payTo regardless of how the challenge was obtained

UX info note

A one-line note prints when --endpoint is used:

ℹ skipping root /.well-known/x402 probe per --endpoint. Note: services that DO publish at root signal extra discoverability hygiene; consider both.

Routes to stdout in --log human, stderr in --log json so stdout stays JSON-parseable.

Validation

--endpoint value is URL-validated at command entry. Non-URL values exit 1 (EXIT_USAGE) with a clear error.

Acceptance criteria (X402-42)

  • New --endpoint <paid-url> flag implemented on bazaar-check
  • npx x402trace bazaar-check --endpoint https://api.tensorfeed.ai/api/premium/<route> parses cleanly and produces verdict + sub-checks against the actual paid endpoint, without requiring root well-known
  • AsaiShota's test-echo-cdp produces a clean verdict under --endpoint mode (no false-fail on well-known)
  • @0xdespot's hyperD.ai similarly produces a clean verdict under --endpoint
  • One-line info note printed when --endpoint is used (per UX note above)
  • Integration tests: 6 new (≥4 AC threshold — happy path + malformed challenge + non-402 + invalid URL + UX note human + UX note json)
  • CHANGELOG [Unreleased] ### Added entry + ### JSON API subsection documenting the additive well-known result shape

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

  • Stage 1 pre-work: branched off bd7494a (PR feat(X402-41): ADR-004 — v0.3.2 scope + JSON API stability + facilitator-aware verdict semantics #75 ADR-004 just-merged); .gitignore WIP on branch but NOT staged (hard rule docs(X402-8): SPEC.md v0.1 — implements the wedge from ADR-001 #7 preserved)
  • Stage 2 implementation: 3 source files modified (1 orchestrator + 2 CLI files) + 1 test file extended + CHANGELOG appended. Parallel-safe with X402-43 (D.5) — independent code surface
  • Stage 3 correctness: ✅ typecheck clean; ✅ lint+prettier clean; ✅ 435 tests pass + 4 skipped (was 429+4; +6 new D.4 integration tests); ✅ build clean; ✅ check:publish-surface 98 files / 362 KB / 0 devDep imports
  • Stage 4 edge cases: non-URL value → exit 1; URL that 200s → implementation_issue with "expected 402, got 200" message; URL that 4xx-not-402s → distinct verdict (cross-ref candidate_F for hyperD free-tier-upgrade case; flagged for follow-up); malformed challenge → implementation_issue but well-known still skipped (no false-positive); UX note routing preserves JSON parseability on stdout; URL validation at entry rejects garbage early
  • Stage 5 gap check: all 6 X402-42 AC items satisfied; CHANGELOG entry + ### JSON API subsection added; cross-references to ADR-004 + X402-47 (fixture consumption uses --endpoint) present
  • Stage 6 ship: this PR; awaiting maintainer merge

What unblocks on merge

🤖 Generated with Claude Code

@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 9:53pm

For services that publish per-route instead of at root /.well-known/x402
— the #2207 pattern documented by @AsaiShota (test-echo-cdp),
@evanatpizzarobot (TensorFeed), and @0xdespot (hyperD.ai). v0.3.0/0.3.1
verdicted these as `implementation_issue` despite being correctly
implemented; default mode requires root well-known.

When `--endpoint <paid-url>` is supplied:
- Skip the root /.well-known/x402 probe entirely (emits a pass-status
  result with a "skipped per --endpoint" message; preserves the
  4-result envelope shape per ADR-004 Pillar 2)
- Fetch the 402 challenge directly from the given paid URL
- Run manifest-shape validations against the 402 body
- Self-payment + indexing run unchanged (consume challenge body's payTo)

UX:
- One-line info note prints when --endpoint is used
- Routes to stdout in human format, stderr in json format (preserves
  stdout JSON-parseability)
- Non-URL values rejected with exit 1 and a clear error

New `endpoint?: string` on BazaarCheckOptions (programmatic) and
BazaarCheckCommandOptions (CLI).

Tests: 6 new integration tests in bazaar-check-pipeline.test.ts —
happy path, malformed challenge, non-402 response, invalid URL,
human-format UX note, json-format UX note routing. 435 total tests
pass (was 429).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@fardinvahdat fardinvahdat force-pushed the feat/X402-42-d4-endpoint-per-route-probe branch from a6e4a43 to afb1782 Compare May 22, 2026 21:53
@fardinvahdat fardinvahdat merged commit 971ab4c 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