diff --git a/FABRIC-2.md b/FABRIC-2.md index 13f4ccc..f5c5546 100644 --- a/FABRIC-2.md +++ b/FABRIC-2.md @@ -4015,11 +4015,45 @@ kernel-read code) — reading/writing a real GPT partition table from `src/stark unstarted work this decision required, before `blkio_usb.c` could hand `blk_subsys_attach_device()` a correctly-offset device view.~~ -- [ ] Design the identity→block-range derivation function's exact input/output (Section V - area A open point: currently zero decisions made, not even a function signature) -- [ ] Decide what "identity" means concretely as an input — the Ed25519 public key itself, - a hash of it, something else -- [ ] Implement the derivation function +**Superseded 2026-08-25 — identity→range is first-touch allocation, not a computed hash +mapping.** The original framing (below, struck through) assumed a hash-modulo-`MAX_IDENTITIES` +formula; dropped once the actual constraint was named directly: **there is no way to know how +many identities might ever exist**, so no population size can be pre-divided into slots at all, +regardless of how the hash is computed. Resolution: no formula, no `MAX_IDENTITIES`. First time +an identity is ever seen (its drive's map is empty), claim a range starting at the SSD's +existing free-space frontier — `block_subsystem.c`'s `g.total_user_lbn`, the same monotonic +"next free LBN" every `blk_subsys_attach_device()`/`blk_subsys_add_raw_device()` call already +appends against — sized to whatever the identity needs right now (open-ended, no quota, +matching Section U item 1), and write that one-time assignment into the drive's own map +(Section U item 4). Every later visit reads the range straight out of the drive's map and +trusts it; the SSD itself never re-derives or centrally directories anything. This resolves the +unbounded-population problem (allocation is append-only against a growing frontier, never +pre-divided), keeps Section U item 4's "the SSD doesn't need to remember anything about you +until you're back" property exactly, and still satisfies "identity-derived, not +attach-order-derived" (Section U item 3) because the lookup key is the identity, not physical +insertion order. + +**Identity itself, decided the same session: a certificate signed by this project's own +(not yet created) CA root — extending Milestone 6's existing PKI design (kernel-embedded +cert validating capsules) to user identity, not a separate mechanism.** The derivation-relevant +value is the cert's *embedded Ed25519 public key* specifically, not the cert's raw bytes or +serial number — a cert can be reissued (renewed, new serial, new validity window) while the +underlying keypair stays the same, and keying off the pubkey means a renewal doesn't silently +relocate a user's already-allocated range. The kernel verifies the cert against the CA chain +(Milestone 6's own not-yet-built verification path) before trusting a drive's self-reported map +as genuinely belonging to that identity — otherwise anyone could hand-edit a drive's map and +claim someone else's already-allocated blocks. + +~~Design the identity→block-range derivation function's exact input/output (Section V area A +open point: currently zero decisions made, not even a function signature). Decide what +"identity" means concretely as an input — the Ed25519 public key itself, a hash of it, +something else. Implement the derivation function.~~ + +- [ ] Implement the CA-signed-cert verification path (Milestone 6 dependency — the cert chain + validator doesn't exist yet either) +- [ ] Implement the first-touch allocation function: given a verified identity pubkey and a + requested block count, either read an existing range from the drive's map or claim a + new one at `g.total_user_lbn` and write it back - [ ] Design the on-drive block-map format (Section U item 4) — what it records (block ranges claimed? individual block liveness? something else), how it's serialized - [ ] Implement writing the block-map to a drive