Command line
The tidemark binary reviews upgrades, watches programs and reads and writes the attestation ledger.
Download a prebuilt binary for Linux, macOS or Windows from the v0.1.0 release, or build it with Cargo:
cargo install --git https://github.com/IIITManjeet/Tidemark tidemark-cli tidemark --help
Review two builds
tidemark diff old.so new.so --json report.json --hunks 4 --fail-on high
| Flag | Meaning |
|---|---|
--json PATH | Write the full report; its hash is printed as the report hash |
--hunks N | How many code hunks to print |
--fail-on LEVEL | Exit 2 at or above info, low, medium, high or critical |
--cache DIR | Reuse earlier reviews keyed by both hashes and the rules version |
--judge | Add the advisory AI judge (needs GEMINI_KEY) |
--isolate | Parse and diff in a separate locked-down process (see below) |
Isolated reviews
With --isolate, the CLI reads both files, then runs the review in a child process with an empty environment that receives the bytes on stdin and returns the report on stdout. The report, verdict hash and exit code are the same as without the flag. A crash, a timeout (120 s) or bad output is an error, never a pass.
On Linux the child also denies itself all filesystem access with Landlock and sets resource limits: 2 GiB of memory, 60 s of CPU, no file writes, no new processes. On macOS and Windows only the separate process and the timeout apply. Network access is not blocked yet.
Inspect and fetch
tidemark inspect program.so tidemark fetch <PROGRAM_ID> --rpc https://api.devnet.solana.com -o program.so
fetch reads ProgramData, strips the 45-byte header and trailing padding, and prints the upgrade authority and last deploy slot.
Review a Squads upgrade proposal
tidemark proposal --multisig <MULTISIG> --index <N> --rpc https://api.mainnet-beta.solana.com
Before you approve, reads Squads v4 vault transaction N, finds each program upgrade in it, fetches the buffer it would deploy and the program that is live now, and reviews the change exactly like diff. It takes the same --json, --hunks and --fail-on flags and exits 2 at or above the level. Proposals that load accounts through an address lookup table are not read yet.
Watch a program
tidemark watch <PROGRAM_ID> --dir snapshots
Keeps every deployed version as snapshots/<program>/<slot>.so and reviews each upgrade against the previous snapshot. Add --attest <LEDGER> to publish each review.
It also subscribes to the ProgramData account over a websocket derived from --rpc (or --ws URL) and checks the moment it changes; polling continues underneath and a dropped socket reconnects. Use --no-ws to poll only.
Who can upgrade it?
tidemark census --rpc https://api.mainnet-beta.solana.com <PROGRAM_ID>...
Classifies each program as immutable, single key, multisig or governance, or program-controlled.
A Squads v4 vault is a plain system account, so name its multisig with --squads MULTISIG (repeatable). Census derives that multisig's vaults and, when one of them holds the upgrade authority, reads the multisig account and reports its threshold, voting members and timelock, for example multisig (Squads v4, 2 of 3, 1h timelock).
tidemark census 8f43wqFP4wZ8NLrJgBrGXDrXp92FgxSvM9Ng21GrgPq6 \ --squads 8jGmTqcvXfp8taPTq6u5Tmorbu7pByKGDmy4eYU2xki9
Ledger commands
| Command | Purpose |
|---|---|
init-registry --threshold K | Create a registry you control |
add-reviewer KEY | Allow a key to attest and approve |
set-reviewer KEY --active BOOL | Enable or disable a reviewer |
set-threshold K | Approvals needed before an entry is final |
propose-authority / accept-authority | Hand a registry to a new key in two steps |
attest --program ID --old SNAPSHOT | Review the deployed upgrade and publish the verdict |
approve --registry R --index N --old SNAPSHOT | Re-run the review and co-sign only if it matches |
verify-ledger --registry R --rpc URL... | Check the whole chain, reviewers and approvals |
Every chain command takes --ledger, --rpc, --keypair and an optional --payer that covers fees, so reviewer keys never need SOL.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Review finished below the --fail-on level |
| 1 | Bad input or usage, for example an unknown level or a non-SBPF file |
| 2 | Risk at or above --fail-on |
| 3 | verify-ledger found a broken chain or RPCs that disagree |