From 8cacfb663c60ccf9434edea98662ab96d9707a58 Mon Sep 17 00:00:00 2001 From: rajames Date: Tue, 6 Oct 2026 19:04:51 -0400 Subject: [PATCH] docs(v4.0.0): storage -- ruled: a static view over a shifting chain, the kernel's mapper, private drives MESH.md section 8 is no longer a proposal. Ten rulings (Captain Bob, 2026-10-06), the design of step 6 as approved, what it leaves out, and one case left open. Step 6a is added for chains that change while running; its acceptance is still to be approved. V3-PARITY.md 1d stands: the mapper is the kernel's block subsystem. Co-Authored-By: Claude Opus 5.5 --- docs/v4.0.0/MESH.md | 166 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 151 insertions(+), 15 deletions(-) diff --git a/docs/v4.0.0/MESH.md b/docs/v4.0.0/MESH.md index f38ec5be..b10fefa1 100644 --- a/docs/v4.0.0/MESH.md +++ b/docs/v4.0.0/MESH.md @@ -270,22 +270,144 @@ kernel-Hermes's work in v3 and is not decided for the mesh. ## 8. Storage -**Proposal.** A disk is a device on a port. Asking for a block is a -message to it — read block *n*, or write block *n* with 1024 characters — -and the answer is a message back; a block is exactly the most a message -carries. Under v3's one block-number space, each device has its own range -of numbers. +**Ruled 2026-10-06** (Captain Bob), in the order the rulings were given. +What is marked *step 6* is built there; what is marked *step 6a* is ruled +and waits for that step. -- A node wired to a disk asks it directly. -- A node not wired to one asks through the node that is: the message is - forwarded like any other. So the common SSD is shared by every node that - has a way to the node that holds it. -- A node with its own drive has that device on one of its own ports. -- A node with no way to any disk has no storage, and `BLOCK` says so. +### 8.1 The rulings -Who may have which block is the block card's, decided where the disk is, -under the identity in the message's ACL tag (`V3-PARITY.md` 1d). Not -checked in this step. +1. **A disk is a device on a port that speaks messages.** Asking for a + block is a message — read block *n*, or write block *n* with 1024 + characters — and the answer is a message back. +2. **A node only ever asks for a block by number, and knows nothing else.** + It has one way to storage, as it has routes: a port, or nothing. This + replaces the earlier proposal that a node be told ranges of block + numbers. Nobody chooses ranges. +3. **Two numbers.** A logical block number is what `BLOCK n` and capsules + use. A physical block number is a place on a real device. A mapper + stands between them. +4. **The view is static; reality shifts to keep it so.** A logical number + always means the same block. Devices chain one after another in physical + space, and that chain changes as devices come and go; the mapper moves + data and changes its map so that the logical view does not change. All + the user sees change is how much storage there is. +5. **One metadata format for every block device** — a cloud store, a swap + file, an SSD, a USB drive, a thumbdrive, and any other within reason. + It is v3's (`v3/include/block_subsystem.h`): the `STFR` version 2 header, + the allocation map, the relocation table, and a card for every block + (`blk_meta_t`). A disk v3 formatted reads in v4. +6. **Plus an identity.** *(step 6a)* Two fields are added in the header's + spare space, as v3 added its relocation and fence fields: the device's + identity, and the identity of the chain it belongs to. A v3 disk reads + zero there: not yet given one. With them a device is known when it + returns, wherever it is plugged in. +7. **The mapper is the kernel's.** `V3-PARITY.md` section 1d stands: the + device chain, the metadata, first-touch claim, ACL, migration and the + Stadium touch stay in the kernel's block subsystem, which is v3's C + code. What a node finds on a storage port is that subsystem, speaking + messages in logical block numbers. (The mapper was first ruled to be a + capsule on the node that holds the devices; that contradicted 1d, and on + being shown the contradiction Captain Bob ruled that 1d stands.) +8. **A node's own drive is private.** It is a second chain in the kernel, + wired to that node's port, and its blocks are nobody else's. A node may + have it in addition to the common store or instead of it. +9. **Common from the bottom up, private from the top down.** A block of the + common store has the same logical number on every node that shares it, + from 2048 upward. A node's private blocks are numbered from the top of + the number space downward: private block *k* is logical number + 2^32 - 1 - *k*, v3's block numbers being 32 bits. The two meet only if + the whole space is used up. +10. **A device leaves by being asked for.** *(step 6a)* Asked to release a + device, the mapper moves its blocks onto the devices that remain and + then says it may be pulled; if there is no room, the release is refused + with a message. A device pulled without asking leaves holes: its + logical numbers stay claimed and answer "no storage" until it returns, + is known by its identity, and its blocks are at the same numbers again. + +### 8.2 What a node does *(step 6)* + +`BLOCK`, `BUFFER`, `UPDATE` and `SAVE-BUFFERS` keep their two buffers and +their FORTH-79 behaviour. The one word beneath them in +`v4/capsule/blocks.v4` that read or wrote a block by storing to four +registers sends a message and waits for the answer instead. + +- A node wired to storage writes the message to that port. +- A node that is not sends the same message toward the node that is, and + it is passed on like any other (section 7). +- A node with no way to storage has none: `BLOCK` is an error with a + message, and the node is back at its prompt. + +The four storage registers and `v4_node_storage_attach` go from the engine. + +### 8.3 The messages *(step 6)* + +Four types, beside text, output and done (section 6): + +| Type | Payload | Answered by | +|---|---|---| +| Block read | the block number, one word | Block data, or Block done with an error | +| Block write | the block number, one word; a Block data message follows it | Block done | +| Block data | 1024 characters | | +| Block done | one word: it worked, there is no storage, or it was refused | | + +A write is two messages because a block is exactly the most a message +carries, so the number cannot go with the data. Whatever answers pairs the +two by who sent them. + +### 8.4 What is on a storage port *(step 6)* + +A device (4.3), in `v4/system/storage.c`, which the hosted and the +bare-metal builds share as they share `boot.c`. It speaks the messages of +8.3 and asks v3's block subsystem (`v3/src/block_subsystem.c`) for every +block. The engine (`v4/src`) knows nothing of it. + +- v3's code does what it does: header, allocation map, block cards, + relocation, three blocks and their cards to a 4 KiB device block. +- The devices beneath are v3's own back ends: RAM and a file when hosted, + the virtio disk on bare metal. +- Blocks 0 to 2047 are the chain's fast RAM, as in v3; nodes that share + the common store share those too. +- The device holds a **view**: the common chain, or a private chain, or + both. A number at the top of the space (ruling 9) is the private + chain's; any other is the common chain's; a number in a chain the view + does not have is "no storage". + +**A change to v3's C.** Its block subsystem is one global chain. For a +second chain its state becomes something there can be two of. The change +is mechanical and the one chain v3 uses behaves as it did. (Approved.) + +Found 2026-10-06 and not yet ruled: `blk_subsys_init` must be given a v3 +`VM`, and refuses without one, though the subsystem stores it and never +uses it (`block_subsystem.c` line 651 is its only mention). The hosted v4 +system has no v3 `VM` to give. The same change would have to take that +argument away, which also changes the kernel's one call of it +(`kernel/src/capsule/capsule_loader.c`). + +**On bare metal** the lone node's storage port fronts the kernel's real +chain — RAM, the ramdrive and the virtio disk — in place of the RAM array +`kernel/src/v4/sk_v4.c` gives it today. (Approved.) Found 2026-10-06: +`kernel_main.c` starts the v4 node (line 523) before it sets that chain up +(lines 620 to 668), and the v4 node never returns, so under `STARFORTH_V4` +the chain does not exist today. Step 6 has the kernel set it up before the +node starts. + +### 8.5 Not in step 6 + +- **Who may have which block is not checked.** First-touch claim, the block + card's ACL and the Stadium touch need the node's identity, which is the + message's ACL tag (`V3-PARITY.md` 1d). Blocks are read and written + through v3's subsystem with nobody's claim on them. Not as intended yet. +- **Chains of more than one device, identities, release and holes** are + step 6a. +- **Cloud stores and real USB drives** wait for their drivers. The format + and the messages already fit them. + +### 8.6 Open + +A node that starts with only its own drive and later gains a way to the +common store. With no common store, its blocks from 2048 upward, a +capsule's among them, can only be on its own drive; when the common store +appears those numbers are claimed twice. Not ruled. ## 9. Birth, and Hera @@ -476,7 +598,21 @@ Each is tested, committed and pushed before the next. `BYE`, and nothing it asks is honoured, as ruled. - The suite now takes about four minutes, eight under the sanitizers: five POSTs. -6. **Storage (section 8).** +6. **Storage (section 8): the disk speaks messages, the kernel's mapper + answers, private drives.** Sections 8.2 to 8.4. Tests: a node reads and + writes blocks through a port, and a disk image v3's code formatted + reads back; in the unit of five, one outer node writes a block and + another reads it, one uses a drive of its own at numbers from the top + down, and one has no way to storage and `BLOCK` on it is an error with + a message (acceptance 3); POST 538 of 538 with `blocks.v4` changed, at + both widths and under the sanitizers; `hosted-check`; the three + bare-metal boots. + + **6a. Storage that changes while running.** Rulings 6 and 10 of + section 8.1: chains of several devices, the device and chain + identities, a device joining at the end and known when it returns, + release by asking, holes. Its acceptance is to be approved before it is + built. 7. **A second unit; scaling while running; sleep, wake and kill by command.** 8. **The hosted product is the five nodes**, on three ISAs: acceptance 1