Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

129 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Epochnotes: keep up with network changes. Know what breaks in your code, with fixes tied to signed records and primary sources.

Explore the registry · Ask your AI agent · Found in the field · Get started · Run the demo · Visual identity

Epochnotes

A signed registry of network changes on Solana, Ethereum and Base — and the checks built on it: what breaks in your code, where, and how to fix it.

An upgrade lands, a call or a contract check that worked for a year starts failing, and the answer lives in a SIMD or an EIP, a client's configuration and the chain itself — three places, none of them your code. Epochnotes keeps that answer as a signed entry, tells you where it applies in your repository, and reads the activation status from each chain at the moment you ask: a feature account on Solana, the head block and the header field a fork adds on Ethereum and Base. One signed version covers every chain it names. When it cannot verify what it reads, it refuses to answer rather than guess; when it had nothing to check something against, it says so instead of reporting a clean result.

Status: pre-release. The registry log has two signed versions (the latest, version 2, from 2026-10-25), kept in registry/versions and served at https://mskrad.github.io/Epochnotes/registry/versions/, and anchored in the registry program on Solana devnet (--onchain compares the two). DEMO_RUNBOOK.md walks through the whole path with a log of your own in about ten minutes. Nothing here has been audited.

Quick start

npm install -g @epochnotes/cli
export EPOCHNOTES_VERSIONS=https://mskrad.github.io/Epochnotes/registry/versions
curl -fsS https://mskrad.github.io/Epochnotes/registry/publishers.json -o epochnotes-publishers.json
export EPOCHNOTES_PUBLISHERS=./epochnotes-publishers.json
epochnotes registry read --json --status mainnet-beta
epochnotes check repo <path>

The publisher file defines the keys you trust. Inspect it before using it. Read the signed log's trust boundaries before relying on its results.

Ask your AI agent

The easiest way to use Epochnotes. The skill lets you ask in plain words: is this upgrade live, and does my project break? Your agent answers from the signed registry, not from what it remembers, and checks your code with the same CLI. It works with any agent that can run a command in your terminal: Claude Code, Codex and others.

  • Answers from the registry. Every answer names the registry version, its signature and the slot or block it read the status from. If the registry cannot be verified, it does not answer at all.
  • Checks your whole project. Code, contracts, lockfiles and your RPC provider: it runs the same checks as the command line and points at the line to fix.
  • Says what it did not check. A rule that could not run, a file it did not read, a guess of its own: each is named, so silence never reads as a clean result.

Get the skill once:

git clone --depth 1 https://github.com/mskrad/Epochnotes ~/epochnotes-src

Then add it to your agent. The skill is one folder with a SKILL.md file, the common format for agent skills.

# Claude Code (terminal, or the Code tab of Claude Desktop)
mkdir -p ~/.claude/skills && cp -R ~/epochnotes-src/skills/epochnotes ~/.claude/skills/

# Codex
mkdir -p ~/.codex/skills && cp -R ~/epochnotes-src/skills/epochnotes ~/.codex/skills/

Any other agent: add this line to the project's AGENTS.md (or the agent's own instructions file):

For questions about network upgrades on Solana, Ethereum or Base, follow ~/epochnotes-src/skills/epochnotes/SKILL.md.

Optional: point it at the published log before you start the agent. Without this the skill names the published log and asks you first, because the publishers file is your trust anchor.

export EPOCHNOTES_VERSIONS=https://mskrad.github.io/Epochnotes/registry/versions
curl -fsS https://mskrad.github.io/Epochnotes/registry/publishers.json -o ~/.epochnotes-publishers.json
export EPOCHNOTES_PUBLISHERS=~/.epochnotes-publishers.json

Then ask:

Is transaction v1 live on Solana mainnet, and does this project break?
What does EIP-7702 change for my contracts on Base?
Check this project against recent network changes.

In Claude Code you can also call the skill by name: /epochnotes followed by the question.

