OverviewFilesCommitsIssuesDocsReleasesPeers

pgh-sidecar commits / 33a1c17

0.2.53: use identityRootHex for the name anchor and identity-info
Three handlers computed the identity root as `masterPublicKey || devicePubkey`: identity-info, claim-name, release-name. `masterPublicKey` is set only by the hyperident loader, so on a linked device — every mirror, and tabertron — all three silently reported the DEVICE key. claim-name wrote it into `publisher.identityRoot`, the field a name is owned by and that update-name will authorise against, so rotating the device would orphan every claim. All three now call pgh's identityRootHex (pgh 0.1.140), which reads rootPubkeyHex first. release-name matters as much as claim-name: an anchor computed differently from the one the claim was written with can never match. Existing claims are unaffected by this — they carry the device key already and need update-name to re-anchor (org #143). Forge org #142. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
33a1c1703a8a0681db9da1f23d0b273a74047948
by plankatron <fleeky@gmail.com> · 2026-08-25T14:13:19.000Z

Changed files (2) +13 -19

lib/index.js +12 -18
……@@ -34,7 +34,7 @@ import { Service } from 'hyper-svc'
3434import { DeployServer } from 'hyper-deploy'
3535
3636import { TreeStore, DEFAULT_ROOT as PGH_STORE_ROOT } from 'pgh/store'
37import { loadOrCreateIdentity } from 'pgh/identity'
37import { loadOrCreateIdentity, identityRootHex } from 'pgh/identity'
3838import { ReleaseRegistry } from 'pgh/release-registry'
3939import { NameRegistry } from 'pgh/name-registry'
4040import { readSubscriptions as readSubscriptionsFromDisk, readNameSubscriptions, addNameSubscription } from 'pgh/subscriptions'
……@@ -1328,10 +1328,10 @@ export class Sidecar {
13281328 const id = this._identity || {}
13291329 const devicePubkey = id.publicKeyHex ||
13301330 (id.publicKey ? id.publicKey.toString('hex') : null)
1331 // masterPublicKey is populated by hyperident; raw fallback has none
1332 const rootPubkey = id.masterPublicKey
1333 ? (Buffer.isBuffer(id.masterPublicKey) ? id.masterPublicKey.toString('hex') : id.masterPublicKey)
1334 : devicePubkey
1331 // The root, via the one accessor that reads rootPubkeyHex first. Reaching
1332 // for masterPublicKey alone reported the DEVICE key on a linked device
1333 // (org #142) — hyperident sets it, `pgh device join` does not.
1334 const rootPubkey = identityRootHex(id)
13351335 return {
13361336 devicePubkey,
13371337 rootPubkey,
……@@ -1588,13 +1588,10 @@ export class Sidecar {
15881588 ? b4a.toString(this._registry._base.key, 'hex')
15891589 : null
15901590 const devicePubkey = this._identity && this._identity.publicKeyHex
1591 const identityRoot = this._identity && (
1592 this._identity.masterPublicKey
1593 ? (Buffer.isBuffer(this._identity.masterPublicKey)
1594 ? this._identity.masterPublicKey.toString('hex')
1595 : this._identity.masterPublicKey)
1596 : devicePubkey
1597 )
1591 // The anchor a name is owned by, and what `update-name` will authorise
1592 // against — it MUST be the root, or rotating the device orphans the
1593 // claim (org #142).
1594 const identityRoot = identityRootHex(this._identity)
15981595 const publisher = {
15991596 devicePubkey,
16001597 registryKey: params.registryKey || registryKeyHex,
……@@ -1611,12 +1608,9 @@ export class Sidecar {
16111608
16121609 svc.handle('release-name', async (ctx, params) => {
16131610 if (!params || !params.name) throw new Error('release-name requires { name }')
1614 const devicePubkey = this._identity && this._identity.publicKeyHex
1615 const identityRoot = this._identity && this._identity.masterPublicKey
1616 ? (Buffer.isBuffer(this._identity.masterPublicKey)
1617 ? this._identity.masterPublicKey.toString('hex')
1618 : this._identity.masterPublicKey)
1619 : devicePubkey
1611 // Same anchor the claim was written with (org #142) — a release that
1612 // computes it differently from the claim can never match.
1613 const identityRoot = identityRootHex(this._identity)
16201614 await this._nameRegistry.release(params.name, identityRoot)
16211615 return { ok: true, released: params.name }
16221616 })
package.json +1 -1
……@@ -1,6 +1,6 @@
11{
22 "name": "pgh-sidecar",
3 "version": "0.2.52",
3 "version": "0.2.53",
44 "description": "Small optional user-level daemon for pgh \u2014 shared identity vault, OTA polling, device linking, bootstrap seed, NameRegistry host",
55 "type": "module",
66 "main": "lib/index.js",