FABRIC-3.md: scope BINDSTEP -- extends the live, unguarded USE word
Traced the actual retarget path before assuming new plumbing: USE (mama_forth_words.c:430-480) already looks up a VM by name and calls sk_repl_set_active_vm() directly, completely unguarded. BINDSTEP is concretely "add the ACLKEY comparison to this one call site." Found one real gap: usb_blk_dev/xdev are function-static inside sk_repl_idle(), invisible to USE -- needs a small new accessor mirroring sk_repl_get_active_vm()'s own precedent. Decisions: re-verify the attached drive live on every USE call rather than trust a cached pubkey; VMs with no VMIdentity installed yet (Hera/Hermes/Artemis today) stay freely targetable, no regression; installed=1 targets refuse on no-drive-attached or pubkey mismatch, matching USE's existing refusal style. Zuse's override UX stays deferred per direct instruction.
This commit is contained in:
+50
-2
@@ -682,7 +682,10 @@ decisions get added here, not to `FABRIC-2.md`. Follow the same discipline `FABR
|
||||
|
||||
- [ ] Implement the actual attach/bind step — extending `sk_repl_set_active_vm()` (confirmed
|
||||
to exist, currently an unguarded raw pointer-set) with the key-match check from above, so a
|
||||
console can only bind to the one VM whose lock matches its key.
|
||||
console can only bind to the one VM whose lock matches its key. **SCOPED 2026-08-27
|
||||
(`FABRIC-3.md` §F.9)**: real gate is `USE` (`mama_forth_words.c:430-480`), the live,
|
||||
already-working, currently-unguarded retarget word — check re-verifies the attached drive
|
||||
live on every call; `installed=0` VMs stay freely targetable.
|
||||
|
||||
- [ ] Implement detach behavior on console disconnect or VM teardown.
|
||||
|
||||
@@ -1426,7 +1429,7 @@ graph TD
|
||||
|
||||
ACLKEY["❓ ACL 'bumps and holes' comparison<br/>semantics — SAME GAP in M5 and D.4"]
|
||||
WIREBIND["❌ Wire hotplug → capsule_birth_baby() (M5)"]
|
||||
BINDSTEP["❌ Extend sk_repl_set_active_vm()<br/>with key-match (M5)"]
|
||||
BINDSTEP["❌ Extend sk_repl_set_active_vm()<br/>with key-match (M5) — SCOPED 2026-08-27 (§F.9)"]
|
||||
DETACH["❌ Detach behavior (M5)"]
|
||||
|
||||
EXPIRE["✅ EXPIRE reframed: session end<br/>= VM detach via COOL (§B + D.2)"]
|
||||
@@ -1519,6 +1522,10 @@ finished). Dashed arrows = softer "gates/informs" relationships.
|
||||
(`CERTVERIFY`, `WIREBIND`, `RUNCAP`, `HOTPLUG`) was already treating raw devblock-0 as the
|
||||
working format. Dropping GPT converts all of those from "interim, revisit later" to simply
|
||||
"the design," retroactively.
|
||||
- **`BINDSTEP` already has a live target to gate, not new plumbing** (§F.9) — `USE`
|
||||
(`mama_forth_words.c`) is a real, working, currently-unguarded retarget word. The only
|
||||
genuinely new code this node needs is a small cross-file accessor for the currently-attached
|
||||
device (mirroring `sk_repl_get_active_vm()`'s own precedent) plus the comparison itself.
|
||||
|
||||
**Not yet done:** an ordered plan (which node to attack first, given the graph). Per Captain
|
||||
Bob's own framing, that's the next pass — "start asking and answering questions iteratively
|
||||
@@ -1876,6 +1883,47 @@ refuse-on-non-blank-media posture — reasonable by analogy, not decided here. T
|
||||
is unchanged and already modeled in the graph: `WRITE(10)` still doesn't exist, so `MINT`
|
||||
cannot write anything to real or QEMU-emulated USB media yet regardless of the above.
|
||||
|
||||
### F.9 — `BINDSTEP` (extending `sk_repl_set_active_vm()` with the `ACLKEY` check)
|
||||
|
||||
Traced against the live retarget path before assuming new plumbing was needed:
|
||||
`USE` (`mama_forth_words.c:430-480`) is the real, already-working console-retarget word —
|
||||
`S" name" USE` looks a VM up by name (case-insensitive) and calls `sk_repl_set_active_vm()`
|
||||
directly, completely unguarded today. `BINDSTEP` is concretely "add the `ACLKEY` (§F.2)
|
||||
comparison to this one call site," not a new mechanism.
|
||||
|
||||
**Real gap found, not just a policy question:** the "re-verify live" approach (decided below)
|
||||
needs access to whatever drive is currently attached, but `usb_blk_dev`/`xdev`
|
||||
(`repl.c:107-108`) are function-static inside `sk_repl_idle()` — invisible to `USE`, which
|
||||
lives in `mama_forth_words.c`. `BINDSTEP` needs a small new accessor exposing "the currently
|
||||
attached home-blocks device," mirroring the existing `sk_repl_get_active_vm()` precedent
|
||||
(`repl.h:67-69`) for exactly this kind of cross-file REPL-state access.
|
||||
|
||||
**Decisions made 2026-08-27 (iterative Q&A pass):**
|
||||
|
||||
1. **Check freshness: re-verify live, not cached.** Every `USE` call re-runs the
|
||||
drive-check/`CERTVERIFY` path against whatever is currently attached, rather than trusting a
|
||||
pubkey cached at original attach time. `USE` is a rare, human-triggered, interactive
|
||||
operation — the repeated DER-parse + `ed25519_verify()` cost is a non-issue, and this avoids
|
||||
any staleness question if a drive was swapped without a clean detach.
|
||||
2. **VMs with no `VMIdentity` installed yet (`installed=0`) — Hera/Hermes/Artemis today, until
|
||||
`D.5`'s per-VM-identity work lands — stay freely targetable, no check applied.** Preserves
|
||||
`USE`'s current working behavior exactly; refusing on `installed=0` would be a real
|
||||
regression today for VMs that were never in scope for this lock in the first place.
|
||||
3. **For an `installed=1` target:** `BINDSTEP` refuses (matching `USE`'s existing clean
|
||||
early-refusal style for not-found/dead-VM cases) whenever either no drive is currently
|
||||
attached, or the freshly re-verified cert's owner pubkey doesn't match the target's
|
||||
`VMIdentity.owner_pubkey`. No drive attached is a plain refusal, not a special case — it
|
||||
simply means "no identity presented," which can never match.
|
||||
4. **Zuse's override UX: deferred**, per direct instruction — this pass confirms the
|
||||
architectural constraint from `F.2` still stands (a distinct, explicit call path, not a
|
||||
branch folded into `USE`'s own logic) without committing to the exact word/interaction yet.
|
||||
|
||||
**Not yet scoped (deferred within this node):** the new accessor's exact name/signature; the
|
||||
refusal message text (matching `USE`'s existing console-message style); whether a refused
|
||||
`BINDSTEP` attempt should produce an audit-log record (this codebase has a real precedent for
|
||||
this — `capsule_parity_log_birth_failed()` and friends, `parity.c` — but nothing says a
|
||||
security-relevant refusal here needs the same treatment; not decided).
|
||||
|
||||
### D.5 — Scope expansion (2026-08-27): identity is common to every VM, not just users
|
||||
|
||||
Surfaced while scoping `ACLKEY`, stated directly: *"the whole object is to deliver a
|
||||
|
||||
Reference in New Issue
Block a user