node-engine: the verbs seat-list and seat-list-again (the operator and the healers) and the state findings, with fixtures (ADR 0636 §1, §7; issue 1966)

This commit is contained in:
2026-11-05 14:34:07 +01:00
parent af804f5abf
commit f4a69e85f2
6 changed files with 629 additions and 1 deletions
+119
View File
@@ -16,6 +16,8 @@ export const verbs = {
compose: "compose",
composeCandidate: "compose-candidate",
manifestReads: "manifest-reads",
seatList: "seat-list",
seatListAgain: "seat-list-again",
} as const;
export const events = {
@@ -49,6 +51,7 @@ export const states = {
data: "data",
packages: "packages",
health: "health",
findings: "findings",
} as const;
/** The key of one value of the state have under the form "<node>.<module>". */
@@ -158,6 +161,21 @@ export function parseHealthByNodeKey(key: string): { node: string } | undefined
return { node };
}
/** The key of one value of the state findings under the form "<key>". */
export function findingsByKeyKey(key: string): string {
return key;
}
/** The parts of a key of the form "<key>", or undefined for a key of another form. */
export function parseFindingsByKeyKey(key: string): { key: string } | undefined {
let rest = key;
if (rest === "") return undefined;
const key = rest;
rest = "";
if (rest !== "") return undefined;
return { key };
}
/** one act asked through the seat, as acts reads it (ADR 0563 §9) */
export interface Act {
/** the act: hand-over, access-act, judge-directories or setuid-search */
@@ -234,6 +252,34 @@ export interface Asked {
"says": string;
}
/** one answer the operator may give from a notification */
export interface FindingAction {
"arguments"?: Record<string, string>;
"label": string;
"level"?: "acknowledge" | "approve";
"machine"?: string;
/** the seat verb the operator channel calls */
"verb": string;
}
/** one observation, as it was said */
export interface FindingEvidence {
"at": string;
"said": string;
}
/** what the condition is about */
export interface FindingSubject {
/** the other machines it concerns */
"also"?: string[];
/** its id within the scope */
"id": string;
/** the machine it concerns, when there is one */
"machine"?: string;
/** machine, plan, call, build, merge, provider, seat, bus, core, probe, mesh, delivery or module */
"scope": string;
}
/** what a node-engine says when what it reads changed or its node returned (ADR 0618 §4) */
export interface ManifestReadsChanged {
/** when it says it, RFC 3339 */
@@ -300,6 +346,34 @@ export interface Said {
"said": string;
}
export interface SeatListStatus {
/** the seat mesh-catalog has answered */
"heard": boolean;
"held": SeatListHeld[];
"last-error"?: string;
/** a trunk definition that does not parse, by seat: the one held stands */
"refused"?: Record<string, string>;
"revision"?: number;
/** the seats held from the bootstrap alone */
"waiting"?: string[];
}
/** what an engine holds of the seat list (novox/hq ADR 0636 §7) */
export interface SeatList {
/** why the read failed, for seat-list-again */
"error"?: string;
/** the one line the engine says of it; empty when nothing waits */
"health": string;
"status": SeatListStatus;
}
export interface SeatListHeld {
/** the digest of the definition held; empty for a bootstrapped one */
"digest"?: string;
"seat": string;
"source": "trunk" | "bootstrap";
}
/** is what hand-over takes. */
export interface HandOverInput {
/** the directory's absolute path, as the engine states it */
@@ -608,6 +682,20 @@ export interface ManifestReadsAnswer {
"v": number;
}
/** is what seat-list takes. */
export interface SeatListInput {
}
/** is what seat-list answers. */
export type SeatListAnswer = SeatList;
/** is what seat-list-again takes. */
export interface SeatListAgainInput {
}
/** is what seat-list-again answers. */
export type SeatListAgainAnswer = SeatList;
/** is the body of the event asked. */
export type AskedEvent = ActSaid;
@@ -720,3 +808,34 @@ export interface HealthByNodeValue {
"v": number;
}
/** is one value of the state findings under the key <key>. */
export interface FindingsByKeyValue {
"actions"?: FindingAction[];
"at": string;
/** newest first, at most 10 */
"evidence"?: FindingEvidence[];
"explanation"?: string;
"headline"?: string;
/** scope.id.token */
"key": string;
"kind": string;
"needs"?: string;
/** the module that wrote it */
"observer": string;
/** the key's last part when it is not the kind */
"ref"?: string;
"resolved"?: string;
/** self, operator, agent or healer:<name> */
"resolver"?: string;
/** what of its own saw it last */
"run"?: string;
"severity": "urgent" | "warning";
/** the row, probe or event that saw it */
"source": string;
"subject": FindingSubject;
/** one line */
"summary": string;
/** layout version, 1 */
"v": number;
}