Skip to content

fix: unpin the platform protocol version so clients auto-detect - #113

Merged
thephez merged 8 commits into
dashpay:mainfrom
thepastaclaw:tracker-2594
Aug 4, 2026
Merged

fix: unpin the platform protocol version so clients auto-detect#113
thephez merged 8 commits into
dashpay:mainfrom
thepastaclaw:tracker-2594

Conversation

@thepastaclaw

@thepastaclaw thepastaclaw commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Closes #112.

The problem

PLATFORM_VERSION_OVERRIDE was pinned to 12 while testnet has been running protocol version 13 since late July. A pin is not a floor — in rs-sdk the version ratchet returns early when version_pinned is set, so a pinned client stays on the old version silently: no error, no warning, no matter what the network reports.

The constant's own TODO said to remove it once dashpay/platform#3809 landed in the consumed SDK. That condition is now met.

Why remove rather than bump to 13

Bumping re-arms the identical trap for protocol version 14 and leaves the failure mode intact — invisible, and (before this PR) unobservable in CI. Removing the pin is what the TODO prescribed, and auto-detection is verified working in the consumed release.

Measured against @dashevo/evo-sdk@4.1.0 and live testnet:

client config sdk.version() after connect() after first proof-bearing read
unpinned 12 13
{ version: 12 } 12 12
{ version: 13 } 13 13

Testnet reports protocol.drive.current = 13; the SDK's own ceiling (EvoSDK.getLatestVersionNumber()) is 13. So an unpinned client negotiates up to the network's active version, capped at what the SDK understands — exactly the #3809 behavior.

Changes

  • Remove the pin. createClient() no longer passes version to testnetTrusted / mainnetTrusted / localTrusted.
  • Delete platformVersion.mjs / .d.mts. The module existed only to hold this constant.
  • Example apps pass sdk.version() to document.toJSON(...) instead of the constant (dashnote, dashnote-starter, dashrate). That reflects the negotiated version and cannot go stale. DashSdk in each app gains version(): number.
  • Standalone lite pages are aligned with SDK 4.1.0. dashmint-lite.html carried the same defect independently — pinned to 11, with a comment pointing back at this constant — so it is unpinned. DashMint, Dashnote, DashRate, and DashProof lite pages now import the same Evo SDK version as their companion apps.
  • Focused regression suites run in PR CI. test:read-only remains tutorial-only; npm test adds separate protocol-negotiation, factory-configuration, and lite-page SDK-version checks.

Regression coverage

The pin was invisible to CI before this PR: pull requests ran only test:read-only, and that suite passed against a PV-13 testnet with the client stuck on 12 the whole time. Nothing asserted the negotiated version.

The coverage is split by concern so test/read-only.test.mjs remains strictly a tutorial suite:

  • test/platform-version.test.mjs performs a proof-bearing DPNS read on both testnet and mainnet, then asserts that each client settles on min(network active version, SDK ceiling). This accommodates a network upgrading ahead of the installed SDK without hiding a stale pin. The testnet case was also verified to fail with { version: 12 } restored.
  • test/platform-version-config.test.mjs spies on testnetTrusted, mainnetTrusted, and localTrusted and asserts that every factory is called with zero arguments. This directly catches any reintroduced { version: ... } option even while a pin happens to equal the network's current version.
  • test/lite-sdk-versions.test.mjs checks that every standalone lite page imports exactly the Evo SDK version declared by its companion app.

npm test runs these focused checks alongside the read-only tutorials, and the PR workflow now calls that aggregate. None of the new checks needs credentials or funds; the live negotiation fixture is the DPNS system contract.

Validation

All against Node 22.22.0, matching the .nvmrc 22.22 release line and package engine constraint.

gate result
npm run lint (tsc) pass
npm test 18 passed, including live testnet + mainnet negotiation and all three no-pin factory guards
npm run test:setup 47 passing
prettier --check (changed files) clean
dashnote build + test + lint build ok, 346 passed
dashrate build + test + lint build ok, 160 passed
dashnote-starter build + lint pass (no test suite by design)
dashmint-lab production build pass
dashproof-lab production build pass
standalone lite SDK-version regression 4/4 pass; built pages contain the 4.1.0 import
scripts/check-shared-auth-parity.sh byte-identical
dashnote load-anchor check no static evo-sdk import in entry chunk

