diff --git a/03-DESIGN/00-as-is/13-the-console.md b/03-DESIGN/00-as-is/13-the-console.md new file mode 100644 index 0000000..2895b20 --- /dev/null +++ b/03-DESIGN/00-as-is/13-the-console.md @@ -0,0 +1,59 @@ +--- +layer: as-is +status: implemented +code: [mesh-catalog modules/mesh-console, mesh-tools src/mesh.ts, mesh-tools src/http.ts, mesh-tools src/runtime.ts, mesh-controller internal/broker, mesh-controller cmd/mesh-controller/check.go] +updated: 2026-09-30 +decisions: + - 02-DECISIONS/0152-the-operators-surface-is-a-module-the-console.md + - 02-DECISIONS/0095-the-control-plane-is-the-way-to-ask-a-module.md + - 02-DECISIONS/0037-where-a-module-lives.md +--- + +# The console, as it runs + +**The mesh's tools reach a person through a module the mesh assigned to their machine.** Since +2026-09-30 a workstation that is a node can be assigned `mesh-console`; the mesh mints a bus account +`.mesh-console`, seals its credential to the machine, and the container binds +`127.0.0.1:` with the port the mesh assigned for the manifest's declared one. An agent on the +machine is pointed at `http://127.0.0.1:/mcp` and sees the mesh's tools; a person uses the same +endpoint. Nothing on the machine holds a credential a person had to carry. + +## What it answers + +`initialize`, `tools/list`, `tools/call`, over HTTP, one JSON body per request, no session and no event +stream. `tools/list` is what the running modules answered: every tool runtime built on or after that day +serves a `tools` verb for its module, and the console asks the catalogue for the roster and each module +for its tools. A module that did not answer is named in the list's `_meta.notAnswering`. On the day it +shipped that was 36 of 51 modules — those that serve no tools at all, and those whose rebuilt runtime the +mesh records rather than rolls out — and 62 tools from the rest. + +`tools/call` reaches any tool by `.`, listed or not. The console's grant is `*`, so what it +may call is every tool on the mesh; its account may publish nothing else and subscribes nothing. + +## What it does not answer + +The mesh's own verbs. `status`, `push`, `assign` and the rest are not served on the bus — they are the +`mesh-controller` seat's tools under ADR 0132, whose three prerequisites are not built — so a person +still opens a shell on the control node for them. The console's handshake says so. + +## Around it + +- **`invokes`** in a manifest is the grant. It is composed into the bus's user list exactly as a + person's account is; the console is the only module that declares it. +- **`module check …`** on the controller's binary judges a manifest with no mesh: the strict + parse, every per-manifest problem, and the rules between the manifests given. It prints what it cannot + judge without a store rather than refusing. The console's own manifest was the first thing checked + with it, and the whole catalogue passes. +- **The person's client remains.** `operator issue` and `mesh tools|call|mcp` with a credential file + still work, for a machine that is not a node and for a mesh not yet able to assign anything. + `mesh tools --console ` goes through a running console with no credential; it is covered by the + runtime repository's tests and was not exercised on the live mesh. + +## What shipped bent + +- A module registered by hand from the catalogue with `--source --path modules/` records a URL, + not a place on the git seat: `--self` takes the forge path form (`/`), which the + operator did not pass. The rebuild-on-merge matched the URL anyway. +- Modules whose upgrade policy is *record* — the forge among them — answered `tools` only once + something pushed their rebuilt runtime; until then they are listed as not answering while still + callable. That is the policy doing what it says, not a fault of the console. diff --git a/03-DESIGN/00-as-is/README.md b/03-DESIGN/00-as-is/README.md index 041652a..dd766fd 100644 --- a/03-DESIGN/00-as-is/README.md +++ b/03-DESIGN/00-as-is/README.md @@ -21,6 +21,7 @@ Where the two disagree, the implementation wins and the disagreement is stated. | [`10-module-catalogue.md`](10-module-catalogue.md) | The catalogue's shape, and what its shape says | | [`11-the-lab.md`](11-the-lab.md) | The lab — the first piece of the new shape that exists, and what it does not yet do | | [`12-the-seats.md`](12-the-seats.md) | The seats the mesh defines, who holds one, and where a seat changes resolution | +| [`13-the-console.md`](13-the-console.md) | The mesh's tools on the machine a person sits at, served by a module the mesh assigned there | ## What these documents are not diff --git a/03-DESIGN/01-to-be/34-the-console.md b/03-DESIGN/01-to-be/34-the-console.md index 653e477..e6e08d1 100644 --- a/03-DESIGN/01-to-be/34-the-console.md +++ b/03-DESIGN/01-to-be/34-the-console.md @@ -1,6 +1,6 @@ --- layer: to-be -status: in-progress +status: implemented code: [mesh-catalog, mesh-tools, mesh-controller] updated: 2026-09-30 decisions: @@ -100,6 +100,23 @@ address gets a refused connection, which is the truthful answer. | on the live mesh: the console assigned to a workstation answers `tools/list` on loopback and a call to the forge returns repositories | the exit of work-order step 3 | | the composed filter for a machine carrying the console opens no port for it | ADR 0144 | +## What shipped, 2026-09-30 + +Everything above, the same day: mesh-controller PR 164 (`invokes`, `module check`), mesh-tools PR 20 +(`mesh serve`, the `tools` verb), mesh-catalog PR 181 (`mesh-console`). Verified on the live mesh: the +console assigned to a workstation answered `tools/list` on its loopback with 62 tools from the modules +whose runtimes had been rebuilt to answer `tools`, named 36 modules as not answering (modules that serve +no tools, and modules whose new runtime the mesh records rather than rolls out), and a `tools/call` of +the forge's `gitea_list_repos` returned repositories. An agent on that machine reaches it as an HTTP +MCP server and reports it connected. The mesh assigned the declared port unchanged, which is what a +machine with nothing else on it does; the console binds whatever it is given. + +Two things shipped bent, both stated in [`00-as-is/13-the-console.md`](../00-as-is/13-the-console.md): +the person's client through the console (`--console`) exists and was exercised in the test suite, not +on the live mesh; and a module registered from the catalogue by hand recorded its source as a URL rather +than as a path on the git seat, because `--self` takes the forge path form — the rebuild-on-merge still +matched it by URL. + ## What this does not settle - Narrowing a console's grant per assignment. ADR 0046 makes it a setting; nothing reads one yet. diff --git a/04-ISSUES/147-the-operators-tools-still-dial-the-bus-that-was-removed/00-report.md b/04-ISSUES/147-the-operators-tools-still-dial-the-bus-that-was-removed/00-report.md index 71479ed..20b7c20 100644 --- a/04-ISSUES/147-the-operators-tools-still-dial-the-bus-that-was-removed/00-report.md +++ b/04-ISSUES/147-the-operators-tools-still-dial-the-bus-that-was-removed/00-report.md @@ -93,3 +93,10 @@ yet; for those a shell is still the way, and design 33 is where that closes. The predecessor's program on the workstation is not replaced by the mesh; it is left where it is and the assistant is pointed at the console beside it. The `hal` entry in the assistant's configuration still names things that are not the mesh's. + +**Verified live, 2026-09-30 evening.** The four pull requests merged; the console was registered +(checked first with `module check`), built, assigned to a workstation, issued a bus account, and pushed. +On that machine `tools/list` answered on loopback with 62 tools and named 36 modules as not answering, +and a call to the forge's `gitea_list_repos` returned repositories. The assistant on that machine now +lists the console as a connected MCP server beside the predecessor's program, which was left where it +is. As-is: [`13-the-console.md`](../../03-DESIGN/00-as-is/13-the-console.md).