OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-proto-peer commits / 3f95b4f

0.3.131: label-list reports the label gate and the signed labels (with ver)
loser-club's member labels were never re-signed with ver and both co-owners logged nothing. get-state's holdsSigner asks the election WITHOUT the network head; the label tick asks WITH it. label-list now returns holds (the exact gate the tick asks) and each signed label with its ver. Read-only. Test-first; 177/177. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3f95b4f5a9f46734b1a97856c57934defc68d831
by plankatron <fleeky@gmail.com> · 2026-10-14T16:27:17.000Z

Changed files (3) +34 -2

lib/serve-device-uds.js +13 -1
……@@ -77,9 +77,21 @@ export async function serveDeviceUds (device, { uds, blobs = null, onRelease = n
7777 if (!uri || !val) throw new Error('label-intent: uri and val required')
7878 return l.ensure(uri, val, { neg: !!neg })
7979 })
80 // label-list — also the labeler's DIAGNOSTIC (2026-10-14: member labels never re-signed and nothing said why).
81 // `holds` is the exact gate the label tick asks (LabelRoom.holds → device.isSigner(), election WITH the network
82 // head — get-state's holdsSigner asks without it and can disagree). `labels` is the signed log itself, `ver`
83 // included, so "is it signed correctly" is a read, not an inference. Read-only.
8084 svc.handle('label-list', async () => {
8185 const l = needLabels()
82 return { intents: await l.base.intents(), signed: (await l.signedLog()).length }
86 const log = await l.signedLog()
87 let holds = null
88 try { holds = l.holds ? !!(await l.holds()) : null } catch { holds = null }
89 return {
90 intents: await l.base.intents(),
91 signed: log.length,
92 holds,
93 labels: log.map((x) => ({ uri: x.uri, val: x.val, cts: x.cts, neg: !!x.neg, ver: x.ver === undefined ? null : x.ver }))
94 }
8395 })
8496 // get-record: read ONE record back. get-state lists {collection, rkey} and no values, so a client
8597 // could see THAT a record exists and never what it says — which makes "is what I would write
package.json +1 -1
……@@ -1,6 +1,6 @@
11{
22 "name": "hyper-proto-peer",
3 "version": "0.3.130",
3 "version": "0.3.131",
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/label-uds.test.mjs +20 -0
……@@ -62,6 +62,26 @@ test('★ label-intent is idempotent; label-list shows intents and how many are
6262 t.is(g.changed, true, 'a negation is a change')
6363})
6464
65// ⛔ DIAGNOSE WHAT THE GATE SEES. 2026-10-14: loser-club's member labels were never re-signed with `ver`, both
66// co-owners logged nothing, and get-state's holdsSigner (asked WITHOUT the network head) said stortron while the
67// label gate asks WITH it. label-list now answers both questions on the device itself: would this device's label
68// tick sign right now (the same holds() the tick calls), and what is actually in the signed log, ver included.
69test('label-list reports the label gate and each signed label with its ver', async (t) => {
70 const sb = mockSb()
71 let gate = true
72 const room = new LabelRoom(sb, { src: SRC, privateKey: KEY, holds: () => gate, ns: '__labelintent__' })
73 const c = await serve(t, room)
74 await c.call('label-intent', { uri: WJ, val: 'loser-club-member' })
75 await room.tick()
76 const l = await c.call('label-list', {})
77 t.is(l.holds, true, 'holds: the gate the tick asks')
78 t.is(l.labels.length, 1)
79 t.alike({ uri: l.labels[0].uri, val: l.labels[0].val, ver: l.labels[0].ver, neg: l.labels[0].neg }, { uri: WJ, val: 'loser-club-member', ver: 1, neg: false })
80 t.ok(typeof l.labels[0].cts === 'string', 'with its cts')
81 gate = false
82 t.is((await c.call('label-list', {})).holds, false, 'and it follows the election')
83})
84
6585test('label-intent checks its input', async (t) => {
6686 const c = await serve(t, new LabelRoom(mockSb(), { src: SRC, privateKey: KEY, holds: () => true, ns: '__labelintent__' }))
6787 await t.exception(() => c.call('label-intent', { uri: WJ }), /val/)