flags: §6 was wrong about EventFlags — correcting a claim I asserted instead of checking
Section 6 said "there is no `EventFlags` type anywhere in the tree". There is:
`cube-core/src/wordflags.rs` defines `EventFlags` with eight classes — CPU 1<<0, MEM 1<<1,
NET 1<<2, WIFI 1<<3, POWER 1<<4, ERROR 1<<5, SECURITY 1<<6, BOOT 1<<7 — and §3's promise
that "the boot record passes `EventFlags::BOOT`" was kept. The driver's `BOOT_FLAGS = 1 << 7`
IS that bit.
What is actually missing is narrower than "no vocabulary": the two sides do not name each
other, because the kernel cannot link `cube-core`, so the number agrees by construction
rather than by reference — the same shape as the boot space `0xFC`, spelled out on both
sides, where the pairing lives in the gate. Here it lives in the driver's comment.
Two consequences, both recorded rather than quietly edited:
* the fix item "move `BOOT_FLAGS` off `TYPE_MASK`" is WITHDRAWN. The bit is in `EventFlags`'
own allocation (bits 0..7 for event classes), not inside `WordFlags`' TYPE_MASK field —
those are different fields, and the earlier section reached the right conclusion from a
wrong premise. What the item got right was the instinct: a bare `1 << 7` at the only class
bit in production is a fact nobody had written down.
* the correction is left in the text, with the reason it was wrong (asserted, not checked),
because a design record that silently rewrites its own mistakes teaches the next reader
nothing about how they happen.
This is the second claim this project has had to retract for the same reason in one day — the
first was a latency figure that had never had a measurement behind it. The pattern is the
same both times: a plausible statement that reads like a checked one.
This commit is contained in:
+23
-11
@@ -87,9 +87,17 @@ inventory as of 2026-09-23, taken by reading the tree rather than the design.
|
|||||||
kernel's `append`; read by `CUBE_OP_FLAG_SCAN` (mask + mode + scope); gated by
|
kernel's `append`; read by `CUBE_OP_FLAG_SCAN` (mask + mode + scope); gated by
|
||||||
`kernel/verify-flag-scan.sh`, which diffs the kernel's scan against userspace's. Deliberately
|
`kernel/verify-flag-scan.sh`, which diffs the kernel's scan against userspace's. Deliberately
|
||||||
vocabulary-agnostic.
|
vocabulary-agnostic.
|
||||||
*Allocation today: **one bit in use** — `BOOT_FLAGS = 1 << 7 = 0x0080`, a bare constant in the
|
*Allocation today: **one bit in use** — `BOOT_FLAGS = 1 << 7 = 0x0080` in the driver, which is
|
||||||
driver. §3 above says "the boot record passes `EventFlags::BOOT`"; **there is no `EventFlags` type
|
exactly `cube_core::EventFlags::BOOT`.* **Correction, and it is mine:** an earlier version of this
|
||||||
anywhere in the tree.***
|
section said "there is no `EventFlags` type anywhere in the tree". That was wrong, and it was
|
||||||
|
asserted rather than checked — `cube-core/src/wordflags.rs` defines `EventFlags` with eight classes
|
||||||
|
(`CPU 1<<0`, `MEM 1<<1`, `NET 1<<2`, `WIFI 1<<3`, `POWER 1<<4`, `ERROR 1<<5`, `SECURITY 1<<6`,
|
||||||
|
`BOOT 1<<7`) and §3's promise was kept. What is actually missing is narrower than "no vocabulary":
|
||||||
|
the two sides do not *name* each other, because the kernel cannot link `cube-core` — the driver
|
||||||
|
hard-codes `1 << 7` where the vocabulary says `EventFlags::BOOT`, and the number agrees by
|
||||||
|
construction rather than by reference. That is the same shape as the boot space (`0xFC` spelled out
|
||||||
|
on both sides), and the same answer: the pairing belongs somewhere a drift can be caught, which for
|
||||||
|
the space is the gate and for this bit is the driver's comment.
|
||||||
|
|
||||||
**[B] the header tier's `CubeHeader::flags: u16`** (`cube-header`). Bits 0..8 are *structured*,
|
**[B] the header tier's `CubeHeader::flags: u16`** (`cube-header`). Bits 0..8 are *structured*,
|
||||||
recomputed from the typed fields — **none are defined yet**. Bits 8..16 are *out-of-band*:
|
recomputed from the typed fields — **none are defined yet**. Bits 8..16 are *out-of-band*:
|
||||||
@@ -117,12 +125,14 @@ in production reads the boot record as **data type = code**. In [B] the same bit
|
|||||||
structured half, where nothing is defined.
|
structured half, where nothing is defined.
|
||||||
|
|
||||||
It is a **latent** collision, not a live one, and the fix is a declaration rather than a move: [A] is
|
It is a **latent** collision, not a live one, and the fix is a declaration rather than a move: [A] is
|
||||||
a field of its own, and `WordFlags` is not its vocabulary. `WordFlags` cannot be, either — its
|
a field of its own, `WordFlags` is not its vocabulary, and the evidence for that is [A]'s own use —
|
||||||
sixteen bits are all allocated, so there is no bit left to borrow — and the *space* axis is already
|
the bit in production is `EventFlags::BOOT`, and `EventFlags` allocates bits 0..7 for event classes,
|
||||||
the hard partition, so a boot record does not need a class bit to be findable at all (it lives in
|
which is a different allocation from `WordFlags`' sixteen. (And `WordFlags` could not be [A]'s
|
||||||
reserved space `0xFC`). What it needed was a vocabulary that claims it, which the driver now does:
|
vocabulary anyway: its bits are all allocated, so there is no bit left to borrow.) The *space* axis is
|
||||||
`BOOT_FLAGS` is documented as the first bit of the store's own class vocabulary, with the overlap
|
already the hard partition too, so a boot record does not need a class bit to be findable at all — it
|
||||||
stated where the constant is defined rather than left for a reader to discover.
|
lives in reserved space `0xFC`. What [A] needed was its vocabulary named on both sides, and the
|
||||||
|
driver now names it: `BOOT_FLAGS` is documented as `EventFlags::BOOT`, with the overlap and the
|
||||||
|
reason the number is written out rather than imported stated where the constant is defined.
|
||||||
|
|
||||||
The one bit the two fields *do* share is shared on purpose and by name: `0x0800`, which
|
The one bit the two fields *do* share is shared on purpose and by name: `0x0800`, which
|
||||||
`cube-store-seal` stamps as `SEALED_FLAG` and which `WordFlags` calls `ENCRYPTED`. Same meaning in
|
`cube-store-seal` stamps as `SEALED_FLAG` and which `WordFlags` calls `ENCRYPTED`. Same meaning in
|
||||||
@@ -144,8 +154,10 @@ a value spread across records, which only it assembles. It must not consume appl
|
|||||||
(MEM/SES/PRJ/EDG): that is §1's partition, restated where it can be enforced.
|
(MEM/SES/PRJ/EDG): that is §1's partition, restated where it can be enforced.
|
||||||
|
|
||||||
**The three concrete fixes, in order.**
|
**The three concrete fixes, in order.**
|
||||||
1. Move `BOOT_FLAGS` off `TYPE_MASK` — or declare [A] its own space in the driver and say so where
|
1. ~~Move `BOOT_FLAGS` off `TYPE_MASK`~~ — **withdrawn.** The bit is `EventFlags::BOOT`, in
|
||||||
the constant is defined, because today it reads as a member of a vocabulary it never joined.
|
`EventFlags`' own allocation; there was nothing to move, and the fix was to make the two sides
|
||||||
|
name each other, which the driver's comment does. What this item got right was the instinct that
|
||||||
|
a bare `1 << 7` at the only class bit in production is a fact nobody has written down.
|
||||||
2. Give one vocabulary a producer *and* a consumer in the same change, and the cheapest is sealing:
|
2. Give one vocabulary a producer *and* a consumer in the same change, and the cheapest is sealing:
|
||||||
the producer exists (`cube-crypt`), the consumer is the store, and the box's store is sealed
|
the producer exists (`cube-crypt`), the consumer is the store, and the box's store is sealed
|
||||||
right now — so the claim is checkable immediately.
|
right now — so the claim is checkable immediately.
|
||||||
|
|||||||
Reference in New Issue
Block a user