2026-05-16 00:32:38 +02:00
|
|
|
# AGENTS.md
|
|
|
|
|
|
|
|
|
|
This repository is `geth`, a Rust monorepo for a personal, local-first,
|
|
|
|
|
Iroh-based mesh runtime. It is not the Ethereum geth client.
|
|
|
|
|
|
|
|
|
|
`geth` has one executable only:
|
|
|
|
|
|
|
|
|
|
- daemon mode: `geth daemon run`
|
|
|
|
|
- control mode: `geth status`, `geth node ...`, `geth cas ...`, etc.
|
|
|
|
|
|
|
|
|
|
Do not add separate `gethd` or `gethctl` binaries.
|
|
|
|
|
|
|
|
|
|
## Core Invariants
|
|
|
|
|
|
|
|
|
|
- All remote geth node-to-node communication must be over Iroh.
|
|
|
|
|
- SSH is not a geth transport and must not become a fallback transport.
|
|
|
|
|
- SSH keys are admin trust anchors and ecosystem integration points.
|
|
|
|
|
- SSH certificate flows and SSH proxying are geth-managed workflows carried by
|
|
|
|
|
local control now and Iroh later.
|
|
|
|
|
- The daemon owns the Iroh endpoint, local identity, local metadata store,
|
|
|
|
|
resource registry, module routing, and synchronized data structures.
|
|
|
|
|
- Discovery is untrusted and never grants capabilities or trust.
|
|
|
|
|
- Authorization is resource-scoped and capability-based.
|
|
|
|
|
- Signed data must use deterministic canonical encoding, not arbitrary JSON.
|
|
|
|
|
- Bearer secrets may grant resource-specific access but must not create trusted
|
|
|
|
|
node identity or trust graph mutation rights.
|
|
|
|
|
|
|
|
|
|
## Workspace Shape
|
|
|
|
|
|
|
|
|
|
- Binary crate: `crates/geth`
|
|
|
|
|
- CLI definitions and formatting: `crates/geth-cli`
|
|
|
|
|
- Daemon orchestration and local control: `crates/geth-node`
|
|
|
|
|
- Local JSONL control protocol: `crates/geth-control`
|
|
|
|
|
- Shared newtypes: `crates/geth-types`
|
|
|
|
|
- Canonical encoding/hash helpers: `crates/geth-codec`
|
|
|
|
|
- Config/path handling: `crates/geth-config`
|
|
|
|
|
- Local SQLite metadata store: `crates/geth-store`
|
|
|
|
|
- Local CAS: `crates/geth-cas`
|
|
|
|
|
- SSH trust/cert models: `crates/geth-ssh-identity`
|
|
|
|
|
|
|
|
|
|
Keep crates focused. Do not create a `geth-common` crate.
|
|
|
|
|
|
|
|
|
|
## Implementation Rules
|
|
|
|
|
|
|
|
|
|
- Prefer existing crate boundaries and patterns.
|
|
|
|
|
- Libraries should use `thiserror`; binaries may use `anyhow`.
|
|
|
|
|
- Keep async only where it is useful.
|
|
|
|
|
- Treat network and control inputs as untrusted.
|
|
|
|
|
- Do not implement complex cryptographic protocols casually. Add types,
|
|
|
|
|
roadmap notes, and explicit non-claims when a feature is only scaffolded.
|
|
|
|
|
- Do not claim Keyhive/BeeKEM-level security properties until they are actually
|
|
|
|
|
designed, implemented, and tested.
|
|
|
|
|
- User service installation must target user service managers, not system
|
|
|
|
|
service managers.
|
|
|
|
|
|
|
|
|
|
## Testing Requirements
|
|
|
|
|
|
|
|
|
|
Every behavior change should include tests proportional to risk:
|
|
|
|
|
|
|
|
|
|
- Add unit tests for pure data models, reducers, encoders, path generation, and
|
|
|
|
|
command builders.
|
|
|
|
|
- Add integration tests for CLI/daemon behavior when practical.
|
|
|
|
|
- Use temp directories and temp `GETH_HOME` values.
|
|
|
|
|
- Avoid tests that require privileged services, real YubiKeys, real network
|
|
|
|
|
relays, or host service-manager mutation.
|
|
|
|
|
- For platform-specific behavior, use generated-definition tests or cfg guards.
|
|
|
|
|
|
|
|
|
|
Before finishing a code change, run at least:
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
cargo fmt --all -- --check
|
|
|
|
|
cargo check --workspace --all-targets
|
|
|
|
|
cargo test --workspace
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Also run clippy when reasonable:
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
cargo clippy --workspace --all-targets -- -D warnings
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
If a command cannot be run, state why in the final report.
|
|
|
|
|
|
|
|
|
|
## Documentation And Roadmap
|
|
|
|
|
|
|
|
|
|
Keep documentation updated with behavior changes:
|
|
|
|
|
|
|
|
|
|
- Update `README.md` for user-visible commands or workflows.
|
|
|
|
|
- Update `docs/architecture.md` for architectural boundaries or invariants.
|
|
|
|
|
- Add or update ADRs in `docs/adr/` for durable decisions.
|
|
|
|
|
- Update `docs/roadmap.md` whenever a feature is added, completed, split, or
|
|
|
|
|
deferred.
|
|
|
|
|
|
|
|
|
|
Roadmap items should be actionable and checkable:
|
|
|
|
|
|
|
|
|
|
- Use `[ ]`, `[~]`, or `[x]`.
|
|
|
|
|
- Include acceptance criteria.
|
|
|
|
|
- Split vague items before implementation.
|
|
|
|
|
- Do not mark an item done unless the acceptance criteria are met or revised
|
|
|
|
|
honestly.
|
|
|
|
|
|
|
|
|
|
## Current Feature Boundaries
|
|
|
|
|
|
|
|
|
|
- Local daemon, local control socket, local identity, local store, local CAS,
|
2026-05-16 03:17:45 +02:00
|
|
|
daemon-owned Iroh endpoint startup, built-in relay-mode config, SSH
|
|
|
|
|
certificate metadata, revocation metadata, user service definitions, and a
|
2026-05-16 14:24:21 +02:00
|
|
|
pinned `geth-iroh` endpoint wrapper with protocol-router scaffold, peer-card
|
2026-05-18 12:09:50 +02:00
|
|
|
types, manual signed peer-card export/import/list commands, `geth peer ping`
|
2026-05-18 17:05:43 +02:00
|
|
|
and `geth peer auth-check` over Iroh, signed peer-card LAN discovery payloads,
|
2026-05-18 17:24:10 +02:00
|
|
|
authorized `geth cas fetch`, `geth ssh cert sync`, and
|
2026-05-18 18:29:45 +02:00
|
|
|
`geth ssh revocation sync` over the Iroh control ALPN, a background SSH
|
2026-05-18 22:17:27 +02:00
|
|
|
metadata and KV live-sync loop with per-peer cursors in `module_state` and an
|
|
|
|
|
authorized sync-status summary that lets peers disclose only permitted stream
|
|
|
|
|
watermarks before module pulls,
|
2026-05-18 18:36:03 +02:00
|
|
|
untrusted discovery-backend trait, custom relay-map config, and Iroh
|
|
|
|
|
local-network discovery toggle exist.
|
2026-05-16 14:37:16 +02:00
|
|
|
- Canonical signed-operation envelopes exist for keychain/auth signature
|
2026-05-16 14:39:18 +02:00
|
|
|
payloads. The keychain reducer builds an active identity view for admin keys,
|
|
|
|
|
users, devices, nodes, agents, and endpoint bindings.
|
2026-05-16 14:41:23 +02:00
|
|
|
- The auth reducer builds a current permission view for resources, grants,
|
2026-05-16 16:32:03 +02:00
|
|
|
groups, and bearer access. The daemon persists local auth grant/revoke ops
|
2026-05-18 04:06:41 +02:00
|
|
|
and uses them for `auth explain`. `kv set --subject <principal>` enforces
|
|
|
|
|
local KV write grants for non-local test callers. Signature validation and
|
|
|
|
|
broader daemon-side module enforcement are still roadmap work.
|
2026-05-16 16:34:20 +02:00
|
|
|
- The daemon persists local keychain init/admin-key ops and reduces them for
|
2026-05-19 16:04:20 +02:00
|
|
|
`keychain status`. `keychain init --signing-key <path>` signs recorded
|
|
|
|
|
keychain ops with `ssh-keygen -Y sign` under the
|
|
|
|
|
`geth.keychain.v1@geth.local` namespace and stores signatures locally.
|
2026-05-19 18:58:07 +02:00
|
|
|
`keychain status` verifies stored signatures with OpenSSH when public key
|
|
|
|
|
material is available. Verification before accepting replicated keychain ops
|
|
|
|
|
is still roadmap work.
|
2026-05-16 21:10:25 +02:00
|
|
|
- Local CAS supports pin/unpin metadata, surfaced through `cas list`, and
|
2026-05-18 17:18:25 +02:00
|
|
|
`cas cleanup` evicts unpinned blobs while retaining pinned blobs. The daemon
|
|
|
|
|
can fetch CAS blobs from an imported signed peer card over Iroh when the peer
|
2026-05-19 15:37:02 +02:00
|
|
|
grants `cas.fetch` on `resource:cas:local`; successful fetches record local
|
|
|
|
|
provider metadata visible through `geth cas providers <hash>`. Full
|
|
|
|
|
`iroh-blobs` provider integration is still roadmap work.
|
2026-05-17 21:20:24 +02:00
|
|
|
- The CAS crate can build deterministic tree objects for local file trees and
|
2026-05-18 03:50:09 +02:00
|
|
|
store those manifests as CAS blobs. The daemon can register and scan local
|
|
|
|
|
file roots, reporting create/update/delete/rename changes without writing back
|
2026-05-20 13:22:40 +02:00
|
|
|
to the working tree. `geth cas root sync <node-id> <name>` can pull authorized
|
|
|
|
|
remote tree metadata and CAS tree bytes, recording a peer-qualified remote
|
|
|
|
|
root with path `remote:<node>:<name>` without applying files or overwriting
|
2026-05-20 13:26:50 +02:00
|
|
|
same-named local roots. Background live-sync refreshes authorized remote file
|
|
|
|
|
roots from sync-status `cas-tree:<name>` watermarks. Durable local
|
|
|
|
|
file-conflict records can be listed and resolved manually; automatic
|
|
|
|
|
cross-node conflict detection and file application are still roadmap work.
|
2026-05-16 21:54:49 +02:00
|
|
|
- DB resources can be registered locally and report local-only status plus a
|
2026-05-17 20:01:36 +02:00
|
|
|
read-only SQLite schema summary/hash and `crsql_changes` metadata when
|
2026-05-17 20:32:36 +02:00
|
|
|
present. The DB crate and daemon can extract typed read-only `crsql_changes`
|
2026-05-18 22:11:57 +02:00
|
|
|
batches through `geth db changes`. `geth db sync <node-id> <name>` can pull
|
|
|
|
|
authorized typed `crsql_changes` batches over the protected Iroh control ALPN
|
|
|
|
|
with `db.sync` on the remote `resource:db:<name>`, compare schema metadata,
|
2026-05-19 19:02:39 +02:00
|
|
|
apply compatible batches into local `crsql_changes`, and advance
|
|
|
|
|
per-peer/per-DB cursors during manual or background live-sync. Loading and
|
|
|
|
|
configuring cr-sqlite for real application databases is still outside the
|
|
|
|
|
bootstrap.
|
2026-05-18 18:36:03 +02:00
|
|
|
- KV stores support local SQLite-backed create/set/get plus authorized
|
|
|
|
|
`geth kv sync <node-id> <name>` over Iroh. Background live-sync refreshes
|
|
|
|
|
local KV stores from known peers with per-peer/per-KV cursors. Iroh Documents
|
2026-05-17 18:26:30 +02:00
|
|
|
replication and command-level prefix-capability enforcement are still roadmap
|
|
|
|
|
work. The auth evaluator already understands `kv.write_prefix:<prefix>`
|
|
|
|
|
grants for `kv.write_key:<key>` requests.
|
2026-05-17 19:59:03 +02:00
|
|
|
- Document resources can be registered locally and updated with validated local
|
2026-05-18 18:49:34 +02:00
|
|
|
JSON state. `geth document sync <node-id> <name>` and background live-sync can
|
|
|
|
|
pull authorized JSON last-writer-wins state over Iroh. Automerge editing/state
|
|
|
|
|
and true CRDT sync are still roadmap work.
|
2026-05-17 18:23:51 +02:00
|
|
|
- Pubsub supports local daemon-lifetime publish/subscribe snapshots through a
|
2026-05-18 18:41:04 +02:00
|
|
|
bounded in-memory ring buffer. Remote publish over the protected Iroh control
|
2026-05-19 15:28:48 +02:00
|
|
|
ALPN requires `pubsub.publish` on `resource:pubsub:<topic>`. Remote subscribe
|
|
|
|
|
over the same path requires `pubsub.subscribe` and returns the peer's current
|
|
|
|
|
daemon-lifetime snapshot. Iroh-gossip replication and private topics are still
|
|
|
|
|
roadmap work.
|
2026-05-18 18:45:10 +02:00
|
|
|
- Pipe listen/connect supports a daemon-lifetime registry. Remote
|
|
|
|
|
`geth pipe connect <name> --node <node-id>` uses the protected Iroh control
|
2026-05-19 19:21:42 +02:00
|
|
|
ALPN and requires `pipe.connect` on `resource:pipe:<name>`. Remote
|
|
|
|
|
`geth pipe listen <name> --node <node-id>` requires `pipe.listen` on the same
|
|
|
|
|
resource before creating a daemon-lifetime listener on the peer. Iroh byte
|
|
|
|
|
streams and TCP/Unix forwarding are still roadmap work.
|
2026-05-19 15:51:11 +02:00
|
|
|
- `geth ssh proxy <node-id>` performs an authorized control-plane handshake over
|
|
|
|
|
the protected Iroh control ALPN and requires `ssh_proxy.connect` on
|
|
|
|
|
`resource:ssh-proxy:local` before returning proxy metadata. It does not carry
|
|
|
|
|
SSH bytes or connect to sshd/admin shell yet.
|
2026-05-16 22:18:49 +02:00
|
|
|
- Resource secret epoch metadata can be created, rotated, and listed locally.
|
2026-05-17 02:58:58 +02:00
|
|
|
Bearer access metadata can be created/listed/revoked as resource-scoped auth
|
2026-05-19 19:08:08 +02:00
|
|
|
ops and must not allow trust graph mutation capabilities. Bearer
|
|
|
|
|
challenge/proof/verify commands exist for resource-scoped possession checks.
|
2026-05-19 19:16:30 +02:00
|
|
|
Remote module authorization paths can accept optional bearer proofs without
|
2026-05-20 13:10:34 +02:00
|
|
|
enrolling the caller as a trusted node. Bearer creation separates the public
|
|
|
|
|
bearer id stored in auth logs from the private bearer token returned to the
|
|
|
|
|
caller once. Payload encryption and key envelopes are still roadmap work.
|
2026-05-18 11:51:12 +02:00
|
|
|
- SSH revocations can be exported as JSONL, OpenSSH KRL specification text, or
|
2026-05-18 11:56:42 +02:00
|
|
|
binary OpenSSH KRL files generated through `ssh-keygen`. JSONL and OpenSSH KRL
|
|
|
|
|
specification imports are supported; binary KRL import is unsupported because
|
2026-05-18 11:58:39 +02:00
|
|
|
OpenSSH KRL files are not enumerable through OpenSSH tooling. Tests cover
|
|
|
|
|
public-key and certificate binary KRL revocations when `ssh-keygen` is
|
2026-05-19 15:56:47 +02:00
|
|
|
available. `geth ssh cert approve` emits the OpenSSH signing command by
|
|
|
|
|
default; `approve --sign` runs `ssh-keygen`, imports the resulting
|
|
|
|
|
certificate, and marks the request signed when local signing succeeds. Local
|
|
|
|
|
SSH certificate and revocation commands accept optional
|
2026-05-19 15:44:13 +02:00
|
|
|
`--subject` principals and enforce `ssh_cert.*` capabilities on
|
|
|
|
|
`resource:ssh:certs` plus `ssh_revocation.*` capabilities on
|
|
|
|
|
`resource:ssh:revocations` for non-owner subjects. Authorized peers can pull
|
|
|
|
|
SSH certificate-flow metadata with `ssh_cert.sync` on `resource:ssh:certs` and
|
|
|
|
|
revocation metadata with `ssh_revocation.sync` on
|
|
|
|
|
`resource:ssh:revocations`. The daemon live-syncs known peers every 30
|
2026-05-20 13:13:44 +02:00
|
|
|
seconds using per-peer cursors. Conflicting records with already-known ids are
|
|
|
|
|
rejected during sync import; this is pull-only metadata sync, not yet a
|
|
|
|
|
signed CRDT/resource-log replication model.
|
2026-05-18 22:11:57 +02:00
|
|
|
- cr-sqlite apply, iroh-docs, iroh-blobs provider/fetch, Automerge sync,
|
|
|
|
|
broader auth enforcement, and Keyhive/BeeKEM-style authorization are future
|
|
|
|
|
roadmap items unless implemented later.
|