A real answer, from a run on Oct 12, 2026, in Claude Code on a small demo app (shortened):

Yes, transaction v1 is live on Solana mainnet, and my-app breaks.
my-app/src/history.ts:6 calls getTransaction with maxSupportedTransactionVersion: 0.
Fix (from the entry): pass 1; with @solana/web3.js use 1.99.0 or later.

Status:   active on mainnet-beta since slot 447120000, read at slot 456149984 (feature account)
Registry: version 1, root 77216c0c..., signature verified, on-chain anchor matches
Not checked: the web3.js version (my-app has no lockfile); the runtime probe

The commands the skill runs are listed under For AI assistants.

Found in the field

We ran epochnotes check repo over 59 public Solana repositories, checked every hit by hand and reproduced each breakage on mainnet before reporting it. Twelve are reported; three are already fixed and merged. Outcomes as of 2026-10-27; an open pull request is a proposal, not an acceptance.

Project What broke Report Outcome
solana-foundation/solana-com The slot-time page read blocks with maxSupportedTransactionVersion: 0, which the RPC refuses once a block holds a v1 transaction issue #2141 merged: fix #2150, 2026-10-07
helius-labs/core-ai The MCP server and CLI asked for full blocks with version 0, so getBlock failed on v1 blocks issue #183 merged: fix #190, 2026-10-14
OpenZeppelin/openzeppelin-monitor The Solana monitor could not load nearly any recent mainnet block PR #515 merged: PR #515, 2026-10-26
wormhole-foundation/wormhole-sdk-ts parseTransaction and parseMessages threw on v1 transactions, and Wormhole messages are already posted in them PR #1049 open
zenmoney/ZenPlugins Solana wallet sync stopped with a TypeError when the sync window held one v1 transaction PR #1213 open
GetBlock-io/getblock-docs The pump.fun migrations guide dropped migrations sent as v1, and the getTransaction and getBlock references taught version 0 PR #25 open
helius-labs/photon-explorer The explorer showed "Failed to load transaction" for any v1 transaction PR #5 open
Squads-Protocol/public-v4-client The multisig lookup stopped at the first v1 transaction in a vault's history issue #48, PR #49 open
sendaifun/solana-new The debug-program agent skill taught a getTransaction call that fails on v1 PR #62 open
sendaifun/solana-mpp Payment verification threw for a payment sent as a v1 transaction PR #7 open
helius-labs/rpc-perf-dash The getBlock benchmark sized its last-hour and last-24h windows at 9,000 slots an hour; with ~212 ms slots they covered about 32 minutes and 12.7 hours PR #31 open
solana-foundation/pay The fanout preflight priced each new token account at the old 2,039,280-lamport rent; mainnet charges 1,488,440, so it asked for 37% more SOL than needed PR #535 open

The same list is on the project page. A daily workflow (.github/workflows/findings.yml) reads each open pull request from GitHub and, when one is merged or closed, updates site/findings.json, the Outcome column above and the page; npm run findings:refresh does the same locally.

Layout

Path Purpose
packages/core Library: entry schema, canonical hashing, validation, status per chain
packages/cli epochnotes command — a thin shell over core
programs/registry Anchor program: publishers and the version log
registry/ Entry schema, registry entries (YAML) and published versions
skills/epochnotes Agent skill: answers from the verified registry, checks a whole project
corpus/ Before/after code pairs and the manifest of what a correct check reports
index.html Project page, generated by npm run site from the entries and site/

Develop

Requires Node.js 22.12+, and for the program: Rust, Solana CLI 4.x, Anchor 0.32.1.

npm ci
npm run verify        # build + tests + lint
npm run build:program # anchor build
npm run corpus:check  # the corpus manifest, its files and the detection engine agree; prints recall

For AI assistants

skills/epochnotes is an agent skill (install it as shown in Ask your AI agent). It holds no facts about any change: it reads entries from the latest verified version, reads the activation status from the network, and refuses to answer when verification fails. The commands it uses work for any consumer:

