OverviewFilesCommitsIssuesDocsReleasesPeers

hypercore-kb commits / f48594c

skills/autobee: host.genesis is not a per-node admission gate
The skill repeated the README ("use this to bootstrap the first writer") and that is wrong for the obvious use. isGenesis() reads the system bee HEAD, which does not move until the batch flushes, so genesis stays true for every node of the batch that admitted the first writer. With optimistic:true that is exploitable: two self-admissions in one batch both see genesis and both land. Measured in favela-peer/test/genesis.test.js. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
f48594cfa9b7250cb79076fc61e8b39d99d8dbcd
by plankatron <fleeky@gmail.com> · 2026-09-06T16:08:34.000Z

Changed files (1) +31 -3

.claude/skills/autobee/SKILL.md +31 -3
……@@ -5,7 +5,8 @@ description: Multi-writer KV built on hyperbee2 — autobase's successor, with p
55
66# autobee
77
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
9one place where the README is misleading (`host.genesis` — see the trap below) (README + source
910under `node_modules/`). Anything sourced from the repo clone or the 2026-09-02 spike instead of the
1011published package is marked ⚠ REMEMBERED.
1112
……@@ -89,8 +90,35 @@ a hot apply loop that is a flush per op.
8990 loud-halt guard, available natively rather than hand-rolled.
9091- `host.createAnchor()` → `{ key, length }` — a verifiable checkpoint later writers can use to prove
9192 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
98MEASURED against 2.1.0 on 2026-09-06 (`favela-peer/test/genesis.test.js`), after taking the README
99at 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
103batch flushes. So `host.genesis` stays `true` for **every node of the batch that admitted the first
104writer**, including nodes applied after `host.addWriter` returned:
105
106```
107node 0 add-device host.genesis: true ← expected
108node 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
113can append at all — so two strangers' self-admissions landing in one apply batch would **both** see
114genesis 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
117apply wrote is visible to the very next op in the same batch (if you accumulate into a pending
118overlay, which you want anyway so the batch flushes once rather than per op). The substrate's head
119is not.
120
121⇒ `host.genesis` is sound as *"has this log ever been written to"*. It is not a per-node gate.
94122
95123## ⛔ Migration — the trap that looks like success
96124