Tidemark

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:

shell
cargo install --git https://github.com/IIITManjeet/Tidemark tidemark-cli
tidemark --help

Review two builds

shell
tidemark diff old.so new.so --json report.json --hunks 4 --fail-on high
FlagMeaning
--json PATHWrite the full report; its hash is printed as the report hash
--hunks NHow many code hunks to print
--fail-on LEVELExit 2 at or above info, low, medium, high or critical
--cache DIRReuse earlier reviews keyed by both hashes and the rules version
--judgeAdd the advisory AI judge (needs GEMINI_KEY)
--isolateParse 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

shell
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

shell
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

shell
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?

shell
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).

shell
tidemark census 8f43wqFP4wZ8NLrJgBrGXDrXp92FgxSvM9Ng21GrgPq6 \
  --squads 8jGmTqcvXfp8taPTq6u5Tmorbu7pByKGDmy4eYU2xki9

Ledger commands

CommandPurpose
init-registry --threshold KCreate a registry you control
add-reviewer KEYAllow a key to attest and approve
set-reviewer KEY --active BOOLEnable or disable a reviewer
set-threshold KApprovals needed before an entry is final
propose-authority / accept-authorityHand a registry to a new key in two steps
attest --program ID --old SNAPSHOTReview the deployed upgrade and publish the verdict
approve --registry R --index N --old SNAPSHOTRe-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

CodeMeaning
0Review finished below the --fail-on level
1Bad input or usage, for example an unknown level or a non-SBPF file
2Risk at or above --fail-on
3verify-ledger found a broken chain or RPCs that disagree
Untrusted input
Program binaries are attacker-controlled. Inputs over 16 MiB are rejected and every analysis step is bounded, so a hostile file can slow a review down but not hang it.