Skip to content

feat(antd): live network health on /health — write_ready, peer counts, last-store age (V2-1027) - #241

Merged
Nic-dorman merged 4 commits into
mainfrom
nic/v2-1027-antd-health-write-readiness
Sep 3, 2026
Merged

feat(antd): live network health on /health — write_ready, peer counts, last-store age (V2-1027)#241
Nic-dorman merged 4 commits into
mainfrom
nic/v2-1027-antd-health-write-readiness

Conversation

@Nic-dorman

@Nic-dorman Nic-dorman commented Aug 20, 2026

Copy link
Copy Markdown
Member

Important

Gate cleared (2026-09-03). saorsa-core#153 (V2-1036) merged 2026-08-28 and is first contained in saorsa-core v0.27.3 (v0.27.2 was cut before the merge despite its later tag date); the lock now pins 0.27.3 via the ant-core ant-cli-v0.3.5 (0.8.0) bump, so the repair path heals at runtime and write_ready can recover. The peer/routing snapshot and readiness formula are delegated to ant-core's Network::health() (one source of truth); antd layers only the daemon-local last_store_ok_secs_ago. Generated-SDK health surfaces beyond the Kotlin proto copy are tracked as V2-1040.

What

Both health surfaces (REST /health, gRPC HealthService.Check) were static snapshots of startup state: a daemon with zero peers reported status:ok while every store failed (#232). They now report live network state:

  • write_ready: max(routing_table_size, connected_peers) >= threshold — best-effort write-path floor; the max() is load-bearing (client-mode routing tables under-report, see V2-1036)
  • connected_peers / routing_table_size / rebootstrap_threshold
  • last_store_ok_secs_ago: stamped on every successful store-type operation across all 7 REST + 7 gRPC write paths (null until the first success this process)

All fields are additive on both wire surfaces; status:ok semantics are untouched so existing liveness probes keep working. antd-rust models are updated in the same change (it regenerates from the shared proto and cannot lag); the other 15 SDKs are V2-1040.

Verification

  • antd 45/45, antd-rust 82/82, clippy clean
  • Verified live: peerless daemon (write_ready:false, rt 0), mainnet (write_ready:true, 5 peers), and a full devnet decay reproduction of the reporter's incident — timeline and evidence on V2-1027

Follow-ups

  • V2-1037: move the formula into ant-core; antd's network_health() becomes a pass-through and drops the mirrored const
  • V2-1040: 15-language SDK fan-out of the new fields

🤖 Generated with Claude Code

Closes #232.

…, last-store age (V2-1027)

Both health surfaces (REST /health, gRPC HealthService.Check) were
static snapshots of startup state: a daemon with zero peers reported
status:ok while every store failed (ant-sdk#232). They now report:

- write_ready: max(routing_table_size, connected_peers) >= threshold —
  best-effort write-path floor; the max() is load-bearing (client-mode
  routing tables under-report, see V2-1036)
- connected_peers / routing_table_size / rebootstrap_threshold
- last_store_ok_secs_ago, stamped on every successful store-type
  operation across all 7 REST + 7 gRPC write paths (null until the
  first success this process)

All fields additive on both wire surfaces; status:ok semantics are
untouched so existing liveness probes keep working. antd-rust models
updated in the same change (it regenerates from the shared proto and
cannot lag); the other 15 SDKs are V2-1040.

MERGE GATE: do not merge before the matching saorsa-core recovery fix
lands (WithAutonomi/saorsa-core#153 / V2-1036). Without it a degraded
client can report write_ready:false indefinitely with no runtime
remedy (the repair path could never heal), and REBOOTSTRAP_THRESHOLD
in state.rs mirrors the saorsa-core const that #153 makes public.

Verified live: peerless daemon (write_ready:false, rt 0), mainnet
(write_ready:true, 5 peers), and a full devnet decay reproduction of
the reporter's incident — timeline and evidence on V2-1027.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Nic-dorman and others added 2 commits September 2, 2026 19:16
…e re-bootstrap recovery

The merge gate for this PR: saorsa-core#153 (V2-1036) shipped in
saorsa-core 0.27.2, reaching antd through ant-protocol 2.3.4 / ant-core
0.8.0. With it in the graph, a client below the rebootstrap threshold
heals at runtime and write_ready can recover instead of sticking false.

REBOOTSTRAP_THRESHOLD stays mirrored: saorsa-core 0.27.3 marks the
upstream const pub, but its module is pub(crate) and nothing re-exports
it, so it is still unreachable for consumers.

antd: cargo test 63/63, clippy -D warnings clean against the new graph.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Nic-dorman
Nic-dorman marked this pull request as ready for review September 3, 2026 07:49

@dirvine dirvine left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for one runtime blocker found in review.

P1 — the locked dependency does not contain the recovery this PR claims to pick up. antd/Cargo.lock resolves saorsa-core to 0.27.2. The client-mode runtime re-bootstrap change from WithAutonomi/saorsa-core#153 was released in 0.27.3, not 0.27.2. Because daemon CI/builds use --locked, this head still produces an antd binary without that recovery while exposing readiness as if the corresponding runtime behaviour were present. Please update the lock to 0.27.3 and re-run the locked checks. I verified cargo update -p saorsa-core --precise 0.27.3 --dry-run resolves cleanly.

Two non-runtime contract issues should be addressed in the same pass:

  • ant-core 0.8.0 already exports Network::health(), NetworkHealth, and REBOOTSTRAP_THRESHOLD, explicitly to keep one readiness formula for antd, FFI, GUI, etc. antd/src/state.rs duplicates that implementation and constant. Delegate the peer/routing snapshot to self.client.network().health().await, then add only the daemon-local last_store_ok_secs_ago, so the advertised threshold cannot drift from the implementation.
  • The public contract rollout is incomplete: antd/openapi.yaml, llms-full.txt, and the vendored/generated health surfaces in the other SDKs still stop at payment_vault_address (the Kotlin proto copy is already inconsistent with antd/proto/antd/v1/health.proto). At minimum, update the canonical OpenAPI/reference docs and either synchronise generated clients or clearly scope a tracked compatibility follow-up. Add REST assertions for the new fields and daemon-level tests for readiness/last-store transitions; current Rust client tests cover gRPC fields but do not exercise those server transitions.

Verification at this exact head: all three GitHub checks pass; locally cargo fmt --check, cargo test --locked, and clippy with -D warnings pass for both antd and antd-rust. The additive protobuf numbering and serde defaults are wire-compatible.

Comment thread antd/Cargo.lock Outdated
[[package]]
name = "saorsa-core"
version = "0.27.0"
version = "0.27.2"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 (blocking): this locks the daemon to saorsa-core 0.27.2, but the client-mode runtime re-bootstrap recovery from WithAutonomi/saorsa-core#153 is in 0.27.3. With --locked, this PR's advertised recovery is therefore absent. Please resolve the lock to 0.27.3 and rerun locked CI.

Comment thread antd/src/state.rs Outdated
/// auto-re-bootstraps. v0.27.3 marked it `pub`, but its module is
/// `pub(crate)` and nothing re-exports it, so it remains unreachable for
/// consumers. Keep in sync until saorsa-core exports it at crate root.
pub const REBOOTSTRAP_THRESHOLD: usize = 3;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: ant-core 0.8.0 already exports REBOOTSTRAP_THRESHOLD, NetworkHealth, and Network::health() specifically as the shared implementation for antd and other embedded clients. Mirroring the constant and formula here creates two sources of truth. Please reuse self.client.network().health().await and layer only last_store_ok_secs_ago in AppState.

…core (review)

P1: the lock resolved saorsa-core 0.27.2, which does NOT contain the
runtime re-bootstrap recovery (saorsa-core#153) — v0.27.2 was cut before
the merge despite its later tag date; 0.27.3 is the first release
carrying it. With --locked builds the daemon would have advertised
recovery semantics its binary lacked. Lock now pins 0.27.3.

P2: drop antd's mirrored REBOOTSTRAP_THRESHOLD and duplicated readiness
formula; the peer/routing snapshot now comes from ant-core's
Network::health() (the shared implementation), with only the
daemon-local last_store_ok_secs_ago layered on via a StoreMarker
newtype. Daemon-level tests cover the store-marker transition, the
compose layering, and degraded -> recovered readiness.

Contract rollout: openapi.yaml HealthResponse and llms-full.txt (REST +
gRPC sections) now document all five fields; the Kotlin proto source
copy is synced with antd/proto/antd/v1/health.proto. Wider generated-SDK
fan-out stays tracked as V2-1040.

antd: cargo test 66/66, fmt + clippy -D warnings clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@dirvine dirvine left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed at f5e2a394dd0249da93b886fef1bc3853b877836c. The blocking dependency mismatch is resolved: antd/Cargo.lock now pins saorsa-core 0.27.3, and readiness delegates to ant_core::Network::health(). OpenAPI/proto surfaces and daemon transition coverage are updated; the remaining SDK fan-out is tracked separately. Local fmt, full locked tests, and clippy pass for antd and antd-rust; GitHub checks and security audit are green.

Non-blocking: a positive REST-client assertion for the five new fields would complement the existing old-daemon compatibility fixture, server JSON assertions, and gRPC coverage.

@Nic-dorman
Nic-dorman merged commit 6c635e8 into main Sep 3, 2026
3 checks passed
@Nic-dorman
Nic-dorman deleted the nic/v2-1027-antd-health-write-readiness branch September 3, 2026 13:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

antd: /health reports ok when the node has no peers and cannot write (no peer-count or write-readiness signal)

2 participants