Skip to content

docs: define TLD-free name identifiers and amend the derivation docs - #464

Open
BigTava wants to merge 11 commits into
mainfrom
docs/name-identifiers
Open

docs: define TLD-free name identifiers and amend the derivation docs#464
BigTava wants to merge 11 commits into
mainfrom
docs/name-identifiers

Conversation

@BigTava

@BigTava BigTava commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds docs/design/name-identifiers.md defining name identifiers, their DotNS namehash form, and the TLD convention.
  • The convention makes the full served name the identity: the TLD stays in account derivation, ring contexts, entropy, permissions, and storage, so test and mainnet deployments never share state.
  • The reserved built-ins are network-scoped: uid.{tld} and peopl.{tld} follow the new dotns_tld host config (CLI presets, wasm runtimeConfig.dotnsTld, native record field), defaulting to dot so unconfigured hosts keep the mobile-pinned derivations.
  • Hosts also declare their network TLD through the optional HostChainSet.tld field in the supported_chains syscall.
  • Adds the Previewnet test TLD to DOTNS_TLDS and updates the host CLI SPEC and README.
  • Regenerates the TS adapter, codegen golden, and Swift bindings. The mobile app still pins uid.dot in its KeyDerivation package and needs the same rule.

@BigTava
BigTava requested review from a team August 20, 2026 10:37
@BigTava
BigTava force-pushed the docs/name-identifiers branch from 012503c to 74349f7 Compare August 20, 2026 10:39

@Imod7 Imod7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In rust/crates/truapi-host-cli/src/attestation.rs, check_identity now derives with tld but still prints a hardcoded label, on the line "//product//uid.dot/index_bytes(0)",. Both presets have a non-dot TLD, so it prints uid.dot while probing uid.paseo, which contradicts the SPEC this PR updated. Please build it with format!("//product//uid.{tld}/index_bytes(0)"). Three siblings need the same: the #[error("uid.dot identity derivation failed: {0}")] on LiteRegistrationError, which a host actually sees, plus check_identity's doc comment and two AccountRecord field comments.

},
Self::Previewnet => NetworkConfig {
id: "previewnet",
tld: "test",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pinned hosts/dotli submodule sets TLD: "dot" for PREVIEW_NET and asserts labelToProductId("acme") === "acme.dot" in its own test. #465's .test claim cites DotnsConfig::gamingnet(), which is Gaming Net rather than Previewnet, so it does not settle this. Since this value now decides key derivation, please confirm it against the previewnet registry's tld() view and correct whichever side is wrong, then record the source next to the field. The paseo value does check out, next-people-paseo sets NetworkSuffix = b"paseo". DOTNS_TLDS needs the same citation.

record: &AccountRecord,
) -> Result<AccountRecord> {
let identity = identity_from_mnemonic(&record.mnemonic)?;
let identity = identity_from_mnemonic(&record.mnemonic, network.tld)?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This re-keys every account already in accounts.json. On paseo-next-v2 the identity moves from uid.dot to uid.paseo, so registered_lite_username just below fails with attested signer has no Resources.Consumers record, after wait_for_ring_membership burns 10 attempts at 4s on a member key that was never admitted. Neither message mentions the TLD, so it reads as a chain or RPC problem. Please store the TLD on AccountRecord with #[serde(default)] giving "dot" for existing files, and bail with a message naming the mismatch. --submit is safe, it bails on ring membership before building anything. The explicit-signer path in start_signing_host has no stored record to compare, so logging which TLD the lookup used would at least make a mismatch visible there.

pub network: String,
/// dotNS TLD the network's registry declares via its `tld()` view, e.g.
/// `dot`, `paseo`, `test`. `None` when the host does not know it.
pub tld: Option<String>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing reads this. features.rs::chain_info is the only place HostChainSet becomes a product-facing answer and it uses set.network alone, and the pinned dotli's createSupportedChains does not set the field either. So a host that declares its TLD here gets no scoping, because the core derives from runtimeConfig.dotnsTld, and the two can disagree with nothing noticing. Please either wire it, resolving dotns_tld from this field so there is one declaration point, or drop it and add it with the change that consumes it. Surfacing it on get_chain_info would be a natural consumer.

}

#[test]
fn built_in_derivations_are_network_scoped() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tests the right property at the wrong layer: two pure functions given different arguments. Nothing proves the argument a host configured is the one they receive, and UnknownDotnsTld is never asserted anywhere, so deleting the resolution entirely would leave the suite green. I wrote both missing tests locally and they pass, so this is a coverage gap rather than a defect: one asserts that a with_dotns_tld("paseo") config yields a session identity equal to derive_identity_keypair(&ENTROPY, "paseo") and not the "dot" one, the other that "nope" is rejected. Could you add both. The two wasm reads of runtimeConfig.dotnsTld are uncovered too.

| Use Case | Description |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Navigation | A host resolves the name a user typed or followed into the content it should load, via [`NavigateDecision`](../../rust/crates/truapi-server/src/host_logic/dotns.rs). Here the name is an address rather than an identity, and it is used verbatim. |
| Product accounts | The account tree of a product hangs off its identifier: `//product//{nameId}/{index}` ([RFC-0022](../rfcs/0022-account-derivations.md)), implemented in [`product_account.rs`](../../rust/crates/truapi-server/src/host_logic/product_account.rs). The built-ins `uid.dot` and `peopl.dot` are reserved identifiers in the same tree. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cell says uid.dot and peopl.dot, and the User identity row two below says the same, both under a Convention section that makes the TLD part of the identity. RFC-0022, which this row cites, was not updated either: it still lists them as the reserved names and spells out //peopl.dot//index_bytes(0), so the citation in product_account.rs leads to the superseded rule. Please update the two cells and the RFC-0022 entries, and link this doc from RFC-0022, since nothing currently points at it. RFC-0024 and RFC-0004 are cited from this table too and worth a .dot grep.

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.

2 participants