Skip to content

feat(skills): add the nevermined-router agent skill - #267

Merged
r-marques merged 2 commits into
mainfrom
docs/router-skill-2595
Aug 3, 2026
Merged

feat(skills): add the nevermined-router agent skill#267
r-marques merged 2 commits into
mainfrom
docs/router-skill-2595

Conversation

@r-marques

Copy link
Copy Markdown
Member

Implements nevermined-io/nvm-monorepo#2595. Part of epic nevermined-io/nvm-monorepo#2268 (Router go-live) and the direct enabler for the autonomous-buy demo, nevermined-io/nvm-monorepo#2596.

What this adds

skills/nevermined-router/ — the machine-readable twin of the Router docs section, so an AI agent
can discover an external service and buy from it autonomously, given nothing but an API key.

It is the companion to nevermined-payments, pointed the opposite way:

Skill Your agent is…
nevermined-payments receiving money, or buying a Nevermined plan
nevermined-router spending money at external x402 / MPP services
skills/nevermined-router/
  SKILL.md                    the six-step buy loop + guardrails
  references/discovery.md     catalog filters, the ARD feed, choosing well
  references/paying.md        mode B, /proxy streaming, mode A, merchant auth
  references/bootstrap.md     API key, Delegation fields, funding the wallet
  references/errors.md        every code, what is retryable, what is refused
  references/ledger.md        records, summary, statuses, reconciliation

How it was written

Every fact is verified against the API source or probed against the live sandbox — not paraphrased
from prose. The catalog example is a real row (superhighway) pulled from a running environment,
not invented.

Three of those checks turned up things that cost real money if an agent gets them wrong, and
each is called out where an agent will actually hit it:

  1. targetUrl is the default endpoint's complete URL, not a base. For superhighway it is
    https://superhighway.walls.sh/search while endpoints[0].path is also /search — so the
    obvious targetUrl + endpoint.path yields /search/search. Verified across all 9 rows on a live
    environment: some targetUrls are full endpoint URLs, some are bare origins, and
    new URL(endpoint.path, targetUrl) is correct for both.

  2. requestId is an idempotency key, not a request counter. A fresh uuid4() per HTTP attempt —
    the default reflex, and what most examples of retry logic teach — is precisely how an agent
    double-spends. The skill says to derive it from the work instead.

  3. Budget is debited in whole cents, rounded up. So "1000 calls at $0.001 = $1.00" is wrong: it
    is $10.00. Sub-cent calls each burn a full cent.

It also documents the mode A / mode B asymmetries that are easy to get backwards: protocol is
advisory and auto-detected in mode B but required and authoritative in mode A; requestId
is required in mode B and optional in mode A.

Guardrails

The skill is explicit that a refusal is the system working. BCK.ROUTER.0003 (over cap) and
0009 (wallet short) are stop conditions to report, not obstacles to route around; only 0006 and
0007 are retryable. It states plainly that widening a Delegation — or minting a second one to
escape an exhausted one — defeats the entire mechanism, since that is the failure mode an
autonomous buyer is most likely to reason its way into.

