FABRIC.md §23 — Q1 dissolved, Q2 sized
Q1 (payload threshold) does not need answering, it needs removing. §3 wanted inline-if-small/by-reference-if-large so a cell need not be sized for a block. §19 gives a better answer: a large patron occupies more cells, chained by index, which is exactly what mass already means. A block is not by reference, a block is heavy. If the payload is in the Stadium, it counts toward mass. If it is not in the Stadium, the patron is not resident -- it is a handle to the warehouse. That closes the §19.6 loophole without a rule: a 1 MB block cannot occupy one cell and read as dense. It also preserves the hysteresis in §19.3, which depends on blocks being genuinely expensive to keep resident. Nothing in §3 is violated -- cells stay fixed-size, links stay indices, the Stadium stays an array. By-reference is reserved for things outside the Stadium, which are not patrons. Q2's premise is stale: §17.5 removed the screen grid, so the screen is no longer the worst case. Underneath it sits a question §17.5 left half-settled -- it decided the dirty event is the patron but not what one event covers. Per cell, an 80x25 redraw is 2,000 patrons and floods the Stadium; per region it is about 25. Leaning region-based, to be confirmed with the console work. The worst case then becomes messages, giving the rule: size the cell so a typical message is exactly one cell. Proposes 64-byte cells (one cache line), ~32-byte header, ~4096 cells per VM at 256 KB. Structure decided, constants leaning -- heat at 8 bytes is fixed by the existing Q48.16 convention, the rest need validating against a real build. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
d74872c222
commit
7c436351a0
@@ -1405,3 +1405,106 @@ rule looks correct.
|
||||
within a fixed total. Whether that total is itself fixed for the machine's lifetime is
|
||||
§20.5 #1, still open — and it should stay fixed, or §2's inescapable wall is not
|
||||
inescapable.
|
||||
|
||||
---
|
||||
|
||||
## 23. §12 Q1 dissolved, §12 Q2 sized
|
||||
|
||||
### 23.1 Q1 — the inline/by-reference threshold should not exist
|
||||
|
||||
> *Q1: Payload threshold — what size goes inline versus by reference.*
|
||||
|
||||
§3's motivation is sound: a cell sized for a 1024-byte block would be grotesque for a
|
||||
patron that carries twelve bytes. But §19 supplies a better answer than a threshold.
|
||||
|
||||
If cells are small and uniform, a large patron **occupies more of them, chained by index**.
|
||||
That is exactly what mass already means. A block is not "by reference" — a block is
|
||||
**heavy**.
|
||||
|
||||
This closes the loophole recorded in §19.6 #1 without introducing a rule:
|
||||
|
||||
> **If the payload is in the Stadium, it counts toward mass. If it is not in the Stadium,
|
||||
> the patron is not resident — it is a handle to the warehouse.**
|
||||
|
||||
A 1 MB block cannot occupy one cell and read as dense, because its bytes are on the floor
|
||||
and the floor is what mass measures.
|
||||
|
||||
This is also what gives §19's hysteresis its teeth. Blocks *should* be expensive to keep
|
||||
resident — that is the entire reason migration back to Artemis is their reap event (§17.2).
|
||||
A threshold that let big patrons masquerade as light ones would have quietly disabled the
|
||||
mechanism.
|
||||
|
||||
Nothing in §3 is violated: cells stay fixed-size, links stay indices, the Stadium stays an
|
||||
array. Multi-cell patrons are consistent with all of it. **By-reference is reserved for
|
||||
things genuinely outside the Stadium**, and those are not patrons.
|
||||
|
||||
**DECIDED — Q1 is dissolved rather than answered.**
|
||||
|
||||
### 23.2 Q2's premise moved, and an unsettled question sits under it
|
||||
|
||||
> *Q2: Arena entry header size… The header must be sized for the worst case, and that case
|
||||
> is the screen.*
|
||||
|
||||
§17.5 removed the screen grid from the Stadium, so that premise no longer holds. What
|
||||
replaces it depends on something §17.5 established only halfway: it decided the **dirty
|
||||
event** is the patron, but not what one event *covers*.
|
||||
|
||||
| Granularity | 80×25 full redraw | Consequence |
|
||||
|---|---|---|
|
||||
| per cell | 2,000 simultaneous patrons | floods the Stadium; starves every other patron |
|
||||
| **per line span / region** | **~25 patrons** | negligible |
|
||||
|
||||
A two-order-of-magnitude swing, currently undefined.
|
||||
|
||||
**Recommend region-based.** Framebuffer updates are naturally regional — a scroll dirties
|
||||
everything, a print dirties one span — overlapping regions coalesce for free, and per-cell
|
||||
events would make the console the numerically dominant patron kind in the entire system.
|
||||
That is absurd for something §17.5 correctly classified as a *utility* rather than an
|
||||
occupant.
|
||||
|
||||
**LEANING region-based.** It is a console-design decision as much as a Stadium one, so it
|
||||
should be confirmed when the console work happens rather than fixed here.
|
||||
|
||||
With that settled, the worst case for cardinality becomes **messages** — numerous,
|
||||
individually small. Which yields the sizing rule:
|
||||
|
||||
> **Size the cell so that a typical message is exactly one cell.**
|
||||
|
||||
### 23.3 Concrete sizing — proposal, to be validated
|
||||
|
||||
These are numbers to check against a real build, not derived truths.
|
||||
|
||||
| | Value | Reasoning |
|
||||
|---|---|---|
|
||||
| Cell size | **64 bytes** | one cache line; keeps density-ranking scans cache-friendly |
|
||||
| Header | ~32 bytes | identity 8, heat 8, TTL 4, link 4, mass 2, flags + behaviour tag 2 |
|
||||
| Inline payload | ~32 bytes | a small message fits in one cell — mass 1 |
|
||||
| 1024-byte block | 17 cells | 1 header + 16 payload; genuinely heavy, correctly so |
|
||||
| Per-VM Stadium | ~4096 cells = 256 KB | hundreds of hot words and blocks, ACLs, messages in flight |
|
||||
|
||||
256 KB per VM is comfortable against QEMU's `-m 1024`, and the outer Stadium's capacity
|
||||
(§20.5 #1) then follows from how many VMs the machine is willing to host.
|
||||
|
||||
Firmness of each figure:
|
||||
|
||||
- **Heat at 8 bytes is fixed**, not chosen — Q48.16 in a `uint64_t`, matching
|
||||
`execution_heat_q48` in the existing implementation.
|
||||
- **Link at 4 bytes** caps the Stadium at ~4 billion cells, far past anything plausible. It
|
||||
could shrink to 3 or even 2 bytes if the header gets tight.
|
||||
- **TTL at 4 bytes** gives ~4 billion ticks — over a year at 100 Hz. Almost certainly
|
||||
oversized; 2 bytes may do.
|
||||
- **Cell size 64** is the one to validate first, because everything else is expressed
|
||||
relative to it.
|
||||
|
||||
**LEANING.** The structure is decided; the constants are not.
|
||||
|
||||
### 23.4 Open
|
||||
|
||||
1. **Dirty-event granularity** (§23.2) — confirm region-based when console work begins.
|
||||
2. **Cell size validation.** Build the header for real, count the bytes, and check that a
|
||||
typical message still fits in one cell with the behaviour tag and flags included.
|
||||
3. **Is `identity` needed at all for every patron kind?** For a word it is a name; for a
|
||||
block a content hash; for a message possibly nothing — its identity could be its index.
|
||||
If identity can be elided for some kinds, 8 bytes of a 32-byte header is a large saving.
|
||||
This must not become a per-kind branch (§18.3), so it is only worth doing if it can be
|
||||
expressed uniformly.
|
||||
|
||||
Reference in New Issue
Block a user