Skip to content

fix(video): close the three money-path holes 0.38.1 left documented (0.39.1) - #101

Merged
VickyXAI merged 2 commits into
mainfrom
fix/video-money-path
Aug 8, 2026
Merged

fix(video): close the three money-path holes 0.38.1 left documented (0.39.1)#101
VickyXAI merged 2 commits into
mainfrom
fix/video-money-path

Conversation

@VickyXAI

@VickyXAI VickyXAI commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Closes the three pre-existing blockrun_video holes the 0.38.1 review documented as "known and unfixed". All are money-path: each one either lets USDC move unvalidated or lets the ledger lie about USDC that moved.

# Hole Fix Pinned by
1 Unparseable 402 amount → re-reserve skipped, raw amount signed, estimate booked — the last way past the budget cap Fail closed before signing ("no charge was made") 6 malformed shapes: nothing signed, 1 fetch, reservation released
2 image_url/last_frame_url had no SSRF guard (blockrun_image has one) http(s)-only + isBlockedFetchHostResolved (resolved, not literal — catches 127.0.0.1.nip.io) before payment 4 hostile shapes refused with zero network calls; public https still flows
3 Malformed completed poll → throw → finally releases reservation while the USDC already settled — ledger silently under-counts, cap silently rises Book the spend the instant completed is observed, before payload validation; caller still gets the error malformed-completed keeps $0.40 booked; failed books nothing; happy path books exactly once

Honest note: the first draft of fix 3 double-booked the happy path (a replace guarded the wrong recordActualSpend occurrence). The new suite's exactly-once ledger assertion caught it pre-commit — the tests assert on money, not messages, for exactly this reason.

Verification: 309/309 tests · typecheck green · no estimator or guard-table changes (verify:prices unaffected).

Merging publishes 0.39.1 to npm + the MCP registry.

All three were flagged by the 0.38.1 review, recorded in that CHANGELOG as
"known and unfixed", and pre-existing since well before the Seedance work.

1. UNREADABLE 402 -> FAIL CLOSED. amountToUsd returning null used to skip
   the re-reserve, sign the raw unvalidated amount, and book only the
   estimate — the last way past the budget cap. Now it aborts before
   createPaymentPayload with "no charge was made". Pinned: nothing signed,
   one fetch (the quote), reservation released, for six malformed shapes.

2. SSRF GUARD on image_url / last_frame_url, mirroring blockrun_image:
   http(s)-only schemes, then isBlockedFetchHostResolved on the hostname —
   resolved, not literal, so 127.0.0.1.nip.io-style names are caught. The
   MCP never fetches these itself; the gateway does. Defense-in-depth plus
   a saved paid round trip. Pinned: four hostile shapes refused with ZERO
   network calls; a public https URL still flows.

3. BOOK ON SETTLEMENT OBSERVATION. The gateway settles on the first poll it
   answers "completed"; the old path validated the payload first, so a
   completed body missing its clip URL threw, and finally released the
   reservation — real USDC spent, ledger unchanged, cap silently raised.
   Booking now happens the instant "completed" is observed. Pinned: the
   malformed-completed case keeps $0.40 in the ledger while still erroring;
   "failed" still books nothing.

The first draft of fix 3 double-booked the happy path (poll site + old tail
call — a replace hit the wrong occurrence). The new suite's exactly-once
ledger assertion caught it before commit, which is the whole argument for
asserting on money, not messages.

309 tests pass, typecheck green.
@VickyXAI
VickyXAI merged commit 1a2ea75 into main Aug 8, 2026
1 check passed
@VickyXAI
VickyXAI deleted the fix/video-money-path branch August 8, 2026 05:30
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