Also in this PR

  • publish-skill-clawhub.yml becomes a matrix over both skills, publishing
    nevermined-router to clawhub.ai/skills/nevermined-router. Per-skill concurrency so the legs
    never queue behind each other, and fail-fast: false so one failing publish cannot block the
    other. The path filter widens to skills/**, which means a change to one skill also runs the
    other's leg — a no-op, because the existing "already published" branch handles it. Adding a third
    skill is now one matrix entry.
  • build-using-nvm-skill.mdx gains a short section explaining which of the two skills you want;
    the existing per-tool install steps work for either by swapping the directory name.

Testing

  • mintlify broken-linksno broken links found
  • Workflow YAML parses; both matrix legs and the templated concurrency group verified
  • All five references/*.md cross-links resolve
  • https://nevermined.ai/docs/products/router/overview (linked from SKILL.md) → 200

Note for reviewers

The skill deliberately says the Router cannot pay conventional SaaS APIs (Exa, Firecrawl,
Tavily…), because they never quote a per-request price on the wire. That is measured, not assumed:
across every rest/other service in the curated catalog set, none returns a 402, none emits a
payment header, and none serves a real x402 manifest — the ones that answer meaningfully return
401/403. Those rows are loaded unlisted for exactly this reason
(nevermined-io/nvm-monorepo#2600).

🤖 Generated with Claude Code

A machine-readable twin of the Router documentation, so an AI agent can
discover an external service and buy from it autonomously with nothing but an
API key. Companion to `nevermined-payments`, which covers the opposite
direction (receiving payments, buying Nevermined plans).

SKILL.md carries the six-step buy loop — API key → Delegation → funded wallet →
discover → pay → account — plus the guardrails an autonomous buyer must respect.
Five reference files cover discovery, paying, bootstrap, errors and the ledger.

Everything is verified against the API source and probed against the live
sandbox rather than paraphrased, including three things that cost real money if
an agent gets them wrong:

- `targetUrl` is the default endpoint's COMPLETE URL, not a base. For
  `superhighway` it is `…/search` while `endpoints[0].path` is also `/search`,
  so concatenating yields `/search/search`. Resolve with
  `new URL(endpoint.path, targetUrl)` instead.
- `requestId` is an idempotency key, not a request counter. A fresh uuid4 per
  HTTP attempt — the default reflex — is how an agent double-spends.
- Budget is debited in whole cents rounded up, so 1000 calls at $0.001 costs
  $10.00, not $1.00.

The skill is explicit that a refusal is the system working: 0003 and 0009 are
stop conditions, and widening or re-minting a Delegation to escape one defeats
the whole mechanism.

Also:
- publish-skill-clawhub.yml becomes a matrix over both skills, with per-skill
  concurrency and fail-fast disabled so one failing publish can't block the
  other. Adding a skill is now one matrix entry.
- build-using-nvm-skill.mdx explains which of the two skills you want.

Refs nevermined-io/nvm-monorepo#2595, epic nevermined-io/nvm-monorepo#2268

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@mintlify

mintlify Bot commented Aug 3, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
Nevermined 🟢 Ready View Preview Aug 3, 2026, 12:53 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@r-marques
r-marques marked this pull request as ready for review August 3, 2026 12:53
@r-marques
r-marques requested a review from a team as a code owner August 3, 2026 12:53

@aaitor aaitor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. This is the most accurate agent-facing documentation I've reviewed in this repo — every factual claim I could check against origin/main source is exactly right, including the three "costs real money" gotchas the PR calls out. The skill is well-structured (SKILL.md + 5 focused references), the guardrail framing ("a refusal is the system working", never widen a Delegation, one requestId per purchase) is exactly what an autonomous buyer needs, and the workflow matrix change is clean. No HIGH or MEDIUM findings.

Verification I ran — I reviewed inline rather than dispatching the agent panel: for a docs PR the load-bearing lens is factual accuracy against the API source, and a security/db/tdd panel adds nothing to Markdown. So I checked the claims directly against nevermined-io/nvm-monorepo@origin/main (4c98d817):

  • Error catalogue — 12/12 exact. All nine BCK.ROUTER.0001–0009 and three BCK.CATALOG.0001–0003 match libs/helpers/src/lib/output/api-errors.ts on HTTP status and retryability: 0001=400, 0002=409, 0003=402, 0004=404, 0005=409, 0006=500 (retryable), 0007=429 (retryable), 0008=403, 0009=402; catalog 404/500/400. The "only 0006/0007 are retryable" rule matches the retryable flags.
  • All 6 endpoints exist and are @Public() in router.controller.ts: POST route, ALL proxy, POST payments, POST payments/:id/settled, GET payments, GET payments/summary.
  • "409 carries the original paymentId" — confirmed in router.service.ts:126,314 ("Return the original paymentId so a mode-B retry can reconcile").
  • "Budget debited in whole cents, rounded up" ($0.001×1000 = $10.00) — confirmed: both atomicToCents (x402-exact.ts) and amountToCents (mpp-tempo.ts) use ceiling division (x + n − 1)/n, with the exact "sub-cent charge still reserves ≥1 cent" comment.
  • requestId ≤ 256@MaxLength(256) in both create-payment.dto.ts and proxy-request.dto.ts. Delegation create fieldsprovider/currency/spendingLimitCents(@Min(1))/durationSecs(@Min(1)) required, allowedRecipients/maxTransactions optional. Matches the bootstrap table.
  • Env-naming gotcha clean — no staging/staging_sandbox/.dev leakage; only api.sandbox.nevermined.app / api.live.nevermined.app (correct .app, per the prod-URL convention).
  • Workflow — matrix over both skills, per-leg concurrency + fail-fast: false, and the publish step captures the real exit code (STATUS=$?, not a masked pipe) with an idempotent "already published" no-op. Correct.
  • Over-engineering pass: lean already, ship. The cross-file repetition (stop-conditions, the requestId rule) is deliberate point-of-need redundancy for agents that load one reference at a time, not debt. The 2-entry matrix is the DRY choice over duplicated jobs. Net removable: ~0.
  • CI: 2 checks passing; Mintlify preview 🟢.

One watch-item for merge (not blocking) — left inline: the versioning comment says the CLI "auto-increments from the latest published version," but nevermined-router is a brand-new slug with no prior version. The merge-commit dry-run leg will confirm the first publish resolves a version; if it doesn't, seed it with --version 0.1.0 on the router matrix entry once.

Comment thread .github/workflows/publish-skill-clawhub.yml Outdated
Addresses aaitor's review note on #267. He flagged that the versioning comment
claims the CLI "auto-increments from the latest published version", which cannot
hold for a brand-new slug, and asked me to confirm rather than assume.

Confirmed against the CLI itself — `clawhub skill publish --help` documents
`--version` as "defaults to 1.0.0 or next patch". So the first publish does not
fail (his stated worry), but it also does not read the version out of SKILL.md
frontmatter: it would land as 1.0.0 while the skill's own frontmatter and its
rendered header say 0.1.0, and those would disagree permanently. 0.1.0 is the
honest number — the payments skill is still 0.x, and this skill has one
acceptance criterion (a real end-to-end paid call) not yet verified.

So his suggested remedy is right, for a different reason than either of us gave.
Adds an optional per-skill `version` to the matrix, set only on the router leg,
to be deleted after the first publish.

Threaded in with `if`, not `[ -n … ] && …`: both are equivalent in this position
(errexit ignores a failing non-final element of an && list — I asserted the
opposite first and my own test disproved it), but the && list's status is 1 when
the version is unset, so it would fail the step if ever moved to the last line.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@r-marques
r-marques merged commit 943f53f into main Aug 3, 2026
3 checks passed
@r-marques
r-marques deleted the docs/router-skill-2595 branch August 3, 2026 13:25
@r-marques

Copy link
Copy Markdown
Member Author

Watch-item closed with evidence — the first publish resolved correctly.

From the merge-commit run (30817857071), router leg:

SKILL_VERSION: 0.1.0
Published nevermined-io/nevermined-router
"version": "0.1.0"

Both legs green — nevermined-router published at 0.1.0, matching the SKILL.md frontmatter and the version rendered in the skill's own header, and nevermined was the expected no-op. Live at https://clawhub.ai/skills/nevermined-router.

The seed line has done its job. Per the comment I left on it, the next change to this skill should drop version: "0.1.0" from the router matrix entry so auto-increment takes over — leaving it pinned would make every future publish try to re-publish 0.1.0 and hit the "already published" no-op, silently freezing the skill at its first version. I'll fold that removal into the next PR that touches the skill (the #2596 demo work).

@eruizgar91 eruizgar91 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the new nevermined-router skill (6 files, 1083 lines), the ClawHub matrix workflow, and the install-page edit through three lenses (defects / repository invariants / conventions + history), then verified every candidate finding adversarially.

Verdict: REQUEST_CHANGES — one HIGH. The install page now promises that every install method works for the new skill by swapping a path, but the router counterparts of the per-IDE rule files don't exist, and the page's own curl commands write the 404 body to disk without failing. Findings are inline.

Conventions were read from CLAUDE.md and AGENTS.md, both of which govern the changed paths.

Checked and deliberately discarded:

  • The matrix workflow's "no-op" claim. Traced through the pinned clawhub@^0.22 CLI: cmdPublish fingerprints the files and short-circuits with status: "unchanged" (exit 0) before both auto-increment and the --dry-run branch, so the untouched leg neither reddens the run nor bumps a version. The unguarded dry-run step and the guarded final step are both fine. Job-level concurrency with ${{ matrix.slug }} is valid.
  • architecture.md not updated. The tracker is a dead letter — it self-reports "Last Updated: January 2026", and #264 (the entire 7-page Router section) and #266 (Exa) both skipped it. Not holding this PR to a rule the repo doesn't run.
  • erc4337-only phrasing in paying.md. products/router/rails-mpp.mdx:96 says the card rail is feature-flagged off, sandbox-only, "don't build against it in production yet" — so the simplification is defensible.
  • The Exa paragraph at SKILL.md:49. Real tension with #266 — that paragraph's only stated outcome is "tell the user it needs an account", with no off-ramp to nevermined-payments, while solutions/api-providers.mdx:13 in this same branch calls Exa the live reference where "no human touched it". But the Router exclusion itself is correct (Exa isn't in the catalog, isn't routable) and the billing description is fair about Exa-the-vendor, so this landed below the bar for a blocking comment. Worth a sentence pointing at /integrations/exa if you're touching the file anyway.
  • The catalog offset=5 example, and the fact that the catalog surface has no docs-site counterpart yet (#264 deferred discover-services).

No lint/typecheck/build findings — those run separately.

| **`nevermined-payments`** | **receiving** money, or buying a Nevermined plan | SDK integration, middleware, plans, credits — the rest of this page |
| **`nevermined-router`** | **spending** money at external services | Discovering services in the catalog, creating a spending Delegation, paying any x402 or MPP endpoint through the [Nevermined Router](/products/router/overview) |

Every install method below works for either — swap `nevermined-payments` for `nevermined-router` in the paths. Installing both is fine; they don't overlap.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HIGH — "Every install method below works for either — swap nevermined-payments for nevermined-router in the paths" holds for 2 of the 8 install tabs on this page. The PR adds only skills/nevermined-router/**; there is no router counterpart in .cursor/rules/, .windsurf/rules/, .clinerules/ or .amazonq/rules/ (each contains exactly one file, the payments one), and the GitHub Copilot and Codex CLI tabs point at .github/copilot-instructions.md and AGENTS.md — single payments-only files with no skill-name segment to swap at all.

The failure is silent, not loud. Every curl on this page uses -o with no -f/--fail:

curl -o .cursor/rules/nevermined-router.mdc \
  https://raw.githubusercontent.com/nevermined-io/docs/main/.cursor/rules/nevermined-router.mdc

raw.githubusercontent returns 404, curl exits 0, and the literal string 404: Not Found is written into the rule file. Cursor then loads it as a valid rule for every .ts/.js/.py file and the assistant has zero Router knowledge — with no error anywhere to say so. Same for Windsurf, Cline and Amazon Q. Copilot and Codex users get payments guidance while believing they installed Router guidance.

The "Supported Tools at a Glance" table further down (lines 215-223) still lists payments-only paths for all 7 tools, so the page contradicts its own new claim two screens later.

Two ways out:

  • Scope the sentence to the methods that actually work (Claude Code and the manual/GitHub-blob tab), and say plainly that the per-IDE condensed rules are payments-only for now.
  • Or add the condensed router rule files.cursor/rules/nevermined-router.mdc, .windsurf/rules/nevermined-router.md, .clinerules/nevermined-router.md, .amazonq/rules/nevermined-router.md — which is what CLAUDE.md asks for: "IDE-specific files (.cursorrules, .cursor/rules/, .github/copilot-instructions.md) contain condensed versions of the skill and should be updated when core patterns change." Then update the glance table too.

Either way, adding --fail (or -fsSL) to the curl commands on this page would turn a corrupt-file-on-disk into an error the user can see.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed and fixed in #269 — thank you, this was a real trap and the silent-failure framing is what made it worth fixing properly rather than just softening the sentence.

Reproduced your failure mode before touching anything:

curl -s  -o probe.mdc  .../.cursor/rules/nevermined-router.mdc   → exit=0   file: [404: Not Found]
curl -sf -o probe2.mdc (same URL)                                → exit=22  file: not created

I took your second option rather than the first — made the claim true instead of retracting it. Condensed router rules now exist for Cursor, Windsurf, Cline and Amazon Q, generated from one shared body so they can't drift. Your CLAUDE.md citation is what decided it.

Two things your review didn't mention that fell out of doing it:

  1. The Windsurf tab documents a 6,000-character limit per rule file. My first draft was 6,057 and would have been over. Trimmed to 5,292–5,457 across all four.
  2. .gitignore had a blanket /.cursor, so .cursor/rules/nevermined-router.mdc would have been silently left out of the commit — shipping the exact 404 we're fixing. It only surfaced because the file was missing from git status. nevermined-payments.mdc survives it only because it was tracked before the rule existed. Narrowed to /.cursor/* + !/.cursor/rules/ and verified both directions.

For Copilot and Codex CLI you're right that there's nothing to swap, so the page is now explicit that those two are payments-only and points at the full skill. The glance table gained a Router column. --fail added to all six commands.

Guard against the whole class: the PR verifies that every raw.githubusercontent URL on that page resolves to a real, committable file (10/10, git check-ignore included so an ignored file can't pass as present).

"protocol": "x402",
"resourceUrl": "https://agent.example/paid",
"requestId": "order-1234",
"target": { "x402Version": 1, "accepts": [ /* verbatim from the 402 */ ] }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOW — The mode A worked example pairs a v1 request with a v2 response. Line 166 mints with "x402Version": 1, the response block at lines 184-185 comes back "x402Version": 2 with credential.name: "PAYMENT-SIGNATURE" — and the mapping table 14 lines later says v2 → PAYMENT-SIGNATURE, v1 → X-PAYMENT. Both blocks sit inside the same numbered step ("### 2 · Mint the credential"), so a reader takes them as one request/response pair and learns the wrong version→header mapping.

