feat(X402-45): D.2 metadata propagation diff (5th check)#79
Merged
Conversation
Closes the @zev / TheRoosters / GM pain pattern: manifest is correctly shaped, indexer drops fields, listing renders blank. v0.3.0/0.3.1 had no signal for this — the verdict came back looks_correct (since well-known + challenge passed), even though the operator's service was effectively invisible on Bazaar. New `propagation` check (5th in results): - Queries CDP discovery for the service's payTo (reuses the same endpoint as the existing indexing check) - Diffs manifest fields (name, description) vs resource fields in the discovery response - Emits detail.metadata_propagation: ok | partial | missing | unknown - ok → status pass (all diffed fields match) - partial → status info + detail.diff[] (some drift, surface to operator) - missing → status info (the @zev pattern: manifest correct, indexer shows nothing — matches the canonical #2207 indexer-state cluster) - unknown → status pass (defensive default for --endpoint mode, missing payTo, network errors, non-JSON responses, empty resources) Facilitator-aware semantics deferred to D.3 (X402-46) per ADR-004 Pillar 3: D.2 returns `unknown` for services not in CDP discovery rather than attributing non-CDP without explicit detection logic. D.3 layers the explicit `not_applicable_non_cdp` state on top. Snapshot test workflow demonstrated: - Adding the 5th check fired the snapshot test (intentional shape change) — exactly what X402-44 designed it to do - Snapshot fixture regenerated to include the 5th result - CHANGELOG ### JSON API subsection documents the additive change - The "5 canonical checks in fixed order" invariant test was updated (was "all four canonical") - Pipeline integration test's mock discovery response was updated to include name + description so propagation returns ok by default (preserves the existing happy-path assertions) Tests: 477 pass (was 466); +15 propagation unit + ≥3 integration adjustments. 98 files / 370 KB / 0 devDep imports (under cap). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
7 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-45 (D.2) — adds the
propagationcheck (5th in the results array). Closes the @zev / TheRoosters / GM pain pattern: manifest is correctly shaped, indexer drops fields, listing renders blank. v0.3.0/0.3.1 had no signal for this — the verdict came backlooks_correct(since well-known + challenge passed) even though the service was effectively invisible on Bazaar.What this PR adds
New module
src/bazaar/propagation.tsexportingcheckPropagation(manifest?, payTo?, opts). The orchestrator runs it as a 5th step after well-known / challenge / self-payment / indexing.Diff scope (narrow on purpose):
name,description. These are the fields the three named pain reports all hit. Extending the field set is a future refinement when more pain shapes surface.Emits
detail.metadata_propagationwith one of four states:okpartialdetail.diff[]lists per-field mismatchesmissingunknown--endpointmode (no manifest), no payTo, network error, non-JSON response, or empty resourcesThe
infostatuses (partial / missing) roll up via the existing verdict synthesizer toupstream_issueexit code 3 — same path as the existing indexing check.Facilitator-aware semantics — layered split
Per ADR-004 Pillar 3, non-CDP services should produce
metadata_propagation: not_applicable_non_cdp. This PR keeps D.2 narrow and returnsunknownfor services not in CDP discovery; D.3 (X402-46) layers the explicitnot_applicable_non_cdpstate on top via its facilitator-detection pass. The two tickets stay independently testable.Snapshot test workflow — demonstrated end-to-end
X402-44 (JSON API stability, just merged) designed the snapshot test to fail on intentional shape changes. Adding the 5th check fired the snapshot test as designed:
expected 4 results, got 5+ key-order tests failedtests/fixtures/bazaar/json-api-snapshot.jsonto include the 5th result### JSON APICHANGELOG subsection documenting the additive changeThis is the maintainer workflow X402-44 was built for, working as intended.
Acceptance criteria (X402-45)
metadata_propagationfacet implemented with four states (ok,partial,missing,unknown)detail.diffpopulated with field-by-field mismatches on partial/missing statesmetadata_propagation: missingwith diff showing the dropped fields### JSON APICHANGELOG entry addedcomputePropagationStatushelper)[Unreleased]### Addedentry documenting the new checkStrict audit gate — abbreviated (user-in-loop mode)
61de55e(PR feat(X402-44): JSON API stability — snapshot test + contract doc + versioning rule #78 X402-44 merged HEAD); .gitignore WIP not staged--endpointmode), missing payTo, network error, 5xx, non-JSON body, empty resources, whitespace-only manifest fields (treated as null), multi-resource (uses first), partial drift, all-fields-dropped (missing path)not_applicable_non_cdpon top); cross-references to X402-46 + ADR-004 presentWhat unblocks on merge
indexer_statefacet alongside D.2'smetadata_propagation; D.3's facilitator-detection pass can decorate D.2'sunknownresult withnot_applicable_non_cdpwhen detection succeedsapi.lastlookdata.combecomes the canonical fixture for themissingpath; TomSmart's cdp-mature drop will cover theokpath across multiple cdp-verified services🤖 Generated with Claude Code