From 3a58d86b11a271a022e5f4fa9b396ec765a29992 Mon Sep 17 00:00:00 2001 From: Rongsong Shen Date: Sat, 20 Jun 2026 03:24:38 +0000 Subject: [PATCH] =?UTF-8?q?spec(controller-lsid):=20init=20=E2=80=94=20LSF?= =?UTF-8?q?-lsid-style=20controller=20status=20opcode=20(C=20tier)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .kiro/specs/controller-lsid/requirements.md | 31 +++++++++++++++++++++ .kiro/specs/controller-lsid/spec.json | 22 +++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 .kiro/specs/controller-lsid/requirements.md create mode 100644 .kiro/specs/controller-lsid/spec.json diff --git a/.kiro/specs/controller-lsid/requirements.md b/.kiro/specs/controller-lsid/requirements.md new file mode 100644 index 00000000..c20c43fd --- /dev/null +++ b/.kiro/specs/controller-lsid/requirements.md @@ -0,0 +1,31 @@ +# Requirements Document + +## Project Description (Input) + +Add an LSF-`lsid`-style controller status opcode (C tier only) so a client can query basic cluster/controller identity and health in one cheap call. + +**Returns:** +- Which node is the current PRIMARY (name; empty/none if mid-election) +- The responding node's role (PRIMARY/STANDBY/ELECTING/INIT) +- The configured controllers/peers (name + host:port list and count) +- The configuration version (the HA committed `config_tag`) +- Additional status: current term (election epoch), `committed_lsn`/`applied_lsn` (catch-up/health), cluster name, serving/fenced state + +Answerable by ANY node (a standby reports who the primary is from its ctrlhello/heartbeat state), so `lsid` works even when the query doesn't land on the primary; it is a failover-aware READ like the existing `clusterconf` op. All the underlying data already exists in `src/controller/ha.h` (`ha->role`, `ha->term`, `committed_config_tag`, `committed_lsn`, peer/candidate list). + +**Components (C tier):** +1. `src/schema/controller.capnp` — new `CtrlInfo`/`CtrlStatus` struct + request opcode + reply-union member, modeled on the existing `clusterconf` opcode (`controller.capnp:489`). +2. Controller `handle_ctrlinfo` handler mirroring `handle_clusterconf`. +3. libxce `xce_ctrlinfo_req` / `xce_ctrlinfo` / `xcecli_ctrlinfo` (+ free helper) as a failover-aware read. +4. `src/controller/testsuite/test.c` — a `ctrlinfo`/`lsid` client command that prints the status, AND switch `cmd_wait_primary`'s probe from `joblist_query` to this lighter, more-direct status op. (`wait-primary` currently piggybacks on `joblist` purely to avoid a new opcode; with this op it becomes a cheap "is a serving primary present + who" probe that can also report the elected primary and term — better diagnostics, directly useful for the `ha-commit-durability` Phase 6 liveness / >60s-election investigation.) + +**KEY DESIGN DECISION the spec must resolve:** whether to EXTEND the existing `clusterconf` opcode (which already returns much richer cluster detail — name/resources/queues/workers) with these HA-status fields, OR add a separate lean status op. `lsid` wants a fast focused identity/health view, not the full resource/queue/worker dump, so the leaning is a dedicated lean op, but the spec should weigh reuse vs separation explicitly. + +**IN SCOPE:** C tier only (controller opcode + libxce + `xce_test` command + `wait-primary` integration). + +**OUT OF SCOPE:** the Go CLI/REST `xce lsid` surface (a later pass); changing HA/election/replication behavior (this only READS existing HA state); structured/JSON output beyond the capnp reply. + +This is the "controller status/probe opcode" that the `xce-test-e2e-primitives` spec explicitly deferred as out-of-scope. + +## Requirements + diff --git a/.kiro/specs/controller-lsid/spec.json b/.kiro/specs/controller-lsid/spec.json new file mode 100644 index 00000000..ac8c14c5 --- /dev/null +++ b/.kiro/specs/controller-lsid/spec.json @@ -0,0 +1,22 @@ +{ + "feature_name": "controller-lsid", + "created_at": "2026-06-19T00:00:00Z", + "updated_at": "2026-06-19T00:00:00Z", + "language": "en", + "phase": "initialized", + "approvals": { + "requirements": { + "generated": false, + "approved": false + }, + "design": { + "generated": false, + "approved": false + }, + "tasks": { + "generated": false, + "approved": false + } + }, + "ready_for_implementation": false +}