diff --git a/FABRIC-3.md b/FABRIC-3.md index e3d171f..1d39510 100644 --- a/FABRIC-3.md +++ b/FABRIC-3.md @@ -3527,3 +3527,184 @@ by refiling after lapse), so #1 is on a hard clock; **#2 (full StarshipOS) is th deliverable** that keeps the flagship covered — and, pending counsel confirmation, may be the conversion vehicle for #1. Authoritative form in `ROADMAP.md` "IP framing of the three products". + +--- + +## H. Session refactor, back to Hera — session struct shape + identity/ACL card model (capture, 2026-09-02) + +Captain Bob announced a major refactor reaching all the way back to Hera's own boot sequence: +formally introduce **session** as a first-class concept at the root of the system, rather than +bolted on later. This sharpens and extends D.2's 2026-08-27 correction ("a session is any VM +client running in the Stadium fabric... Zuse is a player like any other") into a concrete +struct shape and, from there, into a full identity/ACL model. **Capture-only pass, matching +this document's own established discipline** ("capture EVERYTHING first then we'll build a +plan," D's own intro) — nothing here is scoped into implementable items yet. + +### H.1 — Session = Stadium patron, admission restated + +- Hera defines what a session *is* (the concept/type itself). At boot, Hera registers + **herself** into her own session first. When Hera births a child VM (Hermes, then Artemis), + she also stands up a session for that child at birth time. +- **A session is a Stadium patron** — registering a session = admitting a patron to the + Stadium, not a new parallel bookkeeping structure. This is the same correction D.2 already + made ("a session IS a VM"), now traced down to the concrete admission mechanism already + live in `src/starkernel/vm/stadium.c`: `StadiumPatronHeader` (64 bytes — identity, heat, + ttl, link, contains, mass, flags [bit 0 = `STADIUM_FLAG_PIN`], behaviour, 32-byte inline + payload) and `stadium_birth_hera()`, which already admits Hera as patron zero, pinned, via + `stadium_admit(vm_uuid_hera(), &candidate)`. No `stadium_birth_hermes()`/`_artemis()` + equivalent exists yet — Hera is the only admitted patron today. +- **Pinned** sessions (Hermes, Artemis — the VMs Hera births at boot) are patrons exempt from + the normal departure path (heat decay / `COOL`): they never leave, permanently. +- Core unifying principle, in the user's own words: **"a process and a virtual machine are + going to be exactly the same thing"** inside this OS — VM identity, process identity, and + session become one concept, not three. +- **A session is a Stadium patron** *(Captain Bob, confirming): "Oh, yeah. God. This is... + this becomes a patron of the stadium, I believe, session, that is."* Pinned patrons are + exempt from the normal departure path (heat decay / `COOL`) — they never leave. +- **Open, not yet stated:** whether a *non-pinned* session (an ordinary Stadium patron subject + to `COOL`) is where a future ephemeral user VM's session would land. The pinned/patron + framing is confirmed; this specific mapping is not — don't assume it. + +### H.2 — Session struct shape + +Confirmed: **a session is a NEW structure, separate from `StadiumPatronHeader`, that +references the patron by `VMUuid`** — not the patron header itself, and not indexed by +Stadium cell index. Gets its own header file, same precedent as `VMUuid`/planned-`VMIdentity` +(never grow `struct VM` or `StadiumPatronHeader` with inline fields for this). + +Confirmed session fields so far: +- `vm_id` (`VMUuid`) — the patron this session references. +- `pinned` — **session is authoritative**; Stadium's `STADIUM_FLAG_PIN` bit follows the + session's value, not the other way around. +- `parent` (`VMUuid`) — who birthed this session (Hera → Hermes/Artemis). *Proposed by the + model, not yet explicitly confirmed word-for-word* — flag before building on it. +- `name` — canonical human-readable name (feeds `console.c`'s `g_active_vm_name` prefix, + doesn't replace the console-binding mechanism itself). *Also model-proposed, not confirmed.* +- `identity` — lives directly embedded in the session struct (confirmed). Contents: the + ACL "stack of cards" model, H.3 onward. + +**User's own framing, explicit and important**: "the floor was, who knows? We're gonna be +revisiting this part of it around and around for a while." Treat this field list as a live, +expected-to-churn working draft, not a locked shape. + +### H.3 — Identity model: ACL "stack of cards" + +Identity carries the VM's/word's ACL as a **stack of cards, each with pinholes punched through +it** — user's own framing: "a stack of cards... got pinholes going through it, and those +pinholes drop all the way down through and give the permission for whatever we're +work[ing on]... a set of graduated sieves." Confirmed accurate by the user. + +**Each card is one permission dimension**, not a redundant extra layer of the same check — +named dimensions so far: VM, word, block, message. A compound action (e.g. "execute word X, +which touches block Z and sends message M") passes through the word card, the block card, and +the message card at once — one card per relevant axis. **Confirmed: an action only consults +the cards for the dimensions it actually touches** — a pure VM-level operation only checks the +VM card, not the full stack every time. + +Whether/how the existing word-level ACL (`acl_ttl`/`acl_allow`/`acl_mode`/`acl_pinned` on +`DictEntry`, see `.claude/CLAUDE.md`'s "Word-Level ACL System") folds into or reconciles with +this new stack-of-cards model is unresolved — the word card (H.5) explicitly reuses one piece +of it (`ACL-TTL`), but the rest is open. + +### H.4 — VM card + +Narrow by design: a single base gate ("who owns / can-touch this VM at all") that other, finer +checks sit on top of. Does not itself enumerate operations (birth/kill, console attach, +retarget, quota grant, etc.) — those are finer-grained checks built elsewhere. + +- **Zuse is entirely outside the card stack**: "forget Zeus [Zuse]. Zeus will always have 100 + percent authority" — unconditional, not modeled as an always-allowed path *through* the VM + card the way the earlier `ACLKEY` pass (§F.2) had framed it. Zuse bypasses the card stack + entirely, full stop. +- **Single owner, for now**: exactly one `owner_pubkey` per VM at this gate (match or no + match), not a list of authorized identities — "single owner for now," multi-owner + explicitly deferred, not in scope. +- Matches the `VMIdentity{owner_pubkey[32], installed}` shape already decided in the earlier + `ACLKEY` pass (§F.2) — the VM card is effectively that ownership check, non-Zuse case only. + +### H.5 — Word card + +- **Default-permissive baseline**: "will have to pretty much admit any word" — not a + default-deny gate that has to explicitly enumerate everything. +- **Dynamic, not fixed**: ACLs at this card are "additive/subtractive dynamic entities" — the + permission set can grow or shrink over the session's lifetime, not a static list decided + once at creation. +- **Hard ceiling invariant**: "they can never exceed the creator's permissions" — a session's + word permissions can never exceed what its own creator/parent had. Delegation is capped by + the parent's own permission set — presumably where H.2's `parent` field earns its keep. +- **Escape hatch, mechanism confirmed reused**: the only way to temporarily exceed that + creator-ceiling is "some kind of temporary Zuse power" — **confirmed reuse of the existing, + already-built-and-measured `ACL-TTL` mechanism** (`acl_ttl` field on `DictEntry`), not a new + parallel temporary-grant mechanism. **Explicitly still undecided: the trigger/path for *how* + a session actually reaches that elevated state** — only the underlying TTL mechanism itself + is settled as reused, not the invocation flow. + +### H.6 — Block card + +**Confirmed: reuses the already-decided `BMAPFMT` design** from §F.4 — distributed per-block +ownership, not a new mechanism. Repurposes the dormant, fully-wired, zero-caller `blk_meta_t` +struct: 8-byte owner-pubkey fingerprint + 1-byte fast-deny `acl_allow`, with deliberate +reserved slack in the 40-byte block ("flexibility until we understand the recipe"). No +separate centralized block-ownership table (makes `homeblocks_sig_t`'s reserved +`blockmap_offset`/`blockmap_devblocks` fields unnecessary, already flagged for cleanup). +`BMAPFMT`'s field design was done as of the §F.4 pass but **the code change was never made** — +this refactor is presumably where it finally lands. + +### H.7 — Messaging protocol groundwork (prerequisite to the message card) + +- **PubSub, decided.** Terminology is **"topics"** — not "channels." Likely reconciles with + the existing `CH` field / `CH-ALLOC` API already on record in D.4's message shape + (`MSG-CELLS` = `TYPE, FROM, TO, PADDR, PLEN, STADIUM-CELL, SEQ, CH, ORIG-TYPE`) — `CH` is + likely the topic identifier, terminology now formalized as "topic." +- **Every VM always subscribes to one well-known "common" topic** — a standing prerequisite, + not something set up per-conversation. This is the rendezvous point. +- **Handshake flow**: VM A posts a message on `common` addressed to VM B — "I would like to + commune with you." VM B, already listening on `common`, responds okay. That handshake + causes a **new private topic** to be created, which A and B then use directly instead of + `common`. +- **ACK/NACK confirmed as a general reliability mechanism**, applied to every message on any + topic (private or `common`) — not specific to the handshake step. + +### H.8 — Message card + +**Scope confirmed narrow and one-sided**: gates only "who's allowed to post on `common` +requesting a commune" — the *initiating* side of the H.7 handshake. The receiving VM's +decision to accept/ACK is **not** gated by this card. Not yet stated: whether traffic on an +established private topic (post-handshake) is gated by this card, a different mechanism, or +left ungated. + +### H.9 — Gap analysis (as of 2026-09-02) + +Explicitly open items surfaced during this capture pass, none decided yet: + +1. **Non-pinned session mapping (H.1).** Does an ephemeral user VM's session land as a + non-pinned (normal-departure, `COOL`-subject) Stadium patron? Framing confirmed, this + specific mapping is not. +2. **`parent` and `name` session fields (H.2).** Proposed by the model, never explicitly + confirmed by Captain Bob — the field list is stated as a live, expected-to-churn draft + ("we're gonna be revisiting this part of it around and around for a while"). +3. **Word-level ACL reconciliation (H.3).** How (or whether) the existing + `acl_ttl`/`acl_allow`/`acl_mode`/`acl_pinned` `DictEntry` fields fold into the stack-of- + cards model, beyond the one confirmed reuse (`ACL-TTL` as the word card's escape hatch, + H.5). +4. **Temporary-elevation invocation path (H.5).** The `ACL-TTL` mechanism itself is confirmed + reused; *how* a session actually reaches that elevated state (who/what invokes it, under + what condition, what Zuse has to do) is explicitly undecided. +5. **`BMAPFMT` code change (H.6).** Field design was finished in the §F.4 pass but the actual + code edit to `blk_meta_t` was never made — a real, concrete implementation gap, not just an + open question. +6. **Topic/`CH` reconciliation (H.7).** "Topic" is the newly formalized term; whether it maps + 1:1 onto the existing `CH` field in `MSG-CELLS` or needs its own representation is inferred + by the model, not explicitly confirmed. +7. **Private-topic traffic gating (H.8).** Whether messages on an established private topic + (as opposed to the initiating `common` post) are gated by the message card, some other + mechanism, or left ungated entirely. +8. **The `EXPIRE`/D.2 relationship.** D.2 already established "session ending = VM detach, + reuse `COOL`" — H.1's pinned/non-pinned framing should be read as refining that, not + replacing it, but the two have not been explicitly reconciled in one pass. +9. **Every other card beyond the four named** (VM, word, block, message) — the model list is + confirmed as the *named-so-far* set, not stated as closed/exhaustive. +10. **No implementation has started.** Every item above, and every card definition in + H.4–H.8, is design capture only — no struct has been written, no `stadium_birth_hermes()`/ + `_artemis()` exists, no `Session` header exists. Standard for this document's own + discipline (see D's intro), but worth stating plainly given the size of this section.