FABRIC-3.md §H: session refactor capture -- struct shape + identity/ACL cards
Design capture from today's session-refactor discussion, back to Hera: session-as-Stadium-patron struct shape (references the patron by VMUuid, pin-authoritative, identity embedded), and the identity ACL "stack of cards" model with all four named dimensions scoped so far (VM, word, block, message) plus the PubSub/topics messaging-protocol groundwork the message card depends on. Closes with a numbered gap-analysis list (§H.9) of everything still explicitly open. Capture-only, matching this document's own established discipline -- no struct written, no code changed. Mirrors §D's Tripod-vision capture in style and structure. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
f81e9c92bc
commit
1349e783aa
+181
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user