Skip to content

Release v0.20.1 - #15

Merged
jdogresorg merged 41 commits into
masterfrom
release/v0.20.1
Sep 24, 2026
Merged

jdogresorg merged 41 commits into
masterfrom
release/v0.20.1

Conversation

@jdogresorg

@jdogresorg jdogresorg commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Release v0.20.1

Coordinated platform release across the 13-repo v0.20.1 train.

  • Base: master
  • Head: release/v0.20.1

What changes

  • Re-slides the v0.20.1 testnet activation train from 153221 to 154074, with BTC producer/consumer activation at 154234/154291, DOGE producer/consumer activation at 67942777/67944741, and ANCHOR_ATTEST_BARRIER_ACTIVATION at 154291; LTC:testnet mirror admission remains null under dq4 (a).
  • Uses exact arithmetic for BET feed days and coinpay plans, and reports mirror leg-amount consolidation as a per-leg error.
  • Emits TIS v1.1.1 documents from nft.tisDocument, refuses null identity fields, and makes sibling parity guards fail closed.
  • Forwards caller encoder options through bridge workflows, uses public-registry keyless discovery, and covers the published MCP and x402 fail-closed paths.

Sibling release PRs

Filled in by open-release-prs.sh --execute once every PR above has a number:

… the BTC instant

The v0.20.0 family was sized 2026-09-16 20:41Z from last-99-block cadences. LTC
testnet then ran at about 82 s per block against the 146.6 s that sizing assumed,
pulling its producer boundary to 3.2 h out while BTC's stayed 53.0 h out, and
DOGE's drifted 7.5 h early. Two legs of one cross-chain match would have crossed
the flag day about two days apart, which is what the same-wall-clock-instant rule
exists to prevent.

Re-measured 2026-09-17 22:45Z over a trailing window as long as the lead being
sized: TBTC 152,891 at 576.7 s per block, TLTC 4,889,190 at 82.5 s, TDOGE
67,904,912 at 27.7 s. BTC is unchanged, still keyed to epoch close 153,216 plus
6 buried; LTC and DOGE are converted onto that same instant, and each consumer
is its own producer plus six hours at its own measured cadence rather than a
block count carried over from the first sizing.

Arms the TRAIN_ACTIVATION 0.20.0 row at testnet 153,116, 106 blocks and about
17 h below the BTC producer. resolveRuleSet reads only the local map, so with no
row every block above the boundary keeps resolving under 0.19.0, and a manifest
naming 0.20.0 halts a fleet in which no build implements it.

Records the cadence-window rule the re-cut used and makes the re-size rule per
chain instead of BTC-keyed, so an LTC or DOGE drift past the six-hour ordering
margin forces a re-cut the way an overrun BTC height already does.
Load BATCH and ISSUE parity handlers from existing mapped handler
rows so directory refactors cannot silently skip the checks. Exercise
all mapped handler source parts and restore 94 SDK-to-indexer parity
cases to the live test count.
Point the coverage citation at test/unit/tooling/sibling_coverage.test.js, which
the feature-directory move left stale, and say plainly that ci-dispatch.sh is
shared tooling on the pushing host rather than a script in this repo. Record its
current fallback ladder: the pushed branch, then origin/master, origin/main,
origin/HEAD, then local HEAD.
The armed LTC:testnet producer/consumer heights (4891504/4891766) are
already behind the live TLTC tip. Ruling dq4 (a), 2026-09-18: LTC:testnet
mirror admission ships null on this train and arms on a later train.
Sets both heights to null in this repo's shared_rows_2.js twin, with the
same replacement comment used across all six carriers.
Tag pushes matching v* build and publish both the SDK and the MCP server.
Authentication is OIDC (id-token: write), so no npm token is stored in the
repository. The version gate fails the run when either package.json disagrees
with the tag, which stops a mistagged release before it reaches the registry.
Propagate the canonical v0.20.1 patch-train reslide into the sdk's
own copy of the shared consensus registry: BTC train height 153221,
BTC mirror producer/consumer 153300/153328 (producer also carries
ANCHOR_ATTEST_BARRIER_ACTIVATION), DOGE mirror producer/consumer
67916857/67917706. LTC:testnet stays null under dq4 (a) and is
untouched.
All five bridge recipes (bridgeLock, bridgeBurn, bridgeTokenLock,
bridgeTokenBurn, setTokenBridgeability) passed a literal empty object as
WalletSession.submit's encoder argument and handed the caller's whole opts
object to the submission slot instead. A caller asking for a feePerKb or for
unconfirmed inputs was silently ignored and the transaction went out at the
default fee rate, with no error to say so.

