Skip to content

CDP/Bazaar alignment Phase 1: validation-order fix + extensions.bazaar - #37

Merged
Mayakovsky merged 2 commits into
mainfrom
cdp-bazaar-alignment-phase1
Aug 3, 2026
Merged

CDP/Bazaar alignment Phase 1: validation-order fix + extensions.bazaar#37
Mayakovsky merged 2 commits into
mainfrom
cdp-bazaar-alignment-phase1

Conversation

@Mayakovsky

Copy link
Copy Markdown
Owner

Summary

Per CDP-BAZAAR-COMPATIBILITY-AUDIT-REPORT-KOV.md, addresses blockers #2 (wire-format mismatch) and #3 (validation-order bug, newly found during the audit) of three. Not blocker #1 (CDP Facilitator routing) — that's Phase 2, blocked on Forces obtaining CDP API keys. verify.ts/settle.ts/clients.ts are untouched.

Task 2 — validation-order fix. offerings.ts/trustRung.ts wired the x402 gate as preHandler, which Fastify runs after body-schema validation. A probe without a schema-valid body (no X-PAYMENT, empty/malformed body — exactly what CDP's own validator sends, and what any discovery crawler that doesn't already know the input shape would send) got a 400 before ever reaching a 402. Fix: preValidation instead of preHandler — same function, runs earlier in Fastify's lifecycle, no business logic touched. A request with valid payment but an invalid body now settles first, then 400s on schema — consistent with this codebase's already-established "settlement stands even if something after it fails" posture, not a new risk category.

Task 3 — CDP's canonical wire shape. Added a top-level extensions.bazaar object ({bazaar: {info: {input, output}, schema}}) alongside (not replacing) the existing accepts[0].extra.bazaar. Reshaped from EvaluationKitEntry via a new shared buildCdpBazaarExtension(). Documented uncertainty: CDP's public docs describe bazaar.info/bazaar.schema but don't publish a complete example of the surrounding extensions envelope's exact position — placed at the top of the body (sibling to accepts), the more spec-consistent reading, not independently verified against a live CDP-indexed endpoint (no API keys yet). Re-verify in Phase 2.

Test plan

  • pnpm build && pnpm test && pnpm typecheck && pnpm lint green (28/28 tasks)
  • New: all 7 priced offerings + the trust rung, empty/malformed body + no payment → asserts 402 with Bazaar metadata, not 400 (the exact gap x402-routes.test.ts had)
  • New: extensions.bazaar shape assertions in challenge.test.ts/trustRung.test.ts (both packages)
  • All pre-existing tests pass unmodified (no regression on the valid-body/valid-payment paths)

CDP-BAZAAR-ALIGNMENT-PHASE1-KOV-directive.md.

🤖 Generated with Claude Code

…ape (Phase 1)

Per CDP-BAZAAR-COMPATIBILITY-AUDIT-REPORT-KOV.md, this addresses
blockers #2 (wire-format mismatch) and the newly-found #3
(validation-order bug), NOT #1 (CDP Facilitator routing -- Phase 2,
blocked on Forces obtaining CDP API keys; verify.ts/settle.ts/
clients.ts untouched here).

Task 2 -- validation-order fix: offerings.ts and trustRung.ts wired
the x402 gate as `preHandler`, which Fastify runs AFTER body-schema
validation. A probe without a schema-valid body (no X-PAYMENT header,
empty/malformed body -- exactly what CDP's own validator sends, and
what any discovery crawler that doesn't already know the input shape
would send) got a 400 before ever reaching the point where a
402-with-Bazaar-metadata would be returned. Fix: wire the gate as
`preValidation` instead, which runs BEFORE schema validation --
identical function, one hook-name change, no business logic touched.
A request that carries valid payment but an invalid body now settles
first, then 400s on schema -- consistent with this codebase's already-
established "settlement stands even if something after it fails"
posture (preHandler.ts's own header comment), not a new risk category.
New tests: all 7 priced offerings + the trust rung, empty/malformed
body + no payment -> asserts 402 with Bazaar metadata attached, not
400 -- exactly the gap x402-routes.test.ts had, per the directive.

Task 3 -- CDP's canonical wire shape: added a top-level
`extensions.bazaar` object (`{bazaar: {info: {input, output}, schema}}`)
alongside (not replacing) the existing `accepts[0].extra.bazaar` --
other consumers may still read the latter. Reshaped from
EvaluationKitEntry via a new shared `buildCdpBazaarExtension()`,
used by both challenge.ts and trustRung.ts. Documented uncertainty
in code: CDP's public docs describe `bazaar.info`/`bazaar.schema`
but don't publish a complete example of the surrounding `extensions`
envelope's exact position -- placed at the top of the body (sibling
to accepts), the more spec-consistent reading, not independently
verified against a live CDP-indexed endpoint (no API keys yet).
Re-verify against the real facilitator in Phase 2.

EXPANSION-CDP-BAZAAR-ALIGNMENT-PHASE1-KOV-directive.md Tasks 2-3.
…(Phase 1 revision)

Moving the whole gate to preValidation fixed the discovery-crawler bug but
over-corrected: it also moved settlement ahead of schema validation, so a
buyer with a valid payment but a malformed body now paid before failing.

Split into two hooks: a new lightweight preValidation check (header
presence only, body-independent) stays ahead of schema validation; the
existing verify+settle logic stays on preHandler, after schema validation,
restoring the pre-existing "malformed body never gets charged" protection.

Applies to both the normal 7-offering gate and the trust-rung gate.
@Mayakovsky
Mayakovsky merged commit e028f83 into main Aug 3, 2026
3 checks passed
@Mayakovsky
Mayakovsky deleted the cdp-bazaar-alignment-phase1 branch August 14, 2026 01:46
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