docs: multistore storefront routing proposal — per-offer origins, offer route table, CR-owned agent config#709
Draft
bussyjd wants to merge 1 commit into
Draft
Conversation
…er route table, CR-owned agent config Battle-tested learnings from operating a live paying multistore (3 x402 offers on per-offer subdomains, agents as paying buyers), reviewed against main @ be0a237 with every claim code-cited and adversarially verified (72 findings, 0 refuted). Headline decision: the x402 market is origin-keyed (x402scan/agentcash crawl per-origin openapi) while the stack is path-keyed (shared-origin /services/<name> + one aggregate openapi) — per-offer origins must land before the URL contract calcifies. Plus: spec.routes[] as the single route table, Agent CRD runtime-config ownership (ends the hermes-config wipe), freePaths/limits, reconcile safety for live-revenue clusters, and a table of 13 verified mechanical fixes. Claude-Session: https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1
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.
What this is
Design proposal distilled from operating a live, paying multistore on obol-stack:
three x402-gated offers (90-route trading-intelligence REST API, solar-economics API,
public Hermes agent at $/turn), each on its own subdomain, with agents as paying
buyers of sibling offers. Reviewed against main @
be0a237; every claim isfile:line-cited and was adversarially verified (72 findings, 0 refuted).
Why now
The x402 market is origin-keyed; the stack is path-keyed. x402scan/agentcash
group and crawl per-origin (
GET <origin>/openapi.json), while main hard-wiresshared-origin
PathPrefix /services/<name>routes and ONE aggregate openapi. Anycrawler sees every offer on a stack mixed into one listing (the "3-service leak" we
hit live). Making a real store today takes ~16 hand-built HTTPRoutes + a static
discovery ConfigMap + a middleware that reconciles actively fight (force-SSA,
catch-all storefront route, template steamroll).
The URL contract (
/services/<name>, catalog links, ERC-8004 endpoints) is whatbuyers and indexers bind to — reversing it later is a breaking migration. This is
the decision to get right before teams build on it.
Proposals (full detail in the doc)
spec.hostnameon ServiceOffer; hostname-scoped route +per-offer openapi +
/.well-known/x402+ landing; tunnel hostname↔offer binding;storefront catch-all opt-out;
identityReffor per-offer ERC-8004.spec.routes[](oropenapiRef) as the single sourcedriving openapi, verifier rules (per-route pricing, free paths), typed MCP tool
catalog (marries the existing in-band x402mcp), and skill.md — kills the
stream:true-in-4-surfaces drift class.spec.mcpServers/maxTurns/toolTimeouts(downstreamimpl exists:
5427f4d) +obol.org/config-unmanaged; ends the hermes-config wipe(bit us twice mid-incident); paid-agent-safe defaults; key out of checksummed
config; config-seed merges instead of clobbering.
spec.limits {maxInFlight, rps}rendered as Traefik middleware (client already wired, unused);free public agents (
price 0→ bearer-injection route).stack up --dry-run+live-services gate; SSA without Force + one
unmanagedannotation; operatorimage-pin overlay (also:
hermesImage()ignores theHERMES_IMAGEenv its owncomment promises); split verifier/controller out of the
baserelease; backupsweep of operator routes/middlewares.
unlogged
no_matching_requirement402s, ForwardAuth query-string free-pass,verifier route-sort specificity, reserved-path denylist,
accepts[]missingscheme/maxTimeoutSeconds, settle-failure double-execution hazard, etc.What main already got right (verified, credited in the doc)
Inline paid-gateway with settle-after-success, v1+v2 payment headers (+tests, in the
pinned image), structurally-free shared discovery routes, paid-agent key injection,
fail-closed prefixes, down/purge gates, catalog de-flapping, SOUL adversarial
section, logo/contact preflights, in-band paid-MCP.
Evidence
Appendix contains the sanitized live manifests this proposal generalizes — serving
paid USDC traffic on base for weeks.
https://claude.ai/code/session_01VquWN9UMaSHH7MHGcG8bw1