No runtime harm: line 203 already says "Read the name off the response rather than hardcoding it", and an agent that follows that attaches the right header regardless. This is a comprehension defect in a file that gets copied verbatim into agent context, in the one step where the header name decides whether an already-minted, already-reserved payment is accepted.

One-token fix: drop "x402Version": 1 from line 166 (it defaults to 2 per the table at line 174), or flip the response block to v1/X-PAYMENT.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #269. You're right, and I'd introduced it.

I took the second of your two options — flipped the response block to v1 rather than dropping "x402Version": 1 from the request — so the step reads as one coherent v1 round trip (x402Version: 1name: "X-PAYMENT"), and added a line right after saying a v2 target returns PAYMENT-SIGNATURE instead. That keeps the request block illustrating the non-default case, which the field table immediately above deliberately calls out ("defaults to 2; set 1 for x402-express") — dropping the field would have lost that.

Agreed on severity: no runtime harm, since line 203 already says to read the name off the response. But "comprehension defect in a file copied verbatim into agent context" is exactly the right bar for this file, and the step where the header name decides whether an already-minted, already-reserved payment is accepted is the wrong place to make a reader infer the mapping.

r-marques added a commit that referenced this pull request Aug 4, 2026
…269)

* fix(skills): add router IDE rule files and stop silent 404 installs

