Skip to content
This repository was archived by the owner on Jun 27, 2026. It is now read-only.

fix(mill): use per-node Nostr secret for identity so children get distinct keys (#266)#267

Open
ALLiDoizCode wants to merge 1 commit into
mainfrom
fix/issue-266-child-identities
Open

fix(mill): use per-node Nostr secret for identity so children get distinct keys (#266)#267
ALLiDoizCode wants to merge 1 commit into
mainfrom
fix/issue-266-child-identities

Conversation

@ALLiDoizCode

Copy link
Copy Markdown
Collaborator

Closes #266.

Problem

A mill provisioned at a non-zero derivation index ran with the apex/town key (index 0). Two nodes sharing one Nostr pubkey collide on the replaceable kind:10032 slot, so the mill's announcement overwrote the town's on the relay (surfaced during the #264 e2e).

Root cause: entrypoint-mill.ts deleted the supplied per-node NODE_NOSTR_SECRET_KEY whenever MILL_MNEMONIC was set ("mnemonic takes priority"), and startMill always derived identity via fromMnemonic(mnemonic) → index 0.

Key insight

The orchestrator already derives and passes each child's distinct key — buildNodeEnv → compose NODE_NOSTR_SECRET_KEY: ${MILL_SECRET_KEY}. Verified on the live apex: that key derives to nodes.yaml's mill pubkey 632981e0… (≠ town e93eeac8…). The fix is just to use it.

Note: the SDK's fromMnemonic(accountIndex) varies the NIP-06 address index (m/44'/1237'/0'/0/{i}), whereas the orchestrator's wallet varies the account (m/44'/1237'/{i}'/0/0) — different keys. So threading an index into fromMnemonic would NOT match nodes.yaml; using the orchestrator's pre-derived secret does.

Fix

  • mill.tsvalidateConfig now allows both mnemonic + secretKey (mnemonic drives BIP-32 swap-key derivation; secretKey overrides the Nostr identity). startMill derives identity from config.secretKey when present, else the mnemonic.
  • entrypoint-mill.ts / cli.ts — keep the per-node secret as an identity override when a mnemonic is also present (instead of deleting it).

DVM already uses its pre-derived index-2 NODE_NOSTR_SECRET_KEY (no mnemonic) → unaffected.

Tests / verification

  • Mill unit tests updated (both-supplied is now valid contract) — 189 pass.
  • Confirmed on the live apex that the mill's injected NODE_NOSTR_SECRET_KEY derives to 632981e0… (distinct from town, matches nodes.yaml).
  • Live container re-verification (mill running as 632981e0) needs the mill image rebuilt — local build OOMs on the mina-zkapp/o1js step, so it's deferred to CI.

🤖 Generated with Claude Code

…tinct keys (#266)

A mill provisioned at a non-zero derivation index (nodes.yaml records mill at
index 1) was running with the apex/town key (index 0): its entrypoint deleted
the supplied per-node `NODE_NOSTR_SECRET_KEY` whenever `MILL_MNEMONIC` was set
("mnemonic takes priority") and `startMill` always derived identity via
`fromMnemonic(mnemonic)` → index 0. Two nodes sharing one Nostr pubkey collide
on the replaceable kind:10032 slot, so the mill's announcement overwrote the
town's on the relay.

The orchestrator already derives and passes each child's distinct key
(`buildNodeEnv` → compose `NODE_NOSTR_SECRET_KEY: ${MILL_SECRET_KEY}`, verified:
that key derives to nodes.yaml's mill pubkey 632981e0…, ≠ town e93eeac8…). The
fix is to USE it:

- mill.ts: `validateConfig` now allows BOTH mnemonic + secretKey (mnemonic drives
  BIP-32 swap-key derivation; secretKey overrides the Nostr identity). `startMill`
  derives identity from `config.secretKey` when present, else the mnemonic.
- entrypoint-mill.ts / cli.ts: keep the per-node secret as an identity override
  when a mnemonic is also present (instead of deleting it).

DVM already uses its pre-derived index-2 `NODE_NOSTR_SECRET_KEY` (no mnemonic),
so it is unaffected. Mill unit tests updated (both-supplied is now valid) — 189 pass.

Live container re-verification needs the mill image rebuilt (CI; local build OOMs
on the mina-zkapp/o1js step).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HS apex: child nodes (mill/dvm) run with the apex/town key (derivation index 0), colliding kind:10032

1 participant