test: pin what clarinet deployments apply --mainnet would publish - #76
Merged
Merged
Conversation
On any machine with settings/Mainnet.toml, `apply --mainnet` publishes the plan clarinet computes from Clarinet.toml (two Enters by default, no prompt under -d). Today that plan has 57 publishes, 26 of them from contracts/test/: the localized copies of every funds-bearing contract, whose sBTC calls resolve to the in-plan mock sbtc-token, plus fixtures like malicious-token. Verified 2026-09-27 against clarinet 3.23.2 in a network-isolated container (see the #75 review). The target, no contracts/test/ path in the mainnet plan, needs D6's structural fix, so it is recorded with it.fails. Until then the known set of 26 is pinned, so registering one more contracts/test/ file fails CI. Generates the plan in a temp copy with the public devnet deployer mnemonic, an unreachable RPC address and --manual-cost: nothing is signed or sent, and no network is needed. Requires CI's clarinet version in CI; skips locally when the binary is missing or mismatched (CLARINET_BIN overrides). Red/green: registering an extra contracts/test/ file, or unregistering malicious-token, fails the pin; breaking the plan parser fails all three.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
mattglory
approved these changes
Sep 28, 2026
mattglory
left a comment
Owner
There was a problem hiding this comment.
Approving. Verified independently, not just re-run:
- Ran the test itself: 2 passed, 1 expected fail — matches your table exactly.
- Then reproduced it completely from scratch, outside the harness: copied Clarinet.toml/contracts/.cache to a temp dir, generated a Mainnet.toml from the same public devnet mnemonic, ran
clarinet deployments generate --mainnet --manual-costdirectly. 57 total publishes, 26 fromcontracts/test/— exact match. The sbtc-token dot-reference incontracts/test/flashstack-sbtc-pool-v3.claris at lines 91 and 102, exactly where you cited it. - Re-checked all 5 audit-track successor names live on-chain right now: all still 404 at SPR9PQAN…, so the squatting risk is current, not stale.
it.failsframing is right — a hard-red test here would block every unrelated PR, and the pinned list turning strict (fails on add OR remove) is exactly the guard this needs.
Good work isolating this properly (network-none container, throwaway key, mock node) rather than trusting source-reading a second time. Merging.
mattglory
added a commit
that referenced
this pull request
Sep 28, 2026
mattglory
added a commit
that referenced
this pull request
Sep 28, 2026
…orrection) Requested changes from Hillary's #75 review. Two prior passes at this section relied on reading clarinet's source -- mine and hers, independently -- and both were wrong. She then actually ran clarinet 3.23.2 (the CI binary) in a network-isolated container against the real repo, before and after #74, with a mock node logging every broadcast attempt. I re-ran her test (#76, merged) and independently reproduced the core claim from scratch outside the harness before writing any of this down: 57 publishes, 26 from contracts/test/, matching exactly; the sbtc-token references she cited at lines 91/102 of the test sbtc-pool-v3 copy matched exactly; all five undeployed audit-track successor names re-confirmed 404 today. What actually changes: - D5: a clean checkout never broadcasts, before or after #74 (recompute fails, falls back, prompts, exits with zero requests either way). The gen-1 plan could only ever be signed by SP3TGRVG..., whose 13 names already exist on mainnet, so a real broadcast would be refused as duplicates regardless. #74 is hygiene -- it removed a route only that key could use, one the chain would have refused anyway -- not the risk reduction either earlier version of this row claimed. - D6: the real, still-live exposure, unaffected by #74. Any machine with settings/Mainnet.toml, any key, reaches the SAME plan clarinet computes fresh from Clarinet.toml (byte-identical before/after #74) -- 57 publishes, 26 from contracts/test/, sBTC resolving to a flash-mintable mock, 54 of 57 names free including all five successors. Now pinned by tests/mainnet-plan-guard.test.ts (#76). - Archive file header: same correction, so the historical record doesn't repeat either wrong prior explanation. - Dates: 2026-09-23 -> 2026-09-26 in all three places, per review. Verified: suite 258 passed / 1 expected fail (259) across 25 files (unchanged from post-#76 main), clarinet check 211/0 (unchanged), archive YAML still parses. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
tests/mainnet-plan-guard.test.ts, the regression guard proposed in the #75 review.On any machine with a
settings/Mainnet.toml,clarinet deployments apply --mainnetpublishes the plan clarinet computes fromClarinet.toml: after two Enters by default, or with no prompt under-d. Today that plan has 57 publishes, 26 fromcontracts/test/. These are the localized copies of every funds-bearing contract, whose sBTC calls resolve to the in-plan mockcontracts/sbtc-token.clar, plus fixtures such asmalicious-token,mock-usdcxandtest-receiver-bad. The full evidence (isolated container, throwaway key, mock node) is in the #75 review.Design: why this doesn't simply go red
The real invariant is no
contracts/test/path in the mainnet plan. That can't hold until D6's structural fix (CONTRACT_INVENTORY §7.3), and a red test onmainwould block every PR. So:it.fails. It shows up as "expected fail" and flips the moment D6 lands. At that point, turn it intoit.contracts/test/file inClarinet.toml, which puts a test build into what a mainnet deploy run publishes, fails CI. Removing one also fails, so the list is only ever changed deliberately.If you'd rather have a plain failing test and fix D6 in the same change, that's a one-line swap. Your call.
Safety
deployments generateonly writes a plan file, and it writes it inside a temp copy ofClarinet.toml,contracts/,.cacheandsettings/Devnet.toml. Nothing is written to the working tree, and nodeployments/default.mainnet-plan.yamlreappears.Mainnet.tomluses the public Clarinet devnet deployer mnemonic, read at runtime fromsettings/Devnet.toml. No new secret material is introduced.http://127.0.0.1:1, and--manual-costskips fee estimation..cache, so no network is needed (verified under--network none).Clarinet version
The test reads the version from
.github/workflows/test.yml(currently 3.23.2), so the two can't drift. In CI (CIset) a missing or mismatched clarinet throws. Locally it skips, since several of us have older binaries (mine is 3.13).CLARINET_BINpoints it at a matching binary. No workflow change is needed, because CI already puts clarinet onPATHbeforenpm test.Verification (clarinet 3.23.2,
CLARINET_BIN)contracts/test/zz-mutation.clar+ zz-mutation.clarmalicious-token- malicious-token.clarflashstack-stx-corepointed at its canonical sourcebeforeAllthrows and the file fails closedCLARINET_BINNoted, not touched
README/ROADMAP/AUDIT_SCOPE say 254 tests;
mainis already at 256/24, and this makes it 259/25. That drift predates this PR, so I've left the docs alone. Happy to reconcile the counts once the open PRs settle.🤖 Generated with Claude Code