node connect.mjs drives the real path end-to-end and reports drive: 4.1.0 on testnet.

Not verified

  • The write path. test:read-write is destructive and consumes testnet credits, and no funded PLATFORM_MNEMONIC was available here, so it was not run. This PR does not claim to have settled the open question in PLATFORM_VERSION_OVERRIDE is still pinned to 12, but testnet has been running protocol version 13 since late July #112 about whether a version-12-pinned client behaved differently for state transitions — it removes the pin so the question stops mattering. A workflow_dispatch run of the read-write suite would still be worth doing before this merges.
  • Standalone lite pages in a browser. No browser-level CDN fetch was performed. Their exact source and production-build import URLs are covered statically, while the live root regression verifies SDK 4.1.0 protocol negotiation against both testnet and mainnet.

Follow-ups, deliberately out of scope

Tracker: thepastaclaw/tracker#2594 (remains open pending review).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • SDK connections now automatically negotiate the supported protocol version for testnet, mainnet, and local environments.
    • Updated example applications to use Evo SDK 4.1.0.
  • Bug Fixes

    • Improved note and review serialization to use the negotiated protocol version.
  • Tests

    • Added coverage for protocol negotiation and SDK version consistency across standalone Lite applications.
    • Expanded the default test suite to include these checks.

thepastaclaw and others added 3 commits August 4, 2026 00:18
PLATFORM_VERSION_OVERRIDE was pinned to 12 while testnet has been running
protocol version 13 since late July. A pin is not a floor: rs-sdk's version
ratchet returns early when `version_pinned` is set, so a pinned client stays
on the old version silently — no error, no warning — no matter what the
network reports.

The pin's TODO said to remove it once dashpay/platform#3809 landed in the
consumed SDK. That condition is now met, and the behavior is verified against
the consumed @dashevo/evo-sdk 4.1.0 and live testnet:

  unpinned    after connect: 12  ->  after a proof-bearing read: 13
  version: 12 after connect: 12  ->  after a proof-bearing read: 12
  version: 13 after connect: 13  ->  after a proof-bearing read: 13

testnet reports protocol.drive.current = 13; the SDK's own ceiling
(getLatestVersionNumber) is 13. So an unpinned client negotiates its way to
the network's active version, capped at what the SDK understands.

Remove the pin rather than bumping it to 13. Bumping re-arms the same trap for
protocol version 14 and leaves the failure mode intact — silent, invisible in
CI, and only observable by manual dispatch of the read-write suite.

platformVersion.mjs existed only to hold this constant, so it goes with it.
Its other consumer was `document.toJSON(PLATFORM_VERSION_OVERRIDE)` in three
example apps; those now pass `sdk.version()`, which reflects the negotiated
version and cannot go stale.

dashmint-lite.html carried the same defect independently — pinned to 11 with a
comment pointing back at this constant — so it is unpinned too.

Co-Authored-By: Claude <noreply@anthropic.com>
The pin that dashpay#112 reported was invisible to CI: pull requests only run
test:read-only, and that suite passed against a PV-13 testnet with the client
stuck on 12 the whole time. Nothing asserted the negotiated version, so the
staleness could only be found by reading the constant.

Assert that a client from createClient() settles on the network's active
protocol version after its first proof-bearing read. Verified both ways
against live testnet: passes unpinned, fails with `{ version: 12 }` restored.

The expected value is min(network active version, SDK ceiling) rather than the
network version alone. When the network upgrades ahead of a released SDK the
client legitimately stops at its own ceiling, and that shouldn't read as a
regression.

Lives in the read-only suite because that is the only job CI runs on pull
requests; test:setup is not wired into any workflow. No credentials or funds
required — the fixture is the DPNS system contract.

Co-Authored-By: Claude <noreply@anthropic.com>
createNote and saveReview now read the negotiated protocol version off the
SDK instead of a shared constant, so the hand-rolled stubs in these suites
need to answer version(). Both stubs are cast (`as never` / `as unknown as
DashSdk`), so the compiler couldn't flag the gap — it showed up at runtime as
"sdk.version is not a function".

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@thephez, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 42 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 867af112-0350-4ca8-bf65-7b9da48501bc

📥 Commits

Reviewing files that changed from the base of the PR and between c78b5cb and b3d195e.

