Skip to content

Latest commit

 

History

History
189 lines (157 loc) · 9.31 KB

File metadata and controls

189 lines (157 loc) · 9.31 KB

Devnet

Status: Draft operating guide
Authority: Current tick_distributor Devnet tooling and approval boundaries
Last reviewed: 2026-07-30

This document authorizes nothing. Every Devnet airdrop, transaction, deployment, initialization, claim, or burn requires the owner's explicit approval at the time it is performed. Mainnet is forbidden.

Current tooling

There is exactly one live TICK program on Devnet: 6bBr6ggWg8CY9HAFWwyvehaUpMnBsoJ6WLcwBHfVaSte, carrying distributor DtCzJirf… and mint FbzcDjaHYhGqVi9vHWpzHQfQUxiedcFYJKR7zyWZQGZ3. The :devnet:test commands are the ones that reach it.

Command Behavior State change
pnpm distributor:status:devnet:test Reads the recorded distributor, mint, vault, schedule, and wallet public balance None
pnpm verify:supply:devnet:test Re-derives the supply invariant against the live mint None
pnpm distributor:claim:devnet:test Claims the full currently available batch to the configured development wallet Yes — approval required
pnpm distributor:burn:devnet:test -- <whole-tick> Irreversibly burns holder-owned Devnet TICK Yes — approval required
pnpm exec ts-node scripts/distributor-init-devnet-test.ts One-off mint, initialize, fund, verify, and test-claim ceremony Already run 2026-07-27. It will now abort: 6bBr6ggW… carries a funded distributor, so §4.0's orphan scan refuses

⛔ The four release-id commands cannot work, and have not been able to since 2026-07-27

pnpm distributor:status:devnet, pnpm distributor:claim:devnet, pnpm distributor:burn:devnet and pnpm exec ts-node scripts/distributor-init-devnet.ts each hardcode const PROGRAM_ID = new PublicKey("5b8oDRPP6iGMP4hLeip9nr5Wtsfejuwy6aqkk3Msh9hP") (distributor-status-devnet.ts:57, distributor-claim-devnet.ts:67, distributor-burn-devnet.ts:81, distributor-init-devnet.ts:170).

That program is permanently closed on Devnet. The id can never host a program there again, so these four have no reachable target and none of them can be repaired by configuration — the hardcoding is deliberate, and tests/phase16-cluster-safety.test.ts requires it. They are retained because they are the Mainnet-shaped originals the -test siblings are pinned against, not because they are runnable. distributor-init-mainnet.ts:739-744 refuses the release id on the Devnet branch for the same reason, quoting the runtime's own "Program … has been closed".

If a fifth Devnet program is ever needed, it gets a fresh id and a fresh pnpm devnet:test:build — see the Devnet dress-rehearsal runbook §4.3.

The mutation scripts:

  • accept only api.devnet.solana.com;
  • verify the live Devnet genesis hash before signing;
  • load the configured wallet only to sign;
  • never print secret bytes;
  • use deployments/devnet.json for gitignored public deployment state.

These guards must be independently rechecked before use.

Required preflight

Before any approved Devnet mutation:

  1. complete the current Localnet build and test pipeline;
  2. verify the program ID and compiled development INIT_AUTHORITY;
  3. freshly run anchor build;
  4. confirm the intended .so and IDL hashes;
  5. inspect the transaction sequence and expected public addresses;
  6. confirm the wallet public address only;
  7. obtain explicit approval for the exact command and purpose;
  8. record public transaction signatures and postconditions without recording secrets.

Program deployment is a separate state-changing action and requires its own explicit approval. Do not finalize the Devnet upgrade authority; Devnet is a rehearsal environment.

Status verification

Do not assume an old curve deployment or an existing deployments/devnet.json represents the current distributor. Verify the program ID, executable account, IDL, mint, distributor PDA, vault authority, vault, authorities, supply, and current code version before describing a Devnet instance as current.

The superseded tick_curve rehearsal guide is retained only at ../archive/bonding-curve/DEVNET_GUIDE.md.


Cleanup — Devnet deployments are disposable, and should be disposed of

Devnet does not run --final — with exactly one deliberate exception. Every program deployed there normally keeps its upgrade authority (the hardware Ledger), which means — unlike Mainnet — it can be shut down and its rent recovered.