epochnotes registry read --json --status mainnet-beta   # verified entries, their provenance, activation status with chain and slot
epochnotes registry read --json --status ethereum       # the same version, read on Ethereum: block, time, what confirmed each fork
epochnotes registry read --status base                  # the same entries, read on Base
epochnotes check repo <path> --versions <dir-or-url>    # detection rules taken from the verified version
epochnotes check rpc --rpc-url <endpoint>               # read-only probe: does this provider behave as the entry says

Every chain is named by its CAIP-2 id, and --chain (or --status for registry read) takes either that id or a name: mainnet-beta, devnet, testnet, localnet for Solana, ethereum and base for the EVM chains. On Solana a change activates by a feature account; on an EVM chain by a fork time, which the head block confirms where the fork adds a header field — a state read by time alone says so. The endpoint is asked which chain it serves: one that serves another chain than the one asked for is refused rather than read, and an endpoint given alone with --rpc-url is read as the chain it says it is. Every reading names the chain and the point it was taken at, and every state says what showed it.

Detection rules read TypeScript, JavaScript, Rust, Go, Python, Markdown and Solidity, and npm lockfiles; the engine also reads Cargo lockfiles, though no entry has a rule for them yet. A rule says how sure it is: breaks is certain, check needs a person to look. The corpus in corpus/ holds before/after pairs — real fixes from open-licence repositories where one was found, written cases otherwise — and npm run corpus:check prints recall per entry; what a rule leaves out on purpose is recorded there with the reason.

A publisher withdraws an entry with a record on chain, which the signed log alone does not show. With --onchain, registry read, check repo, check rpc and rent scan leave withdrawn entries out, name them under revoked, and refuse an entry asked for by name (exit 1), in the same words as registry verify. Without it the output says that revocations were not checked.

--versions and --publishers default to the environment variables EPOCHNOTES_VERSIONS and EPOCHNOTES_PUBLISHERS. --working-copy <dir> reads unsigned entry files, and the output says so.

A runtime probe is data in the entry, not code: the read-only calls to make against a known transaction, what to record from each answer, and the conditions under which the endpoint behaves as the entry says. check rpc first asks the endpoint which chain it serves, then runs only the probes pinned to that chain — today a Solana mainnet-beta probe and one each for Ethereum and Base.

A check that could not ask its question says so instead of passing. check repo lists, under entriesNotChecked, every entry that carries no rule a static check can run: no finding for such an entry means nothing was looked for. check rpc exits 2, not 0, when no probe observed the endpoint — the probes of an entry are pinned to the cluster of their fixture, so an endpoint of another cluster is left unexamined, and a check that runs it in CI must not go green on that.

Watching for changes

Entries are written by people; the watcher tells them where to look. watch solana reads every feature gate agave declares (feature-set/src/lib.rs at a pinned commit) and its state on mainnet-beta, testnet and devnet, compares it with the snapshot of the last look, and reports:

  • gates on the way to mainnet-beta — active on testnet or devnet, or scheduled on mainnet-beta — and the entry that covers each, if any;
  • gates agave declared since the last look, and every change of state per cluster;
  • for each gate that moved and no entry names, a draft entry: the activations and the source are filled in, what breaks and how to fix it are not.
epochnotes watch solana --state ~/.epochnotes/watch/state.json --out ~/.epochnotes/watch   # report.md, report.json, drafts/

It only reads, and it never signs or publishes. A draft carries DRAFT: markers that registry validate refuses, so it cannot be published by mistake: a person writes it from the SIMD, adds the SIMD as a source, and signs. A gate whose account holds lamports but is not a feature account is reported as unknown, with what the account holds instead. A look that could not read agave or any of the clusters exits 2 and leaves the last snapshot as it was.

The project page (index.html, served by GitHub Pages from the root of main) shows the entries and the latest watcher reading. npm run site -- --watch-report <dir>/report.json takes a new reading into site/watch.json and regenerates the page; a test fails while the page is behind the entries.

Run it on a schedule — cron, CI, or a scheduled task of an AI assistant that also drafts the prose from the SIMD for a person to review. Next: watchers for Ethereum and Base (fork times in the client configurations), a notification when something not in the registry moves, and the project page updated from each report without a person in between.

Rent held above the minimum

The staged rent reduction lowers the minimum balance of every account, and returns nothing by itself. rent scan measures, read-only, what is left above the minimum:

epochnotes rent scan --program <address>            # every account of a program, split by account type
epochnotes rent scan --program <address> --sample   # a program too large for one request: seeded random sample, with a standard error
epochnotes rent scan --wallet <address>             # accounts of known programs that the wallet owns

Getting it back:

epochnotes rent close --account <address>   # builds the unsigned transaction for the owner, and simulates it; sends nothing
epochnotes rent template --account-type Position --authority-field owner   # an Anchor instruction for your own program

rent close has adapters for OpenBook v2 open-orders accounts and marginfi v2 accounts. It reads the owner out of the account, builds the close transaction with that owner as the only signer and as the destination, and asks the cluster what the transaction would do (simulateTransaction, signature checks off). It holds no keys and never sends. A program's IDL is not proof that an instruction runs: Drift's IDL lists deleteUser and reclaimRent, and the deployed program rejects both, which only the simulation showed. rent template prints withdraw_excess: authority-gated, with the minimum read from the cluster at run time. It takes everything the account holds above that minimum, so it fits accounts whose lamports are a rent deposit and nothing else; the template says so where a developer will read it. With the default names it is the file programs/rent-example/src/withdraw_excess.rs, which is tested on a local validator.

A sample splits accounts by one byte of their data. The groups of the byte values 0x00, 0x01 and 0xff are always read, because a flag, a counter or padding piles a whole account type onto them; the rest is sampled. Accounts too short to have that byte sit in no group; they are read separately, by exact size, and counted as they are. When the offset is too far in for that, the result is marked partial. The standard error is that of excessNow of the sampled part.

The rates come from the registry entry, the rate in force from the Rent sysvar, the state of every step from its feature gate. For OpenBook v2, marginfi v2 and Drift the report says who can close each account type — its owner, a program admin, or nobody — as read from the close constraints in the program's source, with the signer taken from its on-chain IDL; for Drift, from what its deployed program answered to a simulation. excessNow counts only accounts whose balance is exactly an earlier minimum; everything else above the minimum is reported apart, as an upper bound that may be reserves. The figures are estimates of deposits, not a market size.

What the signed log proves, and what it does not

A registry version is a Merkle root over all entries, linked to the previous version and signed by its publisher. epochnotes registry verify checks the signatures, the chain of versions and the content hash without trusting the server. --onchain also compares the log with the registry program on Solana, which is what catches a log that was truncated, or re-signed with different content by the holder of the publisher key, and an entry its publisher has revoked.

Limits you should know about:

  • Upgrade authority. The on-chain program is upgradeable and one key holds the authority. Whoever holds it can replace the program. The log cannot be forked by a publisher or a server; it can by that key holder.
  • Initialization. initialize makes its first caller the admin. Deploy and initialize in one go, then read the Config account back.
  • No admin rotation. Losing the admin key means upgrading the program.
  • The RPC node is trusted. State is read at confirmed commitment with no state proofs. A lagging or dishonest node can hide newer versions and revocations.
  • Revision rules live off chain. The program sees roots, not content, so "every edit raises rev" is enforced by the publisher's tooling, not by the chain.
  • A suspended publisher fails verification, including versions it published earlier: the chain does not record since when the key was unsafe.
  • Revocations are permanent, and a revoked id is never reused.
  • Writes go to devnet and to a local validator only. The cluster is identified by its genesis hash, not by the name or URL you pass.

Deployed on devnet only, for development. Nothing here has been audited.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages