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.
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 |
pnpm distributor:status:devnet,pnpm distributor:claim:devnet,pnpm distributor:burn:devnetandpnpm exec ts-node scripts/distributor-init-devnet.tseach hardcodeconst 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.tsrequires it. They are retained because they are the Mainnet-shaped originals the-testsiblings are pinned against, not because they are runnable.distributor-init-mainnet.ts:739-744refuses 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.jsonfor gitignored public deployment state.
These guards must be independently rechecked before use.
Before any approved Devnet mutation:
- complete the current Localnet build and test pipeline;
- verify the program ID and compiled development
INIT_AUTHORITY; - freshly run
anchor build; - confirm the intended
.soand IDL hashes; - inspect the transaction sequence and expected public addresses;
- confirm the wallet public address only;
- obtain explicit approval for the exact command and purpose;
- 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.
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.
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.mdruns--finalon 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.
--finalis 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:5438/38 and:13441/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 atphase18-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 — never6bBr6ggW…, 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.
| 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…andH7hyWyS4…were all closed on 2026-07-27 (re-verified read-only 2026-07-30: each programdata account returnsnull).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: trueafter 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.
- 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
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.