feat(X402-46): D.3 indexer-state probe + upstream_stuck composite verdict#81
Merged
Merged
Conversation
…dict
Closes Max's polyodds.bet pain pattern: settles complete against CDP
/settle returning {bazaar: {status: "processing"}}, but discovery
shows 0 resources for the payTo — queue stalled. Per ADR-004 Pillar 1,
this is `upstream_stuck` (distinct attribution from generic
`upstream_issue` like propagation drift or network errors).
New file `src/bazaar/facilitator-detect.ts`:
- Shared D.2 + D.3 helper, manifest-claim-based detection
- Recognizes "coinbase-cdp" / "cdp" / "coinbase" (case-insensitive) as cdp;
any other non-empty string as non-cdp; everything else as unknown
- Default behavior is `unknown` when manifest doesn't declare —
conservative; existing CDP-discovery probe path handles unknown
- v0.3.3+ deferred: TomSmart's `facilitator_inferred` field + empirical
probe (require external fixture data still pending Sunday)
`src/bazaar/indexing.ts`:
- Now accepts `manifest?: WellKnownManifest` for facilitator detection
- Short-circuits to `not_applicable_non_cdp` BEFORE network probe when
manifest declares non-CDP (fast, no HTTP cost, no false-positive)
- Every result emits `detail.indexer_state`: indexed | processing |
unknown | not_applicable_non_cdp
- 404 + empty resources both map to `processing` (matches Max's case
+ 0xdespot's bucket taxonomy from #2207)
- Legacy `detail.status` field preserved for backward-compat
`src/bazaar/propagation.ts`:
- Now also short-circuits to `not_applicable_non_cdp` when manifest
declares non-CDP (ADR-004 Pillar 3 consistency: both D.2 and D.3
honor the same attribution)
- `metadata_propagation` enum gains 5th value `not_applicable_non_cdp`
`src/bazaar/verdict.ts`:
- New `upstream_stuck` composite verdict (exit code 3, same as
upstream_issue; preserves CI contract)
- Synthesizer prefers `upstream_stuck` over `upstream_issue` when
indexer_state=processing fires
- `not_applicable_non_cdp` paths roll up to `looks_correct` (WAI per
ADR-004 Pillar 3)
`src/bazaar/types.ts`:
- `BazaarVerdict` union extended with `upstream_stuck`
- New `IndexerState` type
Tests: +22 new (8 facilitator-detect + 7 indexing state coverage +
2 propagation NA-non-CDP + 5 verdict upstream_stuck). Snapshot fixture
regenerated to include indexer_state on the indexing result. Existing
"upstream_issue when only indexing surfaces info" pipeline test
renamed + retargeted to upstream_stuck (the new attribution).
499 tests pass (was 477). 100 files / 389 KB / 0 devDep imports.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
v0.3.0 shipped at 96 files. PR #69 fixtures pushed to 100. v0.3.2 cycle adds (X402-44 json-api stability + X402-43 D.5 extensions-bazaar + X402-45 D.2 propagation + X402-46 D.3 facilitator-detect) bring it to 102 — over the v0.3.0-era cap. Raise to 110 with breathing room for X402-47 fixture consumption + future v0.3.x facets. Existing 400 KB unpacked cap unchanged (currently 389 KB, well below). Discovered when PR #81 (X402-46) CI failed on the publish-surface check; my local dist/ was stale and reported 100. Fresh local build matches CI's 102. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
X402-46 (D.3) — closes Max's polyodds.bet pain pattern: settles complete against CDP
/settlereturning{bazaar: {status: "processing"}}, but discovery shows 0 resources for the payTo — queue stalled. Per ADR-004 Pillar 1, this becomesupstream_stuck(distinct attribution from genericupstream_issuelike propagation drift or network errors).Also implements ADR-004 Pillar 3 facilitator-aware semantics across D.2 + D.3.
What this PR adds
New shared helper:
src/bazaar/facilitator-detect.ts"coinbase-cdp"/"cdp"/"coinbase"(case-insensitive) ascdp; any other non-empty string asnon-cdp; everything else asunknownfacilitator_inferredfield + empirical probe (require external fixture data still pending Sunday)Extended
src/bazaar/indexing.tsmanifest?: WellKnownManifestoption for facilitator detectionnot_applicable_non_cdpBEFORE network probe when manifest declares non-CDP (fast, no HTTP cost, no false-positive)detail.indexer_state:indexed|processing|unknown|not_applicable_non_cdpprocessing(matches Max's case + @0xdespot's bucket taxonomy from #2207)detail.statusfield preserved for backward-compatExtended
src/bazaar/propagation.tsmetadata_propagationenum gains 5th valuenot_applicable_non_cdpNew verdict:
upstream_stucksrc/bazaar/verdict.tssynthesizer prefersupstream_stuckoverupstream_issuewhenindexer_state: processingfiresupstream_issue, preserves CI contract per ADR-004 Pillar 1)not_applicable_non_cdppaths roll up tolooks_correct(WAI per ADR-004 Pillar 3)Acceptance criteria (X402-46)
not_applicable_non_cdpto theindexer_stateenum (4 states total: indexed, processing, unknown, not_applicable_non_cdp)not_applicable_non_cdp→looks_correct(NOTupstream_issue)upstream_stuckcomposite verdict; rolls up to exit code 3indexer_statefield on indexing detail### Added(D.3) +### Changed(indexer_state field on indexing) +### JSON APIsubsection (D.3 additive changes)v0.3.3+ deferred —
processing_freshvsprocessing_stalePer the X402-46 ticket, the original AC included staleness-threshold logic (
--processing-stale-after-hours, default 24h). Deferred because it requires settle-timestamp data x402trace doesn't collect without driving live settles or accepting operator-supplied evidence (a--settle-txor--last-settle-atflag). Filing as a v0.3.3+ follow-up; theindexer_state: processingvalue catches both fresh + stale cases under one bucket for v0.3.2 ship.Strict audit gate — abbreviated (user-in-loop mode)
7972da3(PR feat(X402-45): D.2 metadata propagation diff (5th check) #79 X402-45 D.2 merged HEAD); .gitignore WIP not staged--endpointmode), manifest with no extensions, facilitator field as non-string, whitespace-only facilitator value, case-insensitive CDP claim matching, short-circuit ordering (must precede payTo check), pipeline test rename (upstream_issue→upstream_stuck), backward-compat preservation of legacydetail.status, multi-result aggregation in verdict (indexing + propagation bothinfo), facilitator-detect helper'sunknowndefaultupstream_stuckverdict) + Pillar 3 (facilitator-aware semantics across D.2 + D.3) both honored; v0.3.3+ deferral on staleness threshold documentedWhat unblocks on merge
upstream_stuckfixture; anchor-x402's JPYC Polygon rail becomes the canonicalnot_applicable_non_cdpfixture once it's wiredv0.3.2 progress after merge
6 of 8 tickets done: X402-41 ADR-004, X402-42 D.4, X402-43 D.5, X402-44 JSON API stability, X402-45 D.2, X402-46 D.3. Remaining: X402-47 fixture consumption, X402-48 release cut. TomSmart's Sunday cdp-mature fixture drop ~24h out.
🤖 Generated with Claude Code