A domain has one id, and every reader compares it verbatim

Accepted

ontoref
adr-081 made `domain.nu::project-domains` the single authority for domain membership. It unified

Context

adr-081 made `domain.nu::project-domains` the single authority for domain membership. It unified WHO answers and left untouched the vocabulary the question is asked in, and the two now disagree.

FOUR DECLARATIONS OF ONE ID, READ BY DIFFERENT CODE.

flat registry code/domains/<dir>/domain.ncl domain-root, bond validate, mode rung (adr-109) provider manifest domain_provides.id describe domain → find-domain-implementations consumer origin manifest domain_origin.id project-domains, suffix-stripped (domain.nu:134) bond carrier .domains-ontoref/<dir>/, bonds.ncl project-domains verbatim, bond.nu

`project-domains` answers in flat ids because it strips `-framework` and `-domain` from `domain_origin.id`. `describe domain` asks with the provider's `domain_provides.id`, unstripped. The ontoref daemon carries a third copy of the strip (ontoref-daemon/src/domain.rs:96).

MEASURED 2026-09-13, on the 17 registered projects:

librosys flat `librosys` provides `librosys-framework` describe domain: 0 of 1 members provisioning flat `provisioning` provides `provisioning-platform` describe domain: 0 of 6 members personal flat `personal` provides `personal-ontology` latent, no member yet rustelo flat `rustelo` provides `rustelo` describe domain: 3 of 3 (control)

The failure is silent on the surface that most needs it. `describe domain` opens with «Changes to the contract surface may affect registered implementations» and then lists none, so a provider changing its contract reads that no project inherits its Hard constraints — while DD-eca inherits librosys's through `domain_origin`, the one provenance that does (adr-081).

THE STRIP COULD NOT HAVE BEEN FIXED BY EXTENDING IT. It encodes a naming convention nobody declared, as a list of suffixes. `-platform` and `-ontology` are already outside it, and every new provider would be another entry.

THE TWO LEVELS OF adr-086 BOUND THE ANSWER. A first-level domain is hosted in the flat directory and its provider is a root. A second-level domain (htmx-site, provided by a project that itself declares `domain_origin`) is never hosted there (`flat-dir-hosts-first-level-only`). So "the id is the registry id" cannot be the whole rule: htmx-site has no registry id and must not get one.

Decision

A DOMAIN HAS EXACTLY ONE ID, AND ITS LEVEL SAYS WHERE IT IS DECLARED.

(1) FIRST LEVEL. The id is the flat registry directory, `code/domains/<id>/`. The project that the entry's `schema_cmd` resolves to declares `domain_provides.id = "<id>"`, byte for byte.

(2) SECOND LEVEL (adr-086). The id is the provider's `domain_provides.id`. It never appears in the flat directory, unchanged from adr-086.

(3) A CONSUMER NAMES A DOMAIN BY THAT ID. `domain_origin.id` and a carrier directory resolve to a flat id, or to the `domain_provides.id` of the project at `domain_origin.path`.

(4) EVERY READER COMPARES VERBATIM. The suffix strip is removed from `domain.nu::project-domains` and from the daemon's `extract_domain_origin`. No alias table replaces it: a name that needs translating is a declaration to correct, and a translation layer is where the next divergence would hide.

(5) ENFORCEMENT IS A MIGRATION, NOT A NORMALIZER. Migration 0098 checks, in the project it runs in, (1) on the provider side and (3) on the consumer side, and names the id it expected. librosys, provisioning and personal-ontoref go pending until they rename; DD-eca goes pending once librosys has, and follows.

adr-081 stands. Membership keeps one authority and typed provenance; this decision fixes the vocabulary that authority is asked in.

Constraints

  • Hard `project-domains` takes `domain_origin.id` as declared; no suffix is stripped.
  • Hard The daemon's domain_origin extraction does not strip suffixes.
  • Soft Migration 0098 checks both the provider and the consumer side and prints the id it expected.

Alternatives considered

  • Normalize the provider id in describe.nu with the same striprejected: One line, and it keeps three vocabularies alive. The suffix list is already incomplete (-platform, -ontology) and would grow with every provider.
  • Make the long provider id canonicalrejected: Renames flat directories, carriers in about eight projects, the ontoref lb aliases and the adr-109 mode path `.ontoref/domains/<id>/`. Much wider reach for no reader that benefits.
  • An alias table in the domain registryrejected: It is the strip written as data. Every reader must consult it, and a reader that forgets is the original defect again.
  • Register htmx-site in the flat directory so every domain has a registry idrejected: Violates adr-086 `flat-dir-hosts-first-level-only`: its provider declares domain_origin.

Anti-patterns

  • A normalizer standing in for an undeclared naming rule — Readers strip or map names so that two declarations of the same entity compare equal, instead of the declarations agreeing.

Related ADRs

ADR-073 · ADR-081 · ADR-086 · ADR-109

Was this useful? Rate it
Got something to add? Tell me what you think, what you'd suggest, or whether we should keep exploring this topic.
· reads

We use cookies to help this site function, understand service usage, and support marketing efforts. Cookie Policy for more info.