Skip to content

docs(testnet): current-gen staging plan + prepared §6a re-run (Flashstack-ajv.6.3) - #64

Merged
unixwhisperer merged 2 commits into
mainfrom
security-lead/testnet-current-gen-plan
Sep 21, 2026
Merged

unixwhisperer merged 2 commits into
mainfrom
security-lead/testnet-current-gen-plan

Conversation

@unixwhisperer

Copy link
Copy Markdown
Collaborator

The two halves of Flashstack-ajv.6.3 that need no key. Docs and one .gitignore line — no contract, no test, no Clarinet.toml.

What's here

deployments/testnet-current-gen-plan.yaml — the plan scripts/deploy-testnet.mjs executes, written down: contract set, order, fees, nonce discipline, arguments. Every value is read off that script with a per-field line reference, because §7 says to derive them there rather than invent them in prose — so you can diff the file against the script instead of trusting it. The evidence: slots are empty on purpose.

It is deliberately not a Clarinet plan and says so at the top. Clarinet publishes source verbatim; on testnet that broadcasts contracts still carrying mainnet principals and aborts at publish time (§5.1). It has a different shape from the default.*-plan.yaml files beside it so the two can't be confused.

docs/TESTNET_STAGING.md §6c — the §6a replacement, pre-written so new txids drop straight in, keeping the Proven / NOT proven split that makes §6a good. It's inside a fenced block so its placeholder checkboxes can't be misread as evidence. It asserts nothing.

.gitignoredeployments/testnet-*.yaml matched the exact filename the bead asks for, so the file would have been committed-looking and silently untracked. Negated the same way testnet-plan.yaml already is.

Two things found while writing it — both are yours to decide

1. The re-run isn't executable today by either route. Steps 1–3 publish names that already exist at ST3XQ5DM…, and a name is consumed permanently at a principal whether or not the publish took effect (CONTRACT_INVENTORY §3).

Route Cost Needs first
A Admin steps only, existing deployment 300,000 µSTX deploy-testnet.mjs is linear with no step selection — needs a step flag or a purpose-built script (precedent: deploy-testnet-bc1-negative.mjs). Doesn't literally satisfy "a run of the current deploy-testnet.mjs".
B Fresh -v3 line, full 10-step run 53.31 STX Not a rename in the script. stx-test-receiver-v2.clar:16 calls .flashstack-stx-core-v2 statically, so a -v3 core needs a -v3 receiver source too.

I'd take A with a --steps flag: the gap is BC1 assertion strength, and B rewrites contracts to fix a documentation problem. But it's your call, and it changes what ajv.6.3 can claim.

2. §6a's two remaining checklist items aren't equal. "Unapproved receiver is rejected" needs no new contract. "Non-repaying receiver reverts" has nothing to run against — no non-repaying receiver exists for this core; one has to be written and published.

Live state, read before writing

Sender ST3XQ5DM…, 2026-09-21: get-admin = deployer, get-pending-admin = none, get-reserve-balance = u50005000, get-fee-basis-points = u5, is-approved-receiver = true, nonce 12, balance 946490000 µSTX. §6b's restore held and the §6a deployment is intact.

Also verified rather than assumed: next-action 4 (TESTNET_EQUIVALENT) landed in #55 — commit 7521791.

Checks

  • Suite 221/221 across 20 files — discovery unchanged.
  • clarinet check 3.23.2: 211 contracts, 0 errors. The clean tree at 737c659, measured in the same session, gives the same 211/0 (warning count differed, 214 vs 202 — the known nondeterminism). Clarinet.toml untouched.
  • clarinet check parses deployments/ without choking on the new file — that was the one real risk in adding it.

🤖 Generated with Claude Code

…-run

Flashstack-ajv.6.3, the two halves that need no key.

deployments/testnet-current-gen-plan.yaml — the plan scripts/deploy-testnet.mjs
executes, written down: contract set, order, fees, nonce discipline, arguments.
Every value is read off that script with a per-field line reference (§7 says to
derive them there, not invent them in prose), so a reviewer can diff the file
against the script instead of trusting it. evidence: slots are empty on purpose.

