diff --git a/.kiro/specs/controller-status/design.md b/.kiro/specs/controller-status/design.md index fd2078ec..47f86644 100644 --- a/.kiro/specs/controller-status/design.md +++ b/.kiro/specs/controller-status/design.md @@ -435,7 +435,7 @@ User enhancement request: `ctrlstatus`'s "Controllers (N):" list should addition 1. Confirm the exact field path from `cluster_t` to its `replicator_t` (repl.h's own comment says only "embedded in persist_t or cluster_t (P2-4)", ambiguous at design time — likely `c->persist.repl` given `replicator_t.ce` couples it to the commit engine which lives off `persist_t`, but confirm against the current struct definition, not this note, before wiring the read). ### Constraints checked -- **Async I/O invariant (ha-async-io.md):** the new read takes `replicator_t.lock` (a `mylock_t`) briefly to scan a small, fixed-size (`MAX_STANDBYS`) in-memory array — no network I/O, no unbounded wait, identical in shape to the already-established `repl_active_standby_count`'s own lock-and-scan. `ctrlstatus_fill` runs on the request-handling path (not the trigger-only delaymgr thread), so a short, bounded lock acquisition here is consistent with the rest of this handler's existing reads (e.g. the primary-identity read already takes `ha->lock` in the original Req 1-9 design). +- **Async I/O invariant (ha-async-io.md):** the new read takes `replicator_t.lock` (a `mylock_t`) briefly to scan a small, fixed-size (`MAX_STANDBYS`) in-memory array — no network I/O, no unbounded wait, identical in shape to the already-established `repl_active_standby_count`'s own lock-and-scan. **Correction (second design-review pass, 2026-09-16):** the previous version of this note claimed "the primary-identity read already takes `ha->lock`" — that was true only of the ORIGINAL Req 1-9 design text, not the as-built code: after the `ade0081` fix (Req 5.1, primaryName made role-derived/self-only), `ctrlstatus_fill`'s current source takes NO lock anywhere — every existing field is an atomic load or a plain config read. This delta's `replicator_t.lock` acquisition is therefore the FIRST lock this function has taken since that fix, not a repeat of an existing pattern within `ctrlstatus_fill` itself. It is still safe: `ctrlstatus_fill` runs on the request-handling path (not the trigger-only delaymgr thread), and the exact same lock is already taken from `repl_active_standby_count` on the write-admission quorum path — a comparably latency-sensitive context — with no documented contention issue. - **Persistence / save-restore completeness:** not applicable — `CtrlPeer.status` is derived entirely from existing in-memory connection state (`replicator_t.standbys[]`, already not persisted) and existing config (`peers_cfg`); nothing new is written to disk, WAL, or any snapshot format, and there is no save/restore path for this delta to audit. ### Schema delta (Cap'n Proto)