OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-proto-peer commits / 83bd683

0.3.133: a labeler DID projects its labels at boot
The boot tick runs before the membrane exists; the initial projection synced the repo + firehose only; a quiet DID has no later event. loser-club's re-signed ver:1 member labels sat in both co-owners' signed logs (label-list projection:null) while the gateway served the old ones and bsky showed no badge. Boot now ticks the label room and syncLabels, bounded like the repo projection. Test-first (red: projection null after boot). 179/179. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
83bd6838cef03ee5788598fb30bd853e28466bb7
by plankatron <fleeky@gmail.com> · 2026-10-14T17:17:52.000Z

Changed files (3) +22 -1

lib/device-node.js +10 -0
……@@ -664,6 +664,16 @@ export async function bootSwarmDevice ({ storage, deviceMnemonic, did, signingKe
664664 // sync() reads the device's __commit__ log through the StateBase. On a device that is not yet admitted
665665 // (roster projected by another machine — #40 §6) that base may never advance, so this too is bounded.
666666 await awaitOrContinue('the initial membrane projection', membraneServing.sync(), 30000)
667 // ⛔ AND THE LABELS. The boot tick above ran before the membrane existed, so it signed but could not project,
668 // and a quiet DID has no later event to tick on. Measured 2026-10-14: loser-club's re-signed (ver:1) member
669 // labels sat in both co-owners' signed logs for hours (label-list projection:null) while the gateway served
670 // the old ones and bsky showed no badge. Sign whatever is pending (election-gated) and project, bounded.
671 if (labelRoom) {
672 await awaitOrContinue('the initial label projection', (async () => {
673 await labelRoom.tick()
674 await membraneServing.syncLabels()
675 })(), 30000)
676 }
667677 }
668678
669679 const close = async () => {
package.json +1 -1
……@@ -1,6 +1,6 @@
11{
22 "name": "hyper-proto-peer",
3 "version": "0.3.132",
3 "version": "0.3.133",
44 "description": "Self-custody, P2P-native atproto peer \u2014 holds the user's key + content as Hypercores and authors+signs its own repo. The source of truth in the peer/bridge split (Model B); atproto-bridge projects it to bsky.",
55 "type": "module",
66 "main": "lib/peer.js",
test/labeler-did.test.js +11 -0
……@@ -61,6 +61,17 @@ test('★ labeler DID: label-intent → a verified label in the served label cor
6161 t.is((await c.call('label-list', {})).signed, 2)
6262})
6363
64// ⛔ BOOT MUST PROJECT THE LABELS, NOT ONLY THE REPO. 2026-10-14: loser-club's re-signed (ver:1) member labels sat
65// in both co-owners' signed logs for hours while the gateway served the old ones — label-list reported
66// projection:null on both. The boot tick runs before the membrane exists, the initial projection after it synced
67// the repo + firehose only, and a quiet DID has no later event to tick on. A labeler's boot projects its labels.
68test('a labeler DID projects its signed log into the label core at boot, with no further event', { timeout: 120000 }, async (t) => {
69 const { c } = await boot(t, { labeler: true })
70 const l = await c.call('label-list', {})
71 t.ok(l.projection, 'label-list reports a projection right after boot (was null)')
72 t.is(l.projection && l.projection.coreLength, l.projection && l.projection.logLength, 'the served core holds the whole signed log')
73})
74
6475test('a DID without labeler: no label core, verbs say so', { timeout: 120000 }, async (t) => {
6576 const { node, c } = await boot(t, { labeler: false })
6677 t.is(node.membrane.labelKey, null)