Skip to main content

Module session_domain

Module session_domain 

Source
Expand description

The session_domain module: the typed session domain, projected.

The module is session_domain and not session because the registry composes builtin modules and declarative kinds into one namespace, and session is already a kind — the closed episode records under .ai/repo/sessions/. The registry refuses the collision rather than letting one shadow the other, which is how this was found: twelve “module 'session' is composed twice” diagnostics, one per record. The capability ids carry the module's name; the tool names and routes are the short ones, because a tool name is a projection and not the identity.

Two capabilities, and deliberately only two.

session.machine answers the lifecycle state machine as data. It exists because the same machine is currently drawn three times — in docs/CONTINUITY.md, in lib/session.sh’s comments and in the Cockpit — and three drawings of one machine drift. The lib/session.sh drawing still had the task guard in it after ADR 0052 removed the guard from the code. The answer here is derived from crate::session::EpisodeState and crate::session::Transition and from nothing else, so a transition that is added to the type appears in every surface and a diagram that disagrees with the code becomes impossible rather than merely discouraged.

session.identity answers the six identities of this checkout, each with the canonical value this executable computes and each store’s own spelling beside it. It exists because a forensic read on 2026-09-11 found the repository recorded as an absolute .git path and as a remote URL, the worktree as an absolute path and as a digest, and the session as an episode id and as a provider’s UUID — three words over six things — and no surface anywhere said so.

There is no third episode listing here. episodes.* (the MCP connection’s episode) and lifecycle.* (session observability) are being added in the same week by two other workers, and a third projection over the same store would be this subsystem’s own favourite defect committed by the module written to stop it. What this module adds is the domain those projections should eventually read from; ADR 0047 records that repointing as a step of the cutover, not of this change.

use majordomus_cli::capability::builtin::session_domain;

let module = session_domain::module();
let ids: Vec<&str> = module.capabilities.iter().map(|e| e.capability.id.as_str()).collect();
assert_eq!(ids, ["session_domain.machine", "session_domain.identity"]);
// every one of them reads: the domain's write path reaches no surface (ADR 0047)
assert!(module.capabilities.iter().all(|e| e.capability.kind.is_read_only()));

Structs§

IdentityReport
The identities of this checkout: one facet per subject, with a standing note about what a reader must not do with them.
MachineReport
The lifecycle machine, with the decision it implements, so that a reader meeting it in a projection can go and read why it is shaped this way.

Constants§

IDENTITY_URI
The URI under which session.identity is read as an MCP resource.
MACHINE_URI
The URI under which session.machine is read as an MCP resource.

Functions§

module
The module: two read-only capabilities over the typed session domain, declared once and projected to MCP and HTTP from that declaration alone.