Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 32 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
# AGENTS.md

EFS — Ethereum File System. On-chain file system built on EAS attestations. Pre-launch, devnet target April 19, 2026. Breaking changes are acceptable for now as there's no real data created yet. Good design and future proofing is key.
EFS — Ethereum File System.

**Production web client** (Vite/Lit, separate repo): https://github.com/efs-project/client. The internal UI at `packages/nextjs/` in this repo is a Scaffold-ETH-based devtools/debug interface — not the production client. Don't apply Scaffold-ETH patterns (`useScaffoldReadContract` etc.) to the production client.
> **Repository status (2026-07-23): deployed v1 reference implementation.**
> The EAS-based v1 system is live on Sepolia with registered schemas and real
> test data. It is not deployed to mainnet. EFS is now being redesigned from
> scratch as v2, so this repository remains authoritative for **v1 behavior**
> only. Do not extend a v1 mechanism or present it as the v2 baseline without a
> current planning-vault decision that explicitly carries it forward.

**Legacy Vite/Lit client** (separate repo):
https://github.com/efs-project/client. The internal UI at `packages/nextjs/`
is the newer v1 explorer/debug interface. Neither is the Client v2
implementation target unless the current design process explicitly chooses it.

## Read on init

Expand All @@ -19,23 +29,36 @@ EFS — Ethereum File System. On-chain file system built on EAS attestations. Pr
- **[specs/README.md](./specs/README.md)** — index of detailed specs (authoritative current behavior)
- **[docs/adr/](./docs/adr/)** — past decisions and reasoning
- **[docs/FUTURE_WORK.md](./docs/FUTURE_WORK.md)** — backlog
- **[docs/LAUNCH_CHECKLIST.md](./docs/LAUNCH_CHECKLIST.md)** — pre-launch blockers
- **[docs/LAUNCH_CHECKLIST.md](./docs/LAUNCH_CHECKLIST.md)** — retired v1 launch posture and the gate for creating a future checklist
- **[reference/README.md](./reference/README.md)** — EAS, EIP, Scaffold-ETH docs (indexed by task)

## Cross-repo coordination — the planning vault

