Skip to content

fix: the price sweep only ever saw one of two gateways - #97

Merged
VickyXAI merged 3 commits into
mainfrom
fix/prices-dual-chain
Aug 8, 2026
Merged

fix: the price sweep only ever saw one of two gateways#97
VickyXAI merged 3 commits into
mainfrom
fix/prices-dual-chain

Conversation

@VickyXAI

@VickyXAI VickyXAI commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Started as the price sweep #91 deferred. Became three things, because probing the second gateway changed what the first two should say.

1. verify:prices was blind to half the surface

BASE was hardcoded to blockrun.ai. Every "verified live" claim this repo has made was a claim about one of two gateways — and they do not agree:

Base Solana
every route base + $0.001 base + $0.000

Solana adds no transaction fee at all. Probed 2026-08-07 across 45 routes: 37 cheaper on Solana, 0 dearer, 8 not served there at all (all six modal routes 503, defillama 404, seedance-2.5@1080p 400 — that last is the already-tracked gateway defect).

They can diverge because they are separate deployments and TRANSACTION_FEE_USD is env-overridable in the gateway: the fee can move on one chain and not the other with nothing here noticing. Same shape as a marketplace check that never reads the skills directory — the tool whose whole job is this bug class could not see the case.

Direction decides severity, so they are counted separately:

  • Solana cheaper → safe. Estimators reserve the Base figure, so we over-reserve there. Reported, not fatal.
  • Solana dearer → every estimator under-reserves for that chain, exactly as fatal as a Base shortfall, since blockrun_wallet action:"chain" lets one agent switch mid-session. Exits 1.
  • Not served → reported per route; a chain switch turns those into a 404/503, not a cheaper call.

Both chains probe concurrently, so the second gateway costs no wall-clock.

2. blockrun_defi and blockrun_modal had no chain guard

Six other tools do. On Solana, modal 503s and defi 404s — the 503 reads as "sandbox is down" (plausible, wrong, invites a retry loop) and the 404 reads as a bad path, so the next move is to re-check the path rather than the chain. Both now fail fast and name the fix.

3. The price sweep itself

Every flat figure across eleven skills was base + $0.002 — the fee that has since gone back to $0.001. Corrected route by route against the live 402, not by subtracting $0.001, because several rows share a printed value while meaning different endpoints. That trap fired mid-sweep: crypto-data's RPC rows went $0.0040 → $0.0030 → $0.0020 when a later rule re-matched an earlier rule's output. Only a per-route audit caught it.

Two figures were wrong for reasons unrelated to the fee, and only probing found them:

  • The modal CPU billing cliff stops being cheaper at 360s, not the 432s claimed (probed: 300s $0.011000, 360s $0.011001, 361s $0.011028).
  • An 8s video clip is $0.421, not $0.402 — its base is $0.42, not the $0.05/sec × 8 the per-second table implies.

dFlow is removed: all three paths return Unknown Predexon endpoint 404 from the gateway itself — de-registered, not an upstream timeout. Gone from the description, triggers and route table (58 → 55 endpoints), from surf's coverage comparison, and from src/tools/markets.ts, which was advertising the same three dead routes to the model on every call.

On the one number the docs print

Prices in skills/ are Base prices. Rather than caveat eleven files with something we intend to delete once the gateways agree, that is stated once in skills/blockrun — the entry point every agent loads first. The open decision is whether to align the gateways (my recommendation: one number, since an agent can switch chains mid-session and a per-chain table doubles the drift surface this PR exists to shrink) or to keep them apart and qualify everywhere.

Verification

  • npm run typecheck, npm run build, 302/302 tests, sync-brand-numbers --check all green.
  • npm run verify:prices0 under-reserving, 0 Solana dearer, exits 0.

This script exists to catch price drift, and it was blind to half of it.
BASE was hardcoded to blockrun.ai, so every "verified live" claim it has ever
made was a claim about one of two gateways.