📒 Files selected for processing (2)
  • README.md
  • test/platform-version.test.mjs
📝 Walkthrough

Walkthrough

The change removes hardcoded platform protocol version overrides, exposes negotiated SDK versions to example applications, updates lite pages to Evo SDK 4.1.0, and adds tests and documentation for negotiation and version alignment.

Changes

Protocol version negotiation

Layer / File(s) Summary
Remove client version pinning
setupDashClient-core.*, example-apps/dashmint-lab/public/dashmint-lite.html
Client factories and DashMint Lite no longer pass a hardcoded protocol version. The override exports and workaround are removed.
Expose negotiated SDK versions
example-apps/dashnote*/src/dash/*, example-apps/dashrate/src/dash/*, example-apps/dashnote/test/*, example-apps/dashrate/test/*
DashSdk.version() is added. Note and review serialization use the negotiated SDK version. Mocks return version 13.
Update lite SDK integrations
example-apps/*/public/*-lite.html
Four lite applications now import Evo SDK 4.1.0.
Validate negotiation and version alignment
test/*, package.json, .github/workflows/test-tutorials.yml, CLAUDE.md, README.md
Tests cover negotiated versions, unpinned factories, and matching lite imports. Package scripts, workflow commands, and documentation describe the expanded suites.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant createClient
  participant EvoSDK
  participant DashNetwork
  participant ExampleApp
  createClient->>EvoSDK: create client without version override
  EvoSDK->>DashNetwork: connect and negotiate protocol version
  DashNetwork-->>EvoSDK: network protocol version
  EvoSDK-->>ExampleApp: negotiated SDK version
  ExampleApp->>EvoSDK: serialize document with version()
Loading

Possibly related PRs

Suggested reviewers: thephez

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes removing the pinned platform protocol version and enabling automatic network version detection.
Linked Issues check ✅ Passed The changes satisfy issue #112 by removing the protocol version pin, updating dependent examples, and adding negotiation regression coverage.
Out of Scope Changes check ✅ Passed The workflow, documentation, example updates, and regression tests directly support protocol negotiation and version-alignment objectives.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@thepastaclaw

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

thepastaclaw and others added 3 commits August 4, 2026 00:44
Co-Authored-By: Claude <noreply@anthropic.com>
The two guards added for dashpay#112 lived inside test/read-only.test.mjs, which otherwise only runs tutorials as subprocesses. Neither guard is a tutorial run, so they are moved to test/platform-version.test.mjs and test/lite-sdk-versions.test.mjs and `test:read-only` goes back to covering just the tutorial suite.

`npm test` and `test:all` now run all three files, and the PR job in test-tutorials.yml calls `npm test` so the new guards run on pull requests.
The live negotiation test only proves the version is unpinned once a proof-bearing read has ratcheted it, so it asserts against network state rather than an invariant. test/platform-version-config.test.mjs adds an offline guard that mocks the three `*Trusted` factories and asserts createClient() passes them no arguments — a reintroduced pin fails there without needing the network, and `local` gets covered too.

The live test now loops over testnet and mainnet instead of reading NETWORK, so a pin on either network shows up rather than only on whichever one the environment happened to select.
@thephez
thephez marked this pull request as ready for review August 4, 2026 20:10
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Around line 111-115: Update the testing prerequisites in README.md so the .env
requirement applies only to npm run test:read-only and npm run test:read-write,
while npm test remains documented as runnable without wallet credentials.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ed1c2a3e-178f-4512-a992-c1a7af2c801d

📥 Commits

Reviewing files that changed from the base of the PR and between 45d513d and c78b5cb.

📒 Files selected for processing (2)
  • CLAUDE.md
  • README.md

Comment thread README.md
The prerequisite said to configure .env "before running tests", which contradicted the line two rows below calling `npm test` a safe default. Only the tutorial suites need credentials: without a PLATFORM_MNEMONIC the read-only suite skips the tutorials that require one, and the write suite cannot run at all.

test/platform-version.test.mjs no longer reads process.env now that it names the networks explicitly, so its dotenv import goes too.

@thephez thephez left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Tests and builds working

@thephez
thephez merged commit a8e7bf7 into dashpay:main Aug 4, 2026
1 check passed
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.

PLATFORM_VERSION_OVERRIDE is still pinned to 12, but testnet has been running protocol version 13 since late July

2 participants