Skip to content

docs: floating-identity doctrine — locations are candidates, never load-bearing - #63

Merged
hartsock merged 4 commits into
mainfrom
docs/floating-identity
Jul 19, 2026
Merged

docs: floating-identity doctrine — locations are candidates, never load-bearing#63
hartsock merged 4 commits into
mainfrom
docs/floating-identity

Conversation

@hartsock

Copy link
Copy Markdown
Member

Elevates the design intent Shawn articulated on #62 into a binding decision doc (docs/decisions/floating_identity.md) — per his ask to "document that somewhere that's more than idle prose."

The doctrine

Docs only. For the transport owner's review alongside #61/#62.

hartsock and others added 3 commits July 14, 2026 08:48
…ad-bearing

Elevates Shawn's PR #62 review from thread prose to binding design law:
identity (fingerprint) is the routing key; socket addresses are only ever
candidate paths; a quiet peer must never resolve to zero paths;
conversations outlive locations. Includes the #61 dial-back case study
(adding candidates fixed, removing the only path regressed — the bug is the
SINGULAR address, so dial_reply_peer(pubkey, [one addr]) is the shape to
retire) and the reviewer checklist + ratchet direction (harnesses fungible,
conversational context durable — the container/cloud playbook one layer up).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
#61) (#64)

Retire the single-address reply dial-back introduced in #21:
`dial_reply_peer` dialed the request's one source `SocketAddr`, so a
scopeless link-local IPv6 (`fe80::` with no scope id — what mDNS surfaces
on CI and most Linux hosts) became an undialable single point of failure.
QUIC `sendmsg` returned `InvalidInput`; a quiet-bind (`announce:false`)
peer, being mDNS-invisible, had dial-back as its only route, so its reply
was lost.

Per the floating-identity doctrine (docs/decisions/floating_identity.md):
a location is only ever a candidate, never load-bearing.

- `reply_dial_candidates`: the source path (its recvmsg scope id already
  intact — verified preserved through iroh's noq-udp fork) plus same-host
  loopback at the source port. Never one address, never empty.
- `is_scopeless_link_local`: hand-rolled `fe80::/10` + `scope_id == 0`
  test, because std's `is_unicast_link_local` is unstable on MSRV 1.75.
  Applied to BOTH dial sites — the reply path and the mDNS `dial_peer`
  candidate set — so a scopeless `fe80::` can no longer `sendmsg`-abort
  the iroh dial race (the racy full-suite failure seen while diagnosing
  the bug).

Regression tests are pure and deterministic, so they gate every PR; the
real dial-back-over-iroh proof stays #[ignore]d on the real-LAN tier.

Supersedes the #62 WIP handoff.

Co-authored-by: Shawn Hartsock <hartsock@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Cut the 20-year-playbook framing + blockquote and the "commodity intelligence" flourish; compress each section to its load-bearing point. The four design laws are unchanged in substance.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ior art

Add the one gap the Zero-Trust research pass found: keyless first contact is a TOFU leap of faith (RFC 7401's own admission). The pin decision is exposed as data and rendered by the consumer (#65). Add a terse prior-art section (Saltzer RFC 1498, HIP, NIST 800-207, SPIFFE, iroh) so reviewers cite the canon instead of rearguing it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@hartsock
hartsock merged commit d22191d into main Jul 19, 2026
3 checks passed
hartsock added a commit that referenced this pull request Jul 19, 2026
…iency (#69)

WHAT: Three real-iroh unit probes in bus.rs that answer, deterministically, what
the #[ignore]d mDNS integration tests cannot: what does incoming.remote_addr()
report for a same-host dial, and does the reply_dial_candidates set actually
reconnect to it?
  - probe_loopback_v4/v6_source_is_dialable_and_reconnects: bind two real
    endpoints, dial asker->responder over loopback, observe the source exactly as
    accept_conn does (logged as evidence), then dial the asker BACK over the
    candidate set and assert it reconnects.
  - probe_scopeless_link_local_source_reconnects_via_loopback_fallback: the
    decisive #61 case — feed the exact fe80::/scope-0 (undialable) shape at the
    asker's real port; assert the candidate set drops it yet still reconnects via
    the loopback fallback over real iroh.

WHY: #63 landed the candidate-set fix (reply_dial_candidates) but the empirical
"is it sufficient?" question was only answerable on a real-LAN runner. These make
the SAME-HOST answer deterministic and CI-gating: #63 delivers the reply even in
the worst-case scopeless-link-local source shape. Cross-host scoped-link-local
(does iroh preserve the recvmsg scope_id?) remains the real-LAN tier, covered by
the existing #[ignore]d reply_reaches_quiet_asker_via_dial_back.

Observed on this host: loopback-v4 -> 127.0.0.1:<port>, loopback-v6 -> [::1]:<port>
(both dialable); all three probes green in ~0.06s.

Co-authored-by: Shawn Hartsock <hartsock@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <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.

1 participant