The exception: the dress-rehearsal program. DEVNET_DRESS_REHEARSAL.md runs --final on its throwaway program id once — on a run that qualifies as a keeper under its §9.1.

Be accurate about why, because the obvious reason is wrong. --final is approval 4 of four, and it has been performed on hardware: twice, on localnet, in the exact flag form the rehearsal prints (scripts/phase18-ledger-ceremony-local.ts:1176-1184; docs/audit/internal/2026-07-26-FREEZE-CHECKLIST.md:54 38/38 and :134 41/41). What it has never met is a public cluster. Nor is it "the step most likely to fail" for want of rehearsal: the H-2 USB-handle trap was found by that localnet harness, on its first run — see the comment at phase18-ledger-ceremony-local.ts:1156-1162, "Found the hard way on the first run of this script" — then fixed, and re-rehearsed on hardware. The real reasons to finalize on Devnet are the §5.0→§5.2 tail timed against Devnet finality, and operator muscle memory at the one keystroke that cannot be taken back.

The larger untested gap is approval 1 — the Ledger-signed deploy --upgrade-authority usb://ledger — which has never been signed on a device anywhere (MAINNET_CEREMONY.md §E). It costs nothing extra and the rehearsal's phase 3 already covers it. If the rehearsal day runs short, approval 1 is the part that must not be cut.

The cost is real and one-way: a finalized program can never be closed, so its ~1.49 SOL of Devnet rent is forfeit permanently, and the result is a permanent Devnet faucet carrying the real TICK metadata and the real Arweave URI. That is a cost, not a bonus — ../public/RISK_DISCLOSURES.md §6, "Nothing real exists yet" tells the public that the Devnet fixture is distinguishable from the launch precisely because "That program is still upgradeable — its upgrade authority has not been revoked." Budget for it, spend it once (the rehearsal's §9.1 keeper rule: non-keeper attempts hand the authority to a hot key instead and are closed for their rent back), and finalize only the rehearsal id — never 6bBr6ggW…, and never anything the website points at.

6bBr6ggW… is the program §6 names. Finalizing it does not merely cost rent — it falsifies a published statement. The Devnet finalization environment record's step B4 once instructed exactly that; that instruction has been inverted and the reasoning is recorded there.

solana program close <PROGRAM_ID> --url devnet \
  --authority usb://ledger --recipient <your wallet>

Closing makes the program non-executable: every claim against it fails and the faucet stops. It refunds the program's rent, roughly 1.49 SOL per deployment.

The mint and any claimed tokens continue to exist as SPL accounts — nothing can un-mint them — but they become inert, because no working program can move the vault. On a network that is periodically reset and whose tokens have no value, that is the correct end state.

What to close, and when

Deployment Close when
Pre-freeze builds as soon as they are superseded — see below
Test builds (patched declare_id!) after the rehearsal they were built for
The current rehearsal faucet when the website no longer points at it

Nothing is currently awaiting a close. 5b8oDRPP…, 7MHwTKWg… and H7hyWyS4… were all closed on 2026-07-27 (re-verified read-only 2026-07-30: each programdata account returns null). 6bBr6ggW… is the one live program and the website points at it, so it stays. The next close will be the mirror's program id, on a non-keeper run, under the Devnet dress-rehearsal runbook §9.1.

A program account stays visible and reports executable: true after a close. That is not evidence it is alive — read the programdata account.

Close superseded builds sooner rather than later. A live, funded faucet running an old build is the thing most likely to be mistaken for the real launch by someone who finds it. RISK_DISCLOSURES.md §6 describes the Devnet faucet as a rehearsal, and that description stays honest only while there is exactly one of them.

Before closing, check

  • no website or documentation still points at that program or mint
  • the deployment record is archived (deployments/devnet.<date>-*.json), not deleted — it is the only record of what that launch was
  • you are closing the PROGRAM id, not a buffer or the mint

What closing does NOT do

It does not remove the token from anyone's wallet, and it does not reduce the supply. Holders keep their balances; those balances simply become unusable, because the only program that could ever have moved the vault is gone.

This is a Devnet-only procedure. On Mainnet the upgrade authority is destroyed at §5.2, and no equivalent exists at any price.