Follow-up to #267, addressing @eruizgar91's REQUEST_CHANGES review, which
landed ~8 minutes after that PR merged.

HIGH — the install page claimed "every install method below works for either,
swap nevermined-payments for nevermined-router in the paths". That held for 2 of
8 tabs. There were no router counterparts under .cursor/rules/, .windsurf/rules/,
.clinerules/ or .amazonq/rules/, and Copilot/Codex load a single file with no
skill-name segment to swap at all. The failure was silent: every curl on the page
used -o with no --fail, so a 404 exits 0 and writes the literal string
"404: Not Found" into the rule file. Cursor then loads that as a valid rule and
the assistant has zero Router knowledge, with nothing anywhere saying so.
Reproduced before fixing: curl -o -> exit 0, file contains "404: Not Found";
curl --fail -> exit 22, no file.

Rather than retract the sentence, made it true:
- Adds condensed router rules for Cursor, Windsurf, Cline and Amazon Q, all
  generated from one shared body so they cannot drift, and all under the
  6,000-char Windsurf limit the page documents (5,292-5,457; the first draft
  was 6,057 and had to be trimmed).
- Scopes the claim honestly for Copilot and Codex CLI, which genuinely cannot be
  swapped, and points those users at the full skill.
- Adds --fail to all six curl commands, and router download commands to the four
  tabs that support them.
