Skip to content

feat(app): name a short id only when the registries of the SF agree, and mark it as a guess - #587

Open
khagele wants to merge 1 commit into
efiten:masterfrom
khagele:feat/452-name-consensus
Open

feat(app): name a short id only when the registries of the SF agree, and mark it as a guess#587
khagele wants to merge 1 commit into
efiten:masterfrom
khagele:feat/452-name-consensus

Conversation

@khagele

@khagele khagele commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Closes #452

The problem

resolveName asked the configured registries in order and took the first that answered ambiguous: false. That flag is a claim about one registry: a second registry knowing the same 2-byte prefix under another name was never asked, so disagreement could not even be observed. A 2-byte relay hash is the forwarder's hash out of the path, one in 65,536 per registry, and the name it got reached the ticker and the HUD looking like a resolved identity (73s.be repeater_3_ on hash 2beb, 2026-08-22). Decisions and what stays a guess are in docs/2026-09-05-names-agree-or-nothing.md.

My changes in this PR

  • resolversFor: every registry of the companion's spreading factor, asked at once; a registry of another SF names nodes this radio cannot hear, so it is left out. With the SF unknown, all are asked. Config order no longer means priority (orderResolvers is gone).
  • consensusName: one registry knowing the prefix, or several agreeing, is a name. Two different names for one prefix is a refusal, cached as such even when a third registry was unreachable, because no retry can turn disagreement into a name. Silence with a registry unreachable is not cached, as before.
  • The guess mark: isGuessedName and displayName in app/src/names.js; a name on a 2- or 3-byte id shows as ~name in the ticker (senderText), the HUD (senderReadout), the target list (targetParts) and the map popup. An advert's own name on its full key, a channel sender's name and an 8-byte discover prefix carry no mark; a 1-byte hash never carries a name.
  • Changelog entry in both copies.

Cost

One request per registry of the SF per unknown id instead of one per id, bounded by the session cache and the in-flight coalescing of #230. With the two registries in config.example.json that is at most double.

Verification

Suite Result
app vitest 908 passed, build and eslint clean
web vitest parity.test.js 57 passed

Tests with two stub resolvers, as the issue asked: two names for one prefix give none and the refusal is remembered; agreement gives the name, and so does one registry knowing it; only the resolvers of the companion SF are asked; silence with a registry down is not cached; disagreement with a registry down stays refused. Mutation-checked: consensus taking the first name, the SF filter removed, the guess floor at 16 hex and the refusal cache dropped each go red. Three existing tests that asserted an unmarked name on a 3-byte id now assert the mark.

Browser, two stub resolvers of SF 7, three receptions: both registries are asked for both prefixes; the ticker and the target list show 2beb (they disagreed), ~Agreed (they agreed) and alpha (an advert's own name, unmarked).

Not in this PR

🤖 Generated with Claude Code

…and mark it as a guess

resolveName took the first registry that called a prefix unique, and
ambiguous=false is a claim about that registry only: a second one knowing
the same 2-byte hash under another name was never asked, and the name
reached the ticker and the HUD with nothing to say it was a guess.

Every resolver of the companion's SF is now asked at once; a name only when
the registries that know the prefix agree, and two different names are a
refusal that stays cached. A name on a 2- or 3-byte id wears ~ on every
surface. Full keys, channel senders and 8-byte prefixes are unchanged.

Closes efiten#452

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

app: a 2-byte relay path hash gets a node's name because one resolver called it unique

1 participant