It is deliberately NOT a Clarinet plan and says so loudly. Clarinet publishes
source verbatim; on testnet that broadcasts contracts still carrying mainnet
principals and aborts at publish time (§5.1). Different shape from the
default.*-plan.yaml files beside it so the two cannot be confused.

.gitignore — deployments/testnet-*.yaml matched the exact filename the bead
asks for, so the file would have been silently untracked. Negated the same way
testnet-plan.yaml already is.

docs/TESTNET_STAGING.md §6c — the §6a replacement, pre-written so new txids drop
straight in, keeping the Proven / NOT proven split. Fenced so its placeholder
checkboxes cannot be misread as evidence; it asserts nothing.

Two things found while writing it, both for the owner:

1. The re-run is not executable today by either route. Steps 1-3 publish names
   that already exist at ST3XQ5DM..., and a name is consumed permanently there
   (CONTRACT_INVENTORY §3). Route A (admin steps only, 300k uSTX) needs a step
   flag or a purpose-built script, because deploy-testnet.mjs is linear — and it
   does not literally satisfy "a run of the current deploy-testnet.mjs". Route B
   (fresh -v3 line, 53.31 STX) is not a rename in the script:
   stx-test-receiver-v2.clar:16 calls .flashstack-stx-core-v2 statically, so a
   -v3 core needs a -v3 receiver source too.

2. §6a's two remaining checklist items are not equal. "Unapproved receiver is
   rejected" needs no new contract. "Non-repaying receiver reverts" has no
   contract to run against at all — none exists for this core.

Live state read before writing (sender ST3XQ5DM...): get-admin = deployer,
get-pending-admin = none, get-reserve-balance = u50005000, is-approved-receiver
= true, nonce 12, balance 946490000 uSTX. §6b's restore held.

§7 and §8 updated: the plan file now exists, and next-action 4 (TESTNET_EQUIVALENT)
landed in #55 — verified against the commit, 7521791, not assumed.

Docs and one gitignore line only; no contract, no test, no Clarinet.toml touched.
Suite 221/221 across 20 files (discovery unchanged). clarinet check 3.23.2: 211
contracts, 0 errors — identical to the clean tree at 737c659 measured in the same
session, which gave 211/0 with a different warning count.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
web Ready Ready Preview Sep 21, 2026 9:01am UTC

Request Review

@mattglory mattglory left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Approving. Live state, the fee arithmetic (0.3 STX for A, 53.31 STX for B), the .gitignore reason, and the static-reference line all reproduce.

…ts it

Owner picked route A. §6b already proves the property on this deployment, so the
gap is assertion strength on the positive path, not a deployment — and B would
rewrite contracts to fix a documentation problem. B is parked: staging
flashstack-stx-pool-v3 is worth more than a -v3 rename.

§6c's route table and the plan file's execution-decision block updated to say so,
and to name deploy-testnet.mjs --steps=admin (PR #66) as what makes A executable.

Recorded honestly rather than quietly: --steps=admin runs deploy-testnet.mjs's
own Step 8 path — extracted into proveBC1(), not copied — but not the whole
script, so it does not literally satisfy ajv.6.3's original "a run of the CURRENT
deploy-testnet.mjs". That criterion was amended in Beads to say so openly.

Consequence for the plan file, now stated in it: steps 1-7 stay unexecuted for
this line, since they are already on chain from the §6a run. Only the 8a/8b/8c
evidence: slots get filled. Steps 1-7 remain the written record of how that
deployment was produced, and the plan a new line would follow.

Docs only; the YAML still parses.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@unixwhisperer
unixwhisperer merged commit 00cf0c4 into main Sep 21, 2026
7 checks passed
@unixwhisperer
unixwhisperer deleted the security-lead/testnet-current-gen-plan branch September 21, 2026 10:14
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.

2 participants