Name no controller verb in hints and drop its handover and paging reads, since the controller ended (issue 1126 B19)

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
2026-11-02 11:23:14 +01:00
parent 49f9269376
commit 4f636b7080
36 changed files with 171 additions and 416 deletions
+6 -6
View File
@@ -433,7 +433,7 @@ export async function connectNats(
/**
* React to events.
*
* The durable consumer is the **controller's** to create, from what this module declared it
* The durable consumer is the **mesh's** to create, from what this module declared it
* consumes (design 29 §3) — this binds to it and never creates one. A runtime that created
* its own would be a module deciding its own delivery semantics, and its account cannot
* reach the JetStream API to do it anyway.
@@ -499,14 +499,14 @@ async function deliver(
env = toEnvelope<unknown>(msg);
} catch {
// Unparseable: terminate it. Redelivering a message no version of this code can read is
// an infinite loop, and what the controller keeps of a message given up on (DEAD_LETTERS,
// an infinite loop, and what the mesh keeps of a message given up on (DEAD_LETTERS,
// novox/hq issue 330) is for handlers that fail, not for bytes that were never an envelope.
msg.term();
return;
}
const forThis = listeners.filter((l) => topicMatches(l.pattern, env.key));
if (forThis.length === 0) {
// The consumer's filters are the controller's, derived from what the module declared it
// The consumer's filters are the mesh's, derived from what the module declared it
// consumes, and may be wider than anything it registered a handler for. Acknowledge it, or it
// would be redelivered until it expired.
msg.ack();
@@ -518,10 +518,10 @@ async function deliver(
} catch {
// Negative-acknowledge with a delay, so a handler failing on a transient cause gets another
// attempt, and one failing permanently exhausts max-deliver rather than spinning: the consumer
// gives the event up, and the controller keeps it in DEAD_LETTERS until a person delivers it
// gives the event up, and the mesh keeps it in DEAD_LETTERS until a person delivers it
// again or drops it (novox/hq issue 330). Delivered again, it arrives under
// `mesh.again.<consumer>.…`, and keyFromSubject reads the same key from it. The consumer's
// limits are the controller's; this only says "not done".
// limits are the mesh's; this only says "not done".
msg.nak(5_000);
}
}
@@ -592,7 +592,7 @@ function toolSubject(key: string, self: string): string {
}
/** A seat's verb, as its holder serves it: flat for a mesh seat, carrying the machine for a
* node-scoped one (design 33 §4) — the same shape the controller grants. */
* node-scoped one (design 33 §4) — the same shape the mesh grants. */
export function seatToolSubject(seat: string, verb: string, scope: string | undefined, node: string | undefined): string {
const base = `mesh.seat.${seat}.tool.${verb}`;
return scope === "node" && node ? `${base}.${node}` : base;
+1 -1
View File
@@ -28,7 +28,7 @@ const CATALOGUE_MODULES = "mesh-catalog.catalog_modules";
/** Where every role's tools are answered: the console on this machine, the Go runtime, which holds mesh-sdk's seat
* definitions and reads who holds each seat from placement (novox/hq ADR 0571 clauses 4 and 5). Asked over the loopback
* channel `mesh --console` already uses, by the method `mesh/seats` beside MCP's; never the controller. */
* channel `mesh --console` already uses, by the method `mesh/seats` beside MCP's; never another record. */
export const SEATS_METHOD = "mesh/seats";
const DEFAULT_CONSOLE = "http://127.0.0.1:4270";
+1 -1
View File
@@ -97,7 +97,7 @@ export function mcpSurface(bus: Broker, who: string): Surface {
`that serves it; what may be called was fixed when this account was issued, so a ` +
`refusal means the account, not the tool. The list is what the running modules ` +
`answered, plus every role's tools from the mesh's records — the mesh's own verbs ` +
`(mesh-controller.status, .push, .assign …) among them; a module that did not answer ` +
`(mesh-delivery.deliveries, mesh-placement.propose …) among them; a module that did not answer ` +
`is named in the list's _meta and can still be called by <module>.<tool>.`,
});