| … | … | @@ -5,7 +5,8 @@ description: Multi-writer KV built on hyperbee2 — autobase's successor, with p |
| 5 | 5 | |
| 6 | 6 | # autobee |
| 7 | 7 | |
| 8 | | **Verified against the installed `autobee@2.1.0` + `hyperbee2@2.13.2` on 2026-09-06** (README + source |
| 8 | **Verified against the installed `autobee@2.1.0` + `hyperbee2@2.13.2` on 2026-09-06**, including |
| 9 | one place where the README is misleading (`host.genesis` — see the trap below) (README + source |
| 9 | 10 | under `node_modules/`). Anything sourced from the repo clone or the 2026-09-02 spike instead of the |
| 10 | 11 | published package is marked ⚠ REMEMBERED. |
| 11 | 12 | |
| … | … | @@ -89,8 +90,35 @@ a hot apply loop that is a flush per op. |
| 89 | 90 | loud-halt guard, available natively rather than hand-rolled. |
| 90 | 91 | - `host.createAnchor()` → `{ key, length }` — a verifiable checkpoint later writers can use to prove |
| 91 | 92 | causal ordering. |
| 92 | | - ★ `host.genesis` — `true` while the system has processed no nodes. **Use this to bootstrap the |
| 93 | | first writer** instead of inferring genesis from an empty roster. |
| 93 | - ⛔ `host.genesis` — the README says *"true if the system has not yet processed any nodes. Use this |
| 94 | to bootstrap the first writer."* **Do not use it as a per-node admission gate.** See the trap below. |
| 95 | |
| 96 | ## ⛔ `host.genesis` does NOT flip mid-batch |
| 97 | |
| 98 | MEASURED against 2.1.0 on 2026-09-06 (`favela-peer/test/genesis.test.js`), after taking the README |
| 99 | at its word and being wrong. |
| 100 | |
| 101 | `system.isGenesis()` is `this.bee.head() === null || this.bee.head().length === 0` |
| 102 | (`lib/system.js:100`) — it reads the **system bee's head**, and the head does not move until the |
| 103 | batch flushes. So `host.genesis` stays `true` for **every node of the batch that admitted the first |
| 104 | writer**, including nodes applied after `host.addWriter` returned: |
| 105 | |
| 106 | ``` |
| 107 | node 0 add-device host.genesis: true ← expected |
| 108 | node 1 (anything) host.genesis: true ← expected false |
| 109 | ``` |
| 110 | |
| 111 | **Why that is a security bug and not a curiosity.** A common admission design makes the founding case |
| 112 | "a device admitting itself, allowed only while genesis". With `optimistic: true` an unadmitted writer |
| 113 | can append at all — so two strangers' self-admissions landing in one apply batch would **both** see |
| 114 | genesis and both be admitted. A stranger would have made itself a writer. |
| 115 | |
| 116 | **The fix that works:** keep your own marker in the **app view**, written through apply. A value your |
| 117 | apply wrote is visible to the very next op in the same batch (if you accumulate into a pending |
| 118 | overlay, which you want anyway so the batch flushes once rather than per op). The substrate's head |
| 119 | is not. |
| 120 | |
| 121 | ⇒ `host.genesis` is sound as *"has this log ever been written to"*. It is not a per-node gate. |
| 94 | 122 | |
| 95 | 123 | ## ⛔ Migration — the trap that looks like success |
| 96 | 124 | |