They do not agree. Probed 2026-08-07 across 45 routes: Base charges
base + $0.001, Solana charges base + $0.000 — Solana adds no transaction fee
at all, so 37 routes are cheaper there by exactly that amount. Eight more are
not served on Solana at all: all six modal routes 503, defillama 404, and
seedance-2.5@1080p 400 (that last one is the already-tracked gateway defect,
a different cause).

The gateways can diverge because they are separate deployments and
TRANSACTION_FEE_USD is env-overridable in the gateway — the fee can move on one
chain and not the other with nothing in this repo noticing. That is the same
shape as a marketplace check that never reads the skills directory: the tool
whose whole job is this class of bug could not see the case.

Direction decides severity, so the two are counted separately:

- Solana CHEAPER is safe for the budget gate. Estimators reserve the Base
  figure, so on Solana we over-reserve. Reported, not fatal.
- Solana DEARER would mean every estimator under-reserves for anyone on that
  chain, which is exactly as fatal as a Base shortfall — `blockrun_wallet
  action:"chain"` lets one agent switch mid-session. It now exits 1.
- NOT SERVED is reported per route, because a chain switch turns those calls
  into a 404/503 rather than a cheaper call.

Both chains are probed concurrently per route, so covering the second gateway
costs no wall-clock.
Neither tool had a chain guard, while price, video, image, speech, music and
realface all do. sol.blockrun.ai does not serve either route family: every
/v1/modal/* path 503s and /v1/defillama/* 404s (probed 2026-08-07 by the
dual-chain sweep, all six modal probes plus defillama).

So an agent that ran blockrun_wallet action:"chain" chain:"solana" earlier in
the session got a raw 503 from blockrun_modal, which reads as "the sandbox
service is down" — a plausible, wrong, unactionable conclusion that invites a
retry loop against a backend that was never going to answer. The defi 404 is
worse: it looks like a bad path, so the next move is to re-check the path
rather than the chain.

Both now say which it is and how to fix it, before the round trip, matching the
wording the six tools that already guard use.
…w is gone

Two defects, one sweep, both verified route by route against live 402 quotes
rather than computed.

PRICES. Every flat figure in the skills was base + $0.002, the per-transaction
fee that has since gone back to $0.001 — so each was a tenth of a cent high,
across eleven files. Agents read these to budget. Corrected against the
`payment-required` header on each specific route, because subtracting $0.001
everywhere is wrong: several rows share a printed value while meaning different
endpoints. That trap fired during this sweep — crypto-data's RPC rows went
$0.0040 -> $0.0030 -> $0.0020 when a later rule re-matched the output of an
earlier one, and only a per-route audit caught it.

Two figures were wrong for reasons unrelated to the fee, and only probing found
them: the modal CPU billing cliff stops being cheaper at 360s, not the 432s
claimed (probed 300s $0.011000, 360s $0.011001, 361s $0.011028), and an 8s
video clip is $0.421, not the $0.402 the table showed — its base is $0.42, not
the $0.05/sec x 8 the per-second table implies.

Prices are Base prices. Solana charges no transaction fee, so every figure runs
$0.001 lower there, and blockrun_defi and blockrun_modal are not served on it
at all. Rather than qualify eleven files with a caveat we intend to delete once
the gateways agree, that is stated once in skills/blockrun — the entry point
every agent loads first.

DFLOW. skills/prediction-markets advertised dflow/trades and the two
dflow/wallet/* paths. All three return "Unknown Predexon endpoint" 404 from the
gateway itself — de-registered, not an upstream timeout. Removed from the
description, the trigger list and the route table; endpoint count 58 -> 55; and
from surf's coverage comparison, which claimed dFlow as a Predexon advantage.

Also removed from src/tools/markets.ts, which listed the same three dead routes
in the tool description — so the model was being told they exist on every call,
not just when the skill loaded.
@VickyXAI
VickyXAI merged commit b00dcdb into main Aug 8, 2026
1 check passed
@VickyXAI
VickyXAI deleted the fix/prices-dual-chain branch August 8, 2026 02:47
VickyXAI added a commit that referenced this pull request Aug 8, 2026
VickyXAI added a commit that referenced this pull request Aug 8, 2026
#97 established that the two gateways disagree and guarded the two affected
tools in code, but the skills still described one catalog. An agent that ran
blockrun_wallet action:"chain" chain:"solana" earlier in the session had no
written way to know that two of the twenty tools stopped existing.

Probed against both gateways 2026-08-07:

- /v1/defillama/* is absent on sol.blockrun.ai — 404, which reads like a bad
  path, so the natural next move is to re-check the path rather than the chain.
- /v1/modal/* is present but unconfigured there — 503 on all four sandbox
  actions. That reads like an outage, which invites retrying against a backend
  that was never going to answer.

Both now say so where the tool is documented (crypto-data's defi section, the
modal skill's opening) rather than only in the core skill, because that is
where an agent is looking when it needs the answer.

The core skill grows a short section on what action:"chain" actually changes —
it repoints every paid call at a different deployment — with the coverage table
and both llms.txt URLs, since each gateway's catalog quotes its own pricing
convention. rules/wallet-and-payment.md carries the mechanics: why the budget
gate reserves the Base figure on both chains (over-reserving on Solana is the
safe direction) and that verify-prices fails the build if Solana ever becomes
the dearer one.
VickyXAI added a commit that referenced this pull request Aug 8, 2026
…ma (0.39.0) (#96)

* fix(video): tighten Seedance capability tables to token360's own schema (0.38.2)

Sibling of blockrun#353 and blockrun-sol#133. Yesterday's 0.38.1 tightened
the guards toward the gateway's tables; live probing (2026-08-07) shows those
tables were themselves hand-typed drift. token360 publishes the answer —
GET /v1/models/{id} → parameter_schema — and nobody had ever read it.

Per-model truth, now enforced here: 2.0 = 480p/720p/1080p/4K in BOTH modes
(the t2v/i2v split is gone; 540p/1K hard-reject upstream even
image-conditioned), 1.5-pro = 480p/720p/1080p, 2.0-fast and 2.5 = 480p/720p.
360p/540p/1K leave the resolution enum and 9:21 leaves the ratio enum — no
model lists them. Off-schema values that merely pass upstream validation
(2.0-fast 1080p, 1.5-pro 540p) stay blocked: "passes validation" is not
"renders", and 1.5-pro historically echoed 2K/4K, billed the tier, rendered
720p.

All probes cost $0: token360 validates duration → resolution → ratio →
other, so an invalid LATER parameter guarantees rejection after the one
under test is judged, and a failed submit never creates a task or bills.

RESOLUTION_TOKEN_FACTOR drops the unreachable tiers (the estimator throws on
a missing key, so stale is loud, not a silent 720p-baseline reserve). The
verify:prices matrix keeps 2.5@1080p as a fleet-consistency probe — the
gateway still quotes $3.55 for a render token360 refuses until #353 deploys
— and drops 2.0@360p, which this client can no longer express.

302 tests pass. Live gate: 0 under-reserving.

* fix(review): the acceptance side was silently revertible, and one assertion matched itself

Five-reviewer pass over this PR (testing, maintainability, api-contract,
Claude adversarial, Codex). What survived verification:

THE TESTS PINNED ONLY HALF THE TABLE — mutation-proven. Emptying 2.0-fast's
resolution set left the suite green: every rejection was tested, almost no
acceptance was, so an over-restrictive edit could brick a paid capability
with no red test. And the first fix draft iterated the exported table in the
test — mutating the table mutated the expectation, same two escapes. The
acceptance sweep now hardcodes the expected pairs (the test IS the spec) and
asserts deep-equality with the shipped table, both directions.

A FOURTH VACUOUS ASSERTION, mutation-proven: `/seedance-2\.0/` intended to
pin the advice pointer, but the message opens with "bytedance/seedance-2.0-
fast", which contains the pattern — deleting the pointer entirely stayed
green. Anchored on the note's phrasing now, and the note itself stops
steering 1080p seekers to the $2.56 model when 1.5-pro renders it at $0.80.

THE "BOTH MODES" CLAIM was carried by 360p — a value real callers can no
longer send (it left the zod enum), tested on the one model whose set holds
all four enum values. Re-adding an image-conditioned wide set in enum-valid
values (the production-reachable bill-high/render-low trap) passed. Now
pinned with 1080p/4K image-conditioned rejections per model; the 360p leg
stays as labeled defense-in-depth.

ASPECT_RATIO'S DESCRIPTION LIED (Codex): "Ignored by xAI/Sora" — the handler
forwards it for every model and the gateway maps it to portrait/landscape on
the per-second models. Description now says what happens.

0.38.2 -> 0.39.0 (api-contract): the enum removals are a deliberate breaking
schema change and were shipping as a patch. CHANGELOG's justification also
overclaimed — seedance-2.0 image-conditioned 360p DID produce billed output
before this release; reworded to the real rationale (off-schema shapes can
downscale while billing the requested tier).

Comment sweep: "per generation mode" (the mode split this PR deleted),
"cannot drift apart" (nothing mechanical enforces it — softened, and the
probe matrix now covers each model's ceiling and floor tier so divergence
shows up in the free 402 sweep: three new rows, including the only
above-720p tier that had no live pin, 1.5-pro@1080p, charge $0.797311 vs
reserve $0.798311), and a "2K" that never existed in this client.

303 tests, 6/6 mutations caught, live gate 0 under-reserving (16 video probes).

* fix(review): round 3 — the round-2 fixes hold; their prose didn't

A fresh-context regression hunt over 61e6993 (round 2's fix commit) plus a
manual pass. The code survived: four new mutations against the acceptance
table, the image-conditioned guard, the pointer note, and 2.5's set all went
red; the probe rows estimate cleanly; the semver bump is consistent. What
did not survive was the WORDS around the code — including one error round 2
introduced while fixing another:

- The aspect_ratio describe (and CHANGELOG) said "Sora/Grok use it to pick
  portrait vs landscape". Grok doesn't: submitXAIVideo builds its body from
  model/prompt/image_url/duration only — the gateway never forwards
  aspect_ratio to xAI. Round 2 replaced "both ignore it" (false for Sora)
  with "both use it" (false for Grok). Third try states each model's truth.

- The CHANGELOG's "previously accepted no-ops" was false for (Sora, 9:21):
  azureSoraSize treats 9:21 as a portrait trigger, so the removed value
  changed output orientation. 9:16 is the exact replacement, now said.

- "302 tests pass" was stale by round 2's own commit (303).

- The probe-matrix comment claimed floor+ceiling coverage per model while
  seedance-2.0@480p — after round 2, the only schema pair with no live
  pin — had no row. Added: charge $0.56874, reserve $0.56974, the fee gap.

- video.ts's table comment described unmerged blockrun PR #353 in the
  present tense. Until it deploys, production runs the old wide tables and
  this client is the only gate — the comment now says so.

303 tests, live gate 0 under-reserving (17 video probes).

* docs: record what #97 ships inside 0.39.0, and its dual-gateway view of the 2.5@1080p probe
VickyXAI added a commit that referenced this pull request Aug 8, 2026
#97 found the two gateways disagree on the transaction fee (Base $0.001,
Solana $0.000) and framed it as an open decision, recommending "align the
gateways". Owner decision (2026-08-08): the gap is DELIBERATE — Solana is
meant to run ~$0.001 cheaper per call as an incentive to settle there.

The sweep's advisory no longer tells the next maintainer to erase an
intentional price difference; it states the policy and the one invariant
that still matters: Solana DEARER than Base fails the gate, because agents
can switch chains mid-session while every estimator reserves the Base
figure. skills/blockrun's qualifier says "on purpose" instead of
"currently", so nobody reads the gap as pending cleanup.

No behavior changes — both surfaces are prose; the direction gate #97
shipped already encoded the right check.
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.

1 participant