docs(router): document BCK.ROUTER.0012 and 0013 - #304
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
c96de0a to
916a14e
Compare
…ct how the asset symbol is resolved (#305) * fix(router): qualify BCK.ROUTER.0006 in the windsurf rules, and correct how the asset symbol is resolved Two independent corrections, both true against nvm-monorepo main today — deliberately carrying no reference to any unreleased error code, so this can land on its own. 1. `.windsurf/rules/nevermined-router.md` wrote the retryable pair as bare `0006`/`0007` where its four sibling IDE rule files write `BCK.ROUTER.0006`. nvm-monorepo's `check-skill-error-drift` guard matches on the qualified form, so it has been reporting the code as undocumented — the ONLY drift between the published skill and `api-errors.ts` today, and it turns that check red on every nvm PR touching the error catalogue. 2. `products/router/rails-x402.mdx` said the asset symbol "is read from the entry's `extra.name` field". That is the pre-#2768 behaviour and has been false since nevermined-io/nvm-monorepo#2775: the symbol comes from the `asset` ADDRESS, matched against the canonical token addresses. The old text sends a reader debugging in exactly the wrong direction. Adds a short section on what `extra.name` actually is — the token's own EIP-712 domain, "USD Coin" on Base mainnet and "USDC" on Base Sepolia — since mistaking it for a ticker is what produced that bug. Split out of #304, which documents two error codes that do not exist until nvm-monorepo#2959 merges and therefore has to wait for it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: correct the windsurf headroom figure to 5,991 (review fold) This PR's edit to `.windsurf/rules/nevermined-router.md` grew it by 11 characters, so the figure CLAUDE.md pins was wrong the moment it landed. Re-measured with the exact command CLAUDE.md prescribes (characters, not bytes — `wc -c` reads 6,063 here because the file is full of `—` and `⚠️ `): base 237a9b5 = 5,980, head = 5,991. The payments sibling is unchanged at 3,759, verified the same way. The number is maintained precisely because the failure is silent: Windsurf drops the END of the file, where the guardrails live. Nine characters of headroom now remain, so the next edit to this file has to displace something rather than absorb it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
The two EIP-712 signing-domain refusals introduced by nevermined-io/nvm-monorepo#2959. Two codes rather than one because the same check fails for opposite owners: 0012 (400) is the seller advertising a domain its own settlement token does not sign under; 0013 (500) is a gap in Nevermined's canonical token table. Coding ours as the seller's told an agent to report OUR defect to an innocent counterparty, and buried the only signal that the table has drifted. Added to all 10 surfaces the drift guard holds to api-errors.ts, plus the rails-x402 page. Skill 0.1.2 -> 0.1.3.⚠️ MERGE AFTER nvm-monorepo#2959. The drift guard is bidirectional — diffErrorTable (scripts/lib/skill-error-table.ts:232) flags a code documented here that api-errors.ts does not define. Landing this first produces 4 stale drifts on nvm main, and publishes a skill telling autonomous buyers to branch on codes the API cannot return. Stacked on #305, which carries the two corrections that are independent of #2959. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Documenting BCK.ROUTER.0012 and 0013 pushed
`.windsurf/rules/nevermined-router.md` to 6,469 characters — 469 over
Windsurf's 6,000 cap, which truncates silently and drops the END of the
file, exactly where the guardrails live. The overflow would have shipped
unnoticed: nothing errors, the rules just stop.
The file could not absorb both codes. Measured, not estimated: at the
tersest honest wording, and after displacing every pure example the file
still had, two codes came to 6,054 — still over. So one had to go.
`0012` is the one omitted, and only from Windsurf:
- It is a **400**, and the file already states the rule that decides it —
"only 0006 and 0007 are retryable". Nothing is lost that the reader
cannot act on.
- `0013` is a **500**, the one shape an agent retries by default. That is
the same reason this copy keeps `0010` while omitting `0007`.
- Cursor, Cline, Amazon Q, Copilot, AGENTS.md and both table surfaces all
carry BOTH codes. Only the capped file diverges.
Displaced to make room, all presentation rather than rules, per CLAUDE.md
("what it trades away is presentation, never a rule"): the `category`
enum example, the spelled-out `payment.fee` column list, and the gloss on
`0007` — itself a declared omission on this surface.
Also updates the headroom figure to 5,994 (6 characters left) and records
the omission on the install page, so the promise the page makes to
readers stays true.
Needs the matching nvm-monorepo change to PROSE_SURFACES before the drift
check accepts it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
916a14e to
ee7dc7d
Compare
|
pr-coord:reviewing — automated fallback review in progress (no human claim after grace window). |
eruizgar91
left a comment
There was a problem hiding this comment.
Paired review with nevermined-io/nvm-monorepo#2969, which teaches the drift checker about the .windsurf omission this PR makes. Reviewed at ee7dc7d5a. No findings on this PR — everything below was checked and came back clean, and the four findings from the paired review all landed on #2969, where the code they concern lives.
What was verified, not read
- The 6,000-character claim, measured.
.windsurf/rules/nevermined-router.mdat this head is 5,994 characters / 6,068 bytes.CLAUDE.md's updated figure is exact, and the byte/character gap (74) is why awc -ccheck would have failed this file wrongly. - The paired change is clean end to end.
check-skill-error-drift.tsfrom #2969, run against this branch:✓ published skill matches api-errors.ts — 13 BCK.ROUTER codes across 2 table(s). - The claimed merge-order independence holds. #2969's checker against docs
mainreports 15 drifts;main's checker against this branch reports exactly one,[undocumented] BCK.ROUTER.0012 — .windsurf/rules/nevermined-router.md. Each PR really does clear the other, in either order. 0012really is absent and0013really is present in.windsurf, and both are present in.cursor(8,514 chars),.clinerules(8,439) and.amazonq(8,351) — none of which is anywhere near a cap, confirming the divergence is scoped to the one file that needed it.- Cross-surface consistency, machine-checked where possible.
SKILL.md,references/errors.md,AGENTS.md,.github/copilot-instructions.mdandproducts/router/guardrails.mdxall state0012= 400 non-retryable and0013= 500 non-retryable, matchingapi-errors.tson status and retry verdict — verified by parsing each table with the drift checker rather than by reading. The three uncapped IDE rule files carry byte-identical prose for both codes..windsurf's0013gloss is terser but states the same verdict, and the blanket "only0006and0007are retryable" rule is present and covers it. - No surface was missed. Every file in the repo mentioning
BCK.ROUTER.0011now carries both new codes, with the one declared exception. - Skill version
0.1.3/lastUpdated 2026-08-17is consistent in both places it appears; no stale0.1.2anywhere in the tree.
On the .windsurf trade-off
I argued the substance on #2969 rather than duplicating it here — short version: 0012 is the right code to give up, and for a firmer reason than the PR body gives. 0012's specific remedy is not actually lost to the agent at runtime: the catalogue hint ("…report it to them and pay a different seller meanwhile") ships in the error response body, independent of any rules file. What a rules file uniquely controls is the pre-arrival default, and for a 400 that default is already right. For 0013 it is wrong — a 500 is the one shape an agent retries before it ever reads the body, and no hint can undo a retry that already fired. Keeping 0013 is the correct half of the trade.
The one caveat, raised on #2969: that trade rests on the blanket retryable sentence staying in this file, and with six characters of headroom the next character-scavenging edit is likely to rewrite exactly that line.
Considered and deliberately not raised
- What was displaced — the
"Search & Research"enum example, the spelled-outpayment.feecolumn list, the "too many concurrent" gloss on0007. All three are presentation: the rule each supported survives (GET /api/v1/catalog/categoriesstill tells you to fetch the enum rather than guess it;fee.capChargedCentsis still named in the following sentence). This meetsCLAUDE.md's "trades away presentation, never a rule" bar. products/router/rails-x402.mdxreferences0012but not0013. Defensible — that section addresses the seller publishingextra.name/extra.version, and0013is our table's gap, not theirs.guardrails.mdxcarries it for buyers.development-guide/api-errors/codes.mdxdoes not yet carry0012/0013, soguardrails.mdx's "Every code below also appears in the canonical API error catalogue" is briefly false if this merges first. Not a defect here:codes.mdxis auto-generated and must not be hand-edited, and #308 — the sync PR for95a006f— is open with auto-merge on. Just worth landing it alongside.products/router/guardrails.mdxis not actually covered by the drift guard, contrary to this PR's description ("All 10 the drift guard holds toapi-errors.ts").TABLE_SURFACESholds two files,PROSE_SURFACESsix, and neither list contains it. It is a hand-maintained public table of retry verdicts with nothing pinning it. Raised as a finding on #2969, where the surface list lives, with a verified one-line fix — flagged here only because the claim is in this PR's body.Router codes vs published skillbeing red is expected, declared, and not a required check. Excluded.
No changes requested. The verdict is issued separately.
eruizgar91
left a comment
There was a problem hiding this comment.
✅ Approved — no blockers, nothing to address.
Inline review: #304 (review)
Documents the two EIP-712 signing-domain refusals introduced by nevermined-io/nvm-monorepo#2959 (merged as
95a006f66, closing nevermined-io/nvm-monorepo#2934).What #2959 does
The Router used to build the x402 EIP-712 signing domain's
name/versionfrom the seller's advertisedaccepts[].extra. It now sources them from its own canonical per-token table and holds the seller's advertised pair to it byte for byte.Why two codes, not one
The same check fails for opposite owners, and the first draft of this PR had a single code for both:
BCK.ROUTER.0012validationBCK.ROUTER.0013internalOne code meant our own table gap returned
400 validationwith a hint saying "this is the seller's bug, pay a different seller" — an error message that sends an operator down the wrong path.0013's hint says explicitly not to report it to the seller.Neither is retryable: both fail deterministically until someone fixes the underlying table, and in both cases nothing was signed, charged or reserved.
Surfaces
All 10 surfaces that restate the codes — plus
Also updated here: the
products/router/rails-x402.mdxsection #305 introduces, which gains the byte-for-byte check and the0012reference here.Skill bumped 0.1.2 → 0.1.3 with
lastUpdated: 2026-08-17, per the convention #299 set..windsurf/rules/nevermined-router.mdis at Windsurf's 6,000-character cap, which truncates silently and drops the end of the file — where the guardrails live. Adding both codes took it to 6,469. Measured, not estimated:Two codes do not fit at any wording. Rather than let it overflow, or cut a rule to make room — which
CLAUDE.mdforbids ("what it trades away is presentation, never a rule") — that one file omits0012by declaration.Why
0012and not0013:0013is a 500, and a non-retryable 500 is the one shape an agent retries by default — the same reason that file already keeps0010while omitting0007.0012is a 400 whose verdict the file still states as a rule ("only0006and0007are retryable").Only the capped file diverges. Cursor, Cline, Amazon Q, Copilot,
AGENTS.mdand both table surfaces all carry both codes.What was displaced to make room is presentation, never a rule: the
categoryenum example, the spelled-outpayment.feecolumn list, and the gloss on0007(itself a declared omission on that surface). The file is now 5,994 / 6,000 — 6 characters left, andCLAUDE.md's figure is updated to match.The omission is recorded on
development-guide/build-using-nvm-skill.mdx, which is the promise this makes to readers, and needs its matching checker change: https://github.com/nevermined-io/nvm-monorepo/pull/2969.Merge order
Both directions now clear each other, so there is no strict order between this PR and nvm#2969 — each leaves one advisory drift until the other lands.
Router codes vs published skillis not a required check.Verification
✓ published skill matches api-errors.ts — 13 BCK.ROUTER codes across 2 table(s).mintlify broken-links: no broken links found, whole site.🤖 Generated with Claude Code