A submitBridge helper now splits opts.encoder out and forwards it as the
encoder argument, leaving the remaining keys as submission options. An opts
with no encoder key still yields the same empty object every recipe passed
before, so no existing caller changes behaviour.
43c77f6 moved keyless discovery from hub.getAllConfig() to hub.getDiscoveryConfig()
and the unit suites kept stubbing the old method, so discover() reached the real
network, failed, and left stale state: six unit failures that have held every sdk
landing at the push gate. The stubs, the two assertions and the HubConnector
descriptor fixture now name the live method. Full suite: 4797 passing, 0 failing.
CONSOLIDATION_LEG_AMOUNT_ACTIVATION was armed at genesis on every
network (including mainnet) by the 2026-09-09 ruling, removing the
false-block risk that kept checks/send.js merely declaring this rule
as unverified. checkSend and checkDestroy now raise AMOUNT_FORMAT_INVALID
per leg, gated on the tick's own decimals, instead of only naming the
rule; the declaration narrows to the residual case where a leg's token
row cannot be read.
…kipping it

A null field in `expected` used to `continue` past the comparison, silently
binding nothing for that identity field. That is never a legitimate
"don't care" (only a caller bug produces it), so it now throws; every
proof_checks.js call site already wraps expectedMismatch in try/catch and
fails closed to an unverified result. undefined (a field genuinely left out
of `expected`) is unchanged and still skipped. Adds a runnable unit case
(node src/protocol/light_client/fetch_helpers.js) covering both cases plus
the existing mismatch/match paths, since this file is the only writable
surface for the row.
…e sweep

Generated block: do not hand-edit it. Change the tier config and re-run the
tier wirer, which owns both this file and the hook so the two cannot drift.

The pre-push venue gate ran the whole GitHub transcript on every push, coverage
re-runs and perf scenarios included. That is the right set to grade a release
with and the wrong set to pay for on every push, especially while three venues
serve every repo on the platform: a long gate does not just cost its own
minutes, it forms a queue behind itself for every other session pushing that
hour.

A push now grades the fast tier. The tiers named in the generated block move to
the scheduled full sweep, which already runs against every repo every three
hours and before any release or deploy, so nothing stops being graded.

The verdict line is rewritten with it, which is the part that matters: a fast
run can no longer print "all tiers green (same set GitHub CI runs)". It prints
which tiers were deferred and states plainly that they were NOT graded there,
so a fast green can never be mistaken for a full one. The dispatcher's verdict
cache is keyed on repo + sha + cmd, so a fast green cannot stand in for a full
one either.
…onger lists it as absent

The light-client suite listed { tick: null } among the absent-field cases that must not change a verdict; the verifier now refuses a null field rather than binding nothing, so that case moves to its own test asserting the closed failure and its reason.
Use npm's canonical git+https form in both published package manifests so publishing does not require registry-side correction.
… sibling parity guards fail closed

tisDocument now requires the top-level name, writes the display-role enum into
images[].type rather than a MIME type, and validates both. The template parity
and sibling coverage guards resolve siblings through the advertised
XCHAIN_*_DIR overrides and fail under XCHAIN_REQUIRE_SIBLINGS=1 instead of
skipping green, and the vendored gate-registry byte-twin parts gain a
cross-repo identity check.
…nt spec citations and guard pins

The BET feed day count floors with integer math, the coinpay owed-vs-available
check is exact, TIS and NFT citations name the current spec pages, the light
client header quotes the real ANCHOR_ACTIVATION, guard mount-order pins track
runtime order, and the INDEXER-MAP review log records the W4 and W5 anchors.
…load path

middleware() now returns guard()'s result so a throwing verify() can be
asserted to fail closed (500, or 503 for X402_STATE_CORRUPT) with next
never called. mcp/test/ adds that coverage plus a pack+install check that
requires xchain-mcp/server.js via its published path, not the in-repo
relative fallback. publish.yml runs both packages' full ci tier
(SDK with sibling checkouts, mcp's own ci) ahead of publish.
… margin

Live testnet tips (TBTC 153698, TDOGE 67924122 at 2026-09-23T15:55Z)
have passed every height the 2026-09-19 reslide armed, so the freeze
preflight refuses them. The operator ruled a second reslide to 40 h
of margin to the nearest armed height at the fastest defensible
cadence (BTC least-squares bound 383.04 s/block, DOGE median 11
s/block), keeping the prior spacing.

Propagate it into the sdk's own copy of the shared consensus registry: BTC
train height 154074 (tip + 376 blocks, 40 h), BTC mirror
producer/consumer 154234/154291 (train + 160, 17 h; producer + 57, 6 h;
the consumer also carries ANCHOR_ATTEST_BARRIER_ACTIVATION), DOGE mirror
producer/consumer 67942777/67944741 (tip + 18655, 57 h, the same
instant as the BTC producer; producer + 1964, 6 h). LTC:testnet stays
null under dq4 (a) and is untouched.
Replace the opaque dq4 (a) decision label with a self-contained
explanation of why LTC:testnet mirror admission ships disabled on
this train. Comment text only; byte-identical to the other five
shared-row carriers.
…iling mean

Operator ruling D11 (a) 2026-09-23: producer moves from 67942777 to
67936053 and consumer from 67944741 to 67936888, the same-instant rule
computed off the 84h trailing block-time mean. BTC:testnet heights are
unchanged; their comments now also carry the 84h trailing mean cadence
bound. Byte-identical to the other five shared-row carriers.
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