Metadata-Version: 2.4
Name: fleetmesh-node
Version: 0.4.0
Summary: meshnode: the first fleetmesh node, built on the fleetmesh-core reference
License: CC0-1.0
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fleetmesh-core>=0.4.0
Requires-Dist: fleetmesh-protocols>=0.1.0
Requires-Dist: cryptography>=41.0.0
Provides-Extra: wasm
Requires-Dist: wasmtime==49.0.0; extra == "wasm"
Provides-Extra: postgres
Requires-Dist: psycopg[binary]==3.3.6; extra == "postgres"
Provides-Extra: p2p
Requires-Dist: libp2p==0.8.0; extra == "p2p"
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == "dev"
Requires-Dist: pyflakes>=3.2; extra == "dev"
Dynamic: license-file

# meshnode

`meshnode` is the sovereign node runtime and peer daemon for **Fleetmesh** ([fleetmesh.org](https://www.fleetmesh.org)).

It runs headless on a VPS, bare metal server, edge gateway, Raspberry Pi, laptop, or embedded device.

## Core Compartments & Subsystems

- **Autonomous Wire Transports**: Multi-rung transport ladder across FIPS-140-3 native datagrams (Rank 5), Iroh QUIC (Rank 10), Rhio NATS JetStream (Rank 12), p2panda operation logs (Rank 15), libp2p (Rank 20), and Nostr WebSocket gift-wrap fallbacks (Rank 30).
- **Pluggable Multi-Protocol Runtime (`node/protocols/`)**: Modular protocol packages (`nostr`, `atproto`, `activitypub`, `ssb`, `p2panda`, `rhio`) multiplexed over `ProtocolHost` with zero overhead when disabled.
- **Signed Bilateral Accounting**: Token-bucket rate limiting, signed consumption receipts, and automated AIMD strain recovery.
- **Verifiable Execution Engines**: Multi-runtime execution fabric: deterministic WASM/WASI, Groth16 & zkVM (RISC Zero/SP1) verifiers, Bacalhau compute-over-data, streaming AI/LLM inference, ReAct agents, and NIP-90 DVM gateway.
- **Storage Fabric**: Dual-engine SQLite WAL and PostgreSQL dialects, Blossom / CAR v1 / MST content-addressed stores, and Negentropy set reconciliation.
- **Control Socket IPC**: High-speed Unix domain socket (`meshnode-control/1`) consumed by `meshctl` for live, non-destructive hot-reconciliation.

## Running Locally

```sh
# Initialize a new node
./bin/meshnode init /var/lib/fleetmesh

# Start the node runtime
./bin/meshnode run /var/lib/fleetmesh

# Check daemon health and compartments
./bin/meshnode health /var/lib/fleetmesh
```

## Running in a fleet

A node runs fine with no operator: `meshnode init <dir>` without `--operator`
publishes a kind 11801 descriptor with no `operator` tag. An operator's fleet is
the set of nodes whose descriptor names that operator, and a node gets there by
enrolling with a `fleet/enrol` token minted for its key alone (see
[fleetmesh.org/networks.html](https://fleetmesh.org/networks.html)):

```sh
# on the node: DID, npub, pubkey and current operator (if any)
./bin/meshnode whoami /var/lib/fleetmesh

# operator, off the node: meshctl fleet token <that pubkey> --key-file operator.key

# running node: meshctl enrol fmenrol1... --dir /var/lib/fleetmesh
# stopped node: the same verification, written straight to config.json
./bin/meshnode enrol /var/lib/fleetmesh fmenrol1...
./bin/meshnode enrol /var/lib/fleetmesh fmenrol1... --force   # move to another operator
```

Enrolling under the operator the node already has changes nothing. A different
operator is refused `already_enrolled` unless `--force` is given. A token for
another node's key is refused `audience_mismatch`; the other codes
(`token_malformed`, `token_legacy`, `bad_signature`, `grant_expired`,
`grant_not_yet_valid`, `grant_revoked`, `capability_missing`,
`operator_unsupported`) come from `fleetmesh_core.network.enrol_token`.

The result lives in `config.json`: `operator` is the operator's 64-hex pubkey
(what the descriptor tag is built from), and `enrolment` is
`{"operator": <DID as written in the token>, "token_id": <grant id>, "at": <unix>, "exp": <token exp>}`.
Whether a node should leave the fleet when `enrolment.exp` passes is undecided;
today it is recorded and not looked at again.

## Private networks

Kind 30830 definitions are followed from the `network` block of `config.json`:

```json
"network": {
  "networks": ["<creator pubkey hex>:<slug>"],
  "relays": ["wss://relay.example"],
  "poll_seconds": 300
}
```

`meshctl network join` writes that block; the node re-reads it on its tick. The
roster the node derives is exported to `face.roster_export_path` (when set) as
`{"<network id>": ["<pubkey hex>", ...]}` for a roster-protected relay.

Three control-socket commands expose the state; they are reachable only over
the socket (`meshctl network show` and `join` call the first two):

- `network.show`: the networks followed, the current definition and roster of
  each, and the ones with no definition yet.
- `network.poll`: fetch definitions from the relays now instead of waiting.
- `network.decide`: what this node would answer a sender asking to join a
  network under its policy. Nothing in the node calls it on its own yet.

Grant revocation lists (kind 30833) are held in memory (`revocation_lists`),
start empty, and are fed by nothing yet: no config key seeds them and no relay
subscription delivers them. The node enforces only lists it is handed.

## Contributing

`CONTRIBUTING.md` says how changes land (the tripwires, pure moves, one
workstream per commit series); `SECURITY.md` says where to report a
vulnerability privately and what is and is not a security boundary.

## Licence

[CC0 1.0 Universal](LICENSE)