EFS uses a separate **planning vault** as the cross-repo coordination point across this repo, the production client (`efs-project/client`), and the future SDK. Repo: [efs-project/planning](https://github.com/efs-project/planning); typically cloned alongside this one (target layout: `/efs/{contracts,client,sdk,planning}/`).
EFS uses a separate **planning vault** as the cross-repo coordination point
across this repo, the legacy client (`efs-project/client`), the pre-v2 SDK
(`efs-project/sdk`), and the v2 redesign. Repo:
[efs-project/planning](https://github.com/efs-project/planning).

The vault holds:

- **Cross-repo designs** with a name-first → numbered-at-promotion lifecycle. Designs that span multiple repos are tracked there; per-repo decisions stay here as ADRs.
- **Cross-repo Kanban board**, milestones (e.g., OnionDAO hackathon 2026-06-01), and an append-only decisions log.
- **Cross-repo Kanban board**, live milestones, and an append-only decisions log.
- **Glossary** of cross-cutting EFS terms.
- **Onboarding** for AI agents (start-here, conventions, escalation, write-a-design walkthrough).

Read the vault's [`AGENTS.md`](https://github.com/efs-project/planning/blob/main/AGENTS.md) on init when your task is cross-repo. **A landed cross-repo design typically produces one or more ADRs here** — the planning design is the cross-cutting proposal; the resulting ADR(s) in this repo's `docs/adr/` are the per-repo decision artifacts. Don't duplicate substantive content; the design tombstones to point at the per-repo ADRs once implementation lands.
Read the vault's
[`AGENTS.md`](https://github.com/efs-project/planning/blob/main/AGENTS.md) on
init when your task is cross-repo. During the v2 redesign, start with the
[`efsv2` current spine](https://github.com/efs-project/planning/blob/main/Designs/efsv2/README.md)
before proposing architectural work here. **A landed cross-repo design
typically produces one or more ADRs here** — the planning design is the
cross-cutting proposal; the resulting ADR(s) in this repo's `docs/adr/` are the
per-repo decision artifacts. Don't duplicate substantive content; the design
tombstones to point at the per-repo ADRs once implementation lands.

For tasks fully scoped to this repo, the planning vault is optional context. For tasks spanning repos or unblocking a milestone, it's required reading.
For maintenance of the deployed v1 implementation, repo-local specs and ADRs
remain authoritative. For architecture, v2 work, cross-repo work, or milestone
work, the planning vault is required reading.

## PR review quick start

Expand Down Expand Up @@ -259,7 +282,8 @@ cd packages/hardhat && npx hardhat test test/EFSIndexer.test.ts --network hardha

## Invariants

**Hardened (load-bearing — don't violate without writing a superseding ADR):**
**Hardened v1 invariants (load-bearing for the deployed Sepolia system — don't
violate without writing a superseding ADR):**

- **Cardinality is declared at the schema level (PIN vs TAG), not per-attestation.** The schema UID is the only permanent, globally-coordinated, machine-readable slot in EFS. PIN = cardinality 1 (file placement, PROPERTY value binding); TAG = cardinality N with an `int256 weight` (folder visibility, descriptive labels, schema-alias discovery). See ADR-0041.
- **Active TAG** (kernel) = unrevoked edge exists. Weight does not affect kernel activity. Use this definition in contracts, resolver helpers, and any non-filter code path.
Expand Down
155 changes: 39 additions & 116 deletions docs/LAUNCH_CHECKLIST.md
Original file line number Diff line number Diff line change
@@ -1,130 +1,53 @@
# Launch Checklist

Two distinct launches:
- **Devnet (April 19, 2026)** — bicycle day. Forked Sepolia on a VPS, weekly reset, upgradeable contracts allowed for iteration.
- **Mainnet (target ~April 22, 2026 → likely later)** — permanent contracts (ADR-0030), no second chances.
> **Status: retired v1 checklist.** The April 2026 devnet/mainnet schedule was
> not the plan EFS ultimately followed. Do not use its dates, unchecked items,
> or architecture assumptions to plan current work.

Update statuses with `[x]` as items land. Add notes inline if blocked.
## Current launch posture

---
- The EAS-based v1 system is deployed to Sepolia. Nine schemas were registered
and the initial scaffolding was sealed on 2026-06-19; current addresses and
authority state live in `docs/CHAINS.md`.
- Mainnet has not been deployed and has no active launch date.
- The project is redesigning EFS from scratch as v2. The carrier, identity,
authority, record, lens, query, privacy, filesystem, SDK, and client
boundaries are being reconsidered together.
- Existing v1 contracts, deployment tooling, explorer, SDK branch, and client
are evidence and reference implementations. They are not a mainnet release
candidate by default.

## Devnet (April 19, 2026)
The active project milestone surface is the planning vault's `Milestones.md`.
The current v2 architecture and sequencing live under
`planning/Designs/efsv2/`.

### Infrastructure
## Historical v1 outcome

- [ ] VPS provisioned with forked Sepolia (anvil/hardhat fork)
- [ ] IPFS node running (kubo or similar) for devnet file hosting
- [ ] Arweave gateway/uploader available (testnet or hosted)
- [ ] Magnet/torrent seed infrastructure (webtorrent tracker?)
- [ ] HTTPS test endpoint(s) for HTTP transport testing
- [ ] Weekly reset cron job (Sunday 00:00 UTC?)
- [ ] DNS / public URL for the devnet
The old checklist mixed three different efforts:

### Contracts
1. an April forked devnet;
2. the later Sepolia deployment and buildathon;
3. a proposed immutable v1 mainnet launch.

- [ ] Devnet contracts deployed behind upgradeable proxy (resolved in `docs/QUESTIONS.md`: which proxy pattern)
- [ ] Upgrade procedure documented (storage layout enforcement via OpenZeppelin's `hardhat-upgrades`)
- [ ] Reset procedure includes redeploying all contracts and clearing all on-chain state
- [ ] EFSIndexer wired to EdgeResolver, MirrorResolver, EFSSortOverlay
- [ ] System anchors created: root plus default `/transports/*` children (`onchain`, `data`, `ipfs`, `arweave`, `magnet`, `https`, `ftp`, `s3`, `gs`, `dat`, `rsync`, `bittorrent`)
- [ ] `setTransportsAnchor()` called on MirrorResolver
Sepolia shipped. The buildathon wound down with low participation. The v1
mainnet launch did not happen, and the v2 redesign superseded the old delivery
plan before its unchecked items were reconciled.

### Frontend / Client
Git history preserves the detailed April checklist. It remains historical
evidence, not an active work queue.

- [ ] Production EFS Client (Vite/Lit, separate repo) reviewed for devnet readiness
- [ ] Internal devtools UI (`packages/nextjs/`) confirmed working against devnet
- [ ] Client knows how to construct `web3://` URLs pointing at the devnet router
- [ ] "DEVNET — RESETS WEEKLY" warning banner in client UI
- [ ] **Empty lens list = "show all data" (still filtered + paged).** Intended model:
a lens of `vitalik.eth` means "only vitalik's data", "me/my address" means "only
mine", and an EMPTY list means "all data from everyone" (the system/nsfw exclusion
and pagination still apply). Today an empty/absent lens chain shows nothing, and
`defaultLensesForContainer` backfills `systemLenses` so it's rarely empty. Needs:
**(a)** an ADR superseding the relevant ADR-0031/0039 viewer-sovereignty +
systemLenses-tail semantics; **(b)** a CONTRACT path for an unscoped-but-filtered
directory page — e.g. `EFSFileView.getDirectoryPageFiltered` treating an empty
`attesters[]` as "all attesters" while still applying the exclude filter + cursor
(this MUST land before the Sepolia contract freeze — EFSFileView is redeployable
but the model should be settled); **(c)** client wiring so an empty
`lensAddresses` routes to that path instead of rendering blank. Deferred from
PR #27 (the on-chain tag-filter PR). Design notes in `docs/FUTURE_WORK.md`.
## Gate for a future launch checklist

### Communication
Create a new dated checklist only after James has explicitly set a launch
milestone and all of the following exist:

- [ ] Devnet announcement post drafted (positioning: "early access, expect breakage, don't store anything you care about")
- [ ] Discord/Telegram/community channel for devnet feedback ready
- [ ] Bug report / feedback flow documented
- an adopted v2 constitution and support matrix;
- an implementation target with current specs and ADR boundaries;
- a deployment and migration posture;
- explicit security-review and audit requirements;
- a client/SDK release surface;
- honest data-durability, authority, privacy, and operational claims.

---

## Pre-Mainnet (target April 22, 2026 — likely slips)

### Pre-Mainnet Architectural Conversations

These are open architectural conversations identified during the ADR-0041 PIN/TAG schema split (PR #10) that are out of scope for that change but become much harder to revisit after mainnet. Each deserves its own focused session and ADR — list each conversation as `[ ]` until either an ADR lands or an explicit "no change for v1" decision is recorded in `docs/decisions.md`.

- [ ] **DATA schema deprecation conversation.** A suggestion surfaced in PR #10's review to remove the DATA schema entirely and replace file placement with `PIN(definition="storageURI", value=BLOB)`. Touches ADR-0001 (three-layer model), ADR-0002 (DATA standalone non-revocable), ADR-0004 (content dedup via `dataByContentKey`), ADR-0011 (transports), ADR-0012 (transport priority), ADR-0013 (lens-scoped mirror selection). The proposal removes the content-addressing layer that lets multiple uploaders converge on the same identity; that layer needs to be replaced by something equivalent or explicitly given up — not just deleted. Decision needed pre-mainnet: keep DATA as-is, redesign, or remove. Default if not addressed: keep DATA (record explicit "no change" decision).
- [ ] **Kernel layer-2 / layer-3 split conversation.** Today `EFSIndexer.sol` does both layer 2 ("I received an attestation; route to handler" — use-case-neutral EAS indexing) and layer 3 ("edges, nodes, paths, active sets" — the graph DB). The two are conceptually separable per the working sketch in `specs/01-System-Architecture.md`. Pre-mainnet split would let layer 2 be reused by other EAS-based projects and let layer 3 stand alone as a graph DB; post-mainnet split is much harder because ADR-0030 freezes EFSIndexer's interface. Cost: cross-contract calls in resolver hot paths add ≥2.6k gas per attestation, so the split must be designed deliberately. Decision needed pre-mainnet: split now, defer to v2 with an explicit migration story, or commit to the combined kernel forever.
- [ ] **Layer-3 audit of `_containsAttestations` (and similar) for file-system bleed.** Some indexes in `EFSIndexer.sol` may be more file-system-specific than graph-generic (the qualifying-folder write-time index from ADR-0008, `_containsAttestations` propagation from ADR-0010). A focused audit would catalog which storage maps belong to layer 3 (graph kernel) vs which should migrate to a layer-4 file-system overlay contract. Output feeds both the kernel split above and any future use-case overlays (social graph, knowledge base, lists). Decision needed pre-mainnet: audit + document layer assignment, even if no code moves; post-mainnet the layer assignment is locked into permanent storage shapes.

### External Audit

- [ ] **External audit pass on EFSIndexer** — single most important item. Engage Trail of Bits, OpenZeppelin, or run a Code4rena contest. Two-week minimum engagement. Treat critical findings as launch-blocking.
- [ ] All audit findings resolved or documented as accepted-risk (with reasoning)
- [ ] Audit report published

### Internal Review

- [ ] Final agent-review pass after all audit-driven fixes (Claude + Codex + Gemini cross-review)
- [ ] All P1/P2 items in PR review history confirmed resolved
- [ ] Test suite >270 passing (current state preserved)
- [ ] Gas snapshot captured for hot paths (upload, directory listing, web3:// resolution) — baseline for regression detection
- [ ] **Classifier parity test** — off-chain URL classifier (`packages/nextjs/utils/efs/containers.ts#classifyTopLevelSegment` and the production Vite/Lit client's equivalent) produces byte-identical `(flavor, uid)` tuples to `EFSRouter.classifyTopLevel(string)` across a fixture table: valid 40-hex address, all-zero address, ENS name (off-chain only — contract rejects), unregistered 64-hex, registered schema UID, attestation UID, malformed hex (odd-length, non-hex chars), empty string, plain anchor name, and anchor name that happens to look like `0x…`. ADR-0030 locks classifier semantics at mainnet deploy, so any off-chain drift becomes a permanent interop bug. `classifyTopLevel` is a pure external view — the parity test can run against a local hardhat deployment with no state required. Tracked as review comment #8 on PR #9.

### Mainnet Deploy Readiness

- [ ] Deploy script tested end-to-end on a fresh fork (not just incremental deploys)
- [ ] All `setTransportsAnchor`, `wireContracts`, etc. one-time calls verified to land in correct order
- [ ] Address mismatch assertions in deploy script confirmed working (revert on bad nonce prediction)
- [ ] `yarn hardhat:simulate` passes against the would-be mainnet config
- [ ] **Recovery plan documented**: if EFSIndexer has a bug post-deploy, what's the migration path? Even if the answer is "redeploy everything," the dependency graph must be written down.
- [ ] Deployer key custody plan (multisig, hardware wallet, etc.)

### Production UI

- [ ] Production EFS Client (external Vite/Lit repo) reviewed end-to-end
- [ ] Lenses UX is intuitive — naive user understands "whose content am I seeing?"
- [ ] Gas costs surfaced upfront in upload flow (not post-hoc)
- [ ] "Permanent archive, not a Dropbox" positioning crystal clear in UI copy
- [ ] Mirror unavailability surfaced gracefully (not just blank previews)

### Ecosystem

- [ ] At least one compelling curator account seeded (Wikipedia snapshot, Project Gutenberg, government records, etc.)
- [ ] Mirror stewardship plan: who pins IPFS content, who funds Arweave uploads
- [ ] Public web3:// gateway compatibility verified (w3link.io, wevm.dev)
- [ ] Subgraph or off-chain indexer running (or external partner committed to running one)

### Strategic / Comms

- [ ] Launch positioning finalized: "permanent record" not "file service"
- [ ] EAS dependency communicated honestly (we are betting on EAS as foundation)
- [ ] Mainnet permanence communicated (no upgrades, no admin override) — this is a feature, market it
- [ ] Press / community announcement drafted

---

## Post-Launch (Week 1)

- [ ] Monitor gas costs on real usage vs. test estimates
- [ ] Mirror availability monitoring — flag when published content becomes unfetchable
- [ ] Bug-bounty program live (or contracts immutable enough that bounty is "publish a finding for fame")
- [ ] First post-mortem if anything broke

---

## Notes

- The devnet → mainnet timeline (April 19 → April 22) is tight. Slipping mainnet for the audit is the right call if pressure comes; devnet learnings will feed into mainnet adjustments anyway.
- "Bicycle day" (April 19) is the symbolic launch date — no real reason to slip it for technical issues; the devnet is meant to be rough.
- Mainnet date should be governed by audit completion, not the calendar. ADR-0030 is unforgiving.
Until then, track research and implementation in the planning vault and
repo-local PRs. Do not convert design hypotheses into launch blockers or
calendar commitments.
Loading
Loading