Summary
Following up on the recent Slack discussion: a small proposal to let ant node status report a node's basic live health on demand — is it connected, how many peers, how many records stored — so an autonomous agent (and any operator) can ask "how is this node doing right now?" without parsing logs.
This is deliberately not a metrics / logging / dashboard system. Just surfacing numbers the node already computes. (There's also a higher-value follow-up — records the node is actually responsible for — covered under Phase 2 below.)
Motivation
We're building an agent-facing skill for operating Autonomi nodes. To tend nodes well — and to be a good network citizen — an agent needs to know whether a node is healthy: connected, not isolated, storing data. Today the CLI and daemon expose only process state (running / pid / uptime). The live health signals exist in the libraries (saorsa-core P2PNode, ant-node storage) but aren't surfaced through the CLI, so the only route today is parsing node logs — brittle and heavy for an agent to rely on.
From the chat, this looks like an unfinished gap from the rewrite rather than a deliberate decision (no ADR covers it; the older Prometheus/dashboard path was dropped in the saorsa-core rewrite). Raising it here to confirm that's right and to check whether a small contribution would be welcome.
Proposed scope (v1 — three readouts)
- connectivity —
P2PNode::is_bootstrapped() (bool)
- peer count —
P2PNode::peer_count()
- records stored —
LmdbStorage::current_chunks() (count)
Surfaced through ant node status (the existing --json form needs no new rendering). Storage bytes are already obtainable from the data dir, so the record count is the part worth surfacing.
Why it looks small (no new ports, endpoints, or deps)
The values already exist as cheap getters, and the node↔manager plumbing is already in place: the daemon spawns each node with --root-dir = data_dir, so they share a directory. A node can write a tiny status.json to its root_dir on a timer, and the daemon reads it into NodeStatusSummary — no new listener, port, or RPC. Rough touch points:
- ant-node: a
health_snapshot() over the existing getters + a periodic atomic status.json writer in RunningNode::run() (mirrors the existing upgrade-monitor background task); storage reached via AntProtocol::storage().current_chunks().
- ant-client: three optional fields on
NodeStatusSummary, a best-effort status.json read in the daemon's get_nodes_status, and None on the offline path. ant node status --json then surfaces them with no new rendering.
(We've done a file-level scope and can share it or supply the PRs if the approach is welcome — see Offer below.)
Design questions for the team (the main reason for this issue)
Before any code, we'd value your steer on:
- Exposure mechanism — is a node-written
status.json the approach you'd want, or would you prefer reviving --metrics-port as a minimal status endpoint, or something else? (We lean toward status.json: smallest surface, no new port.)
- "peer count" semantics — active connected peers (
peer_count()) vs DHT routing-table size (get_routing_table_size())? For an "am I isolated?" signal we lean active peers, clearly labelled.
- Freshness — a periodic file is "last write," so ~5–10s old at most; is that acceptable with a staleness check, or do you need exact-instant reads (which would push toward an endpoint instead)?
Phase 2 (also valuable) — relevant / in-range records
Arguably the most useful signal of all: how many of the stored records this node is actually responsible for (within its close-group range) — i.e. is it holding its slice of the keyspace well, not just a raw count. We'd like to add this too.
Honest caveat: unlike the three above, this one has no in-process aggregate today — it needs each stored key compared against the node's live responsibility range (DHT / close-group math), so it's genuinely new work, not just surfacing existing getters. It's cleanly separable from v1: the status.json schema can gain an optional records_in_range field later without disturbing it.
Question: would you want this, and where would you prefer the counter to live — maintained incrementally by the replication engine (which already tracks close-group membership), or a cached scan in the storage layer?
Offer
This clearly isn't a priority on your side, and we don't want to pull focus from the network-use work. But it's a small, decoupled win for every operator and agent — so if it's welcome and you're happy with the approach, we can do the build and raise the PRs (ant-node + ant-client) for your review — starting with the v1 three, and the Phase 2 in-range counter as a follow-up if you want it. We just wanted your nod on direction first.
Summary
Following up on the recent Slack discussion: a small proposal to let
ant node statusreport a node's basic live health on demand — is it connected, how many peers, how many records stored — so an autonomous agent (and any operator) can ask "how is this node doing right now?" without parsing logs.This is deliberately not a metrics / logging / dashboard system. Just surfacing numbers the node already computes. (There's also a higher-value follow-up — records the node is actually responsible for — covered under Phase 2 below.)
Motivation
We're building an agent-facing skill for operating Autonomi nodes. To tend nodes well — and to be a good network citizen — an agent needs to know whether a node is healthy: connected, not isolated, storing data. Today the CLI and daemon expose only process state (running / pid / uptime). The live health signals exist in the libraries (saorsa-core
P2PNode, ant-node storage) but aren't surfaced through the CLI, so the only route today is parsing node logs — brittle and heavy for an agent to rely on.From the chat, this looks like an unfinished gap from the rewrite rather than a deliberate decision (no ADR covers it; the older Prometheus/dashboard path was dropped in the saorsa-core rewrite). Raising it here to confirm that's right and to check whether a small contribution would be welcome.
Proposed scope (v1 — three readouts)
P2PNode::is_bootstrapped()(bool)P2PNode::peer_count()LmdbStorage::current_chunks()(count)Surfaced through
ant node status(the existing--jsonform needs no new rendering). Storage bytes are already obtainable from the data dir, so the record count is the part worth surfacing.Why it looks small (no new ports, endpoints, or deps)
The values already exist as cheap getters, and the node↔manager plumbing is already in place: the daemon spawns each node with
--root-dir = data_dir, so they share a directory. A node can write a tinystatus.jsonto itsroot_diron a timer, and the daemon reads it intoNodeStatusSummary— no new listener, port, or RPC. Rough touch points:health_snapshot()over the existing getters + a periodic atomicstatus.jsonwriter inRunningNode::run()(mirrors the existing upgrade-monitor background task); storage reached viaAntProtocol::storage().current_chunks().NodeStatusSummary, a best-effortstatus.jsonread in the daemon'sget_nodes_status, andNoneon the offline path.ant node status --jsonthen surfaces them with no new rendering.(We've done a file-level scope and can share it or supply the PRs if the approach is welcome — see Offer below.)
Design questions for the team (the main reason for this issue)
Before any code, we'd value your steer on:
status.jsonthe approach you'd want, or would you prefer reviving--metrics-portas a minimal status endpoint, or something else? (We lean towardstatus.json: smallest surface, no new port.)peer_count()) vs DHT routing-table size (get_routing_table_size())? For an "am I isolated?" signal we lean active peers, clearly labelled.Phase 2 (also valuable) — relevant / in-range records
Arguably the most useful signal of all: how many of the stored records this node is actually responsible for (within its close-group range) — i.e. is it holding its slice of the keyspace well, not just a raw count. We'd like to add this too.
Honest caveat: unlike the three above, this one has no in-process aggregate today — it needs each stored key compared against the node's live responsibility range (DHT / close-group math), so it's genuinely new work, not just surfacing existing getters. It's cleanly separable from v1: the
status.jsonschema can gain an optionalrecords_in_rangefield later without disturbing it.Question: would you want this, and where would you prefer the counter to live — maintained incrementally by the replication engine (which already tracks close-group membership), or a cached scan in the storage layer?
Offer
This clearly isn't a priority on your side, and we don't want to pull focus from the network-use work. But it's a small, decoupled win for every operator and agent — so if it's welcome and you're happy with the approach, we can do the build and raise the PRs (ant-node + ant-client) for your review — starting with the v1 three, and the Phase 2 in-range counter as a follow-up if you want it. We just wanted your nod on direction first.