- Updates the "Supported Tools at a Glance" table, which still listed
  payments-only paths and contradicted the new claim two screens later.

Root cause of the missing Cursor file, caught pre-commit: .gitignore had a
blanket `/.cursor`, so the new rule would have been silently left out of the
commit and shipped as the very 404 this PR fixes. nevermined-payments.mdc only
survives it because it was tracked before the rule existed. Narrowed to
`/.cursor/*` + `!/.cursor/rules/` so published rules track normally while local
Cursor state stays ignored; verified both directions.

LOW — the mode A worked example paired a v1 request with a v2 response, teaching
the wrong version->header mapping in the one step where the header name decides
whether an already-minted, already-reserved payment is accepted. Now a coherent
v1 round trip, with a line noting what v2 returns instead.

Also, per @aaitor on #267: drops the one-shot `version: "0.1.0"` seed now that
the first publish has happened, so auto-increment takes over (leaving it would
re-try 0.1.0 forever, hit the "already published" no-op, and freeze the skill).
Bumps the skill to 0.1.1 to match. The SKILL_VERSION plumbing stays for the next
new slug.

And @eruizgar91's noted tension on the Exa paragraph: it now points at the
out-of-band rail (/integrations/exa, a $7 card-delegation purchase of Exa API
credits) instead of dead-ending at "tell the user it needs an account".

Verified: every raw.githubusercontent URL on the install page resolves to a real,
committable file (10/10); mintlify broken-links clean; workflow YAML parses with
both matrix legs on auto-increment.

Refs nevermined-io/nvm-monorepo#2595

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs(skills): fold in @eruizgar91's discarded-but-correct review points

He approved and explicitly rated these below the blocking bar. Two are genuine
inaccuracies in prose I wrote, so they're worth fixing rather than shipping.

1. Codex CLI is NOT "nothing to swap". Verified: its tab already documents an
   `.agents/skills/` install, which takes a skill DIRECTORY. Only Copilot is
   truly single-file. Split the bullet, added the router `cp` line to that tab,
   and corrected the glance table from "No" to "Yes — via `.agents/skills/`;
   not via AGENTS.md".

2. `lastUpdated` now moves with the version (0.1.1 / 2026-08-04), matching how
   the sibling skill treats the pair.

Also fixes the stale IDE-surface inventory in CLAUDE.md that he flagged as
out-of-scope. It named a `.cursorrules` that does not exist and omitted
`.windsurf/rules/`, `.clinerules/` and `.amazonq/rules/` entirely — the same rule
I cited when justifying this PR, so leaving it wrong would mislead the next
person the same way. Replaced with a verified table (both skills present in all
four rule dirs; Copilot + AGENTS.md single-file), the `.gitignore` re-include
rationale, and a pointer to keep the install page and its glance table in sync.
Also corrects "7 reference files" — payments has 12, router has 5. Every number
and path in that table was checked against the tree, not carried over.

Deliberately NOT folded in, agreeing with his assessment: the condensed rule
files stop at the Exa dead-end without the out-of-band off-ramp (an omission in
a size-capped surface, and Windsurf is already at 5,240 of 6,000 chars), and the
CLAUDE.md v2-headers rule governs the Payments SDK server surface rather than
the Router paying a merchant whose version is the merchant's choice.

mintlify broken-links: clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

3 participants