Protocol / Domain / Project as adaptive scopes — role-scoped placement is migratory and direction-reported, never a fixed partition

Accepted

ontoref
ontoref exists (ADR-001) because a protocol was 'a specification layer that happened to live in the

Context

ontoref exists (ADR-001) because a protocol was "a specification layer that happened to live in the wrong repo". Its reason for being is to decouple a protocol from its host project. It reproduced the same entanglement one level in:

- One undifferentiated ADR store. 78 ADRs in .ontoref/adrs/ mix product/self decisions (adr-002 daemon, adr-005 auth, adr-006 nushell, adr-013 vcs) with protocol/domain decisions that govern every consumer (adr-012, 018, 024, 028, 031, 045, 073, 074). - One undifferentiated mode store. self-dev modes beside protocol-offering modes (adopt_ontoref, new_project, update_ontoref). - No self-domain. The `framework` domain is one domain among domains; the manifest declares level = { index = 'Base } but no domain_provides for project-management. Base, not domain-of-itself.

Propagated downstream. Because the protocol never modeled "domain as a unit separable from its host project", consumers inherit the non-separation: rustelo's framework-governing decisions live in the PROJECT's .ontoref/adrs/ yet surface as consumer-governing HARD constraints; a domain's schema is coupled to the host .ontoref/ via required_extensions. You cannot manage only the domain of a project (its extensions, its implementation modes) without adopting ontoref for the host project — the motivating case with no answer today.

Relation to ADR-028. ADR-028 decides the addressing/sovereignty axis (content-addressed oplog, Ed25519/blake3, CRDT). This ADR is the orthogonal role/scope + adaptivity axis. ADR-028 exhibits the very collapse this ADR forbids — it pins classification with Type1..4 under severity = 'Hard.

Relation to adr-075. adr-075 makes the query surfaces route by the declared chain + bonds. This ADR adds the role-scope taxonomy those surfaces then route by; the routing itself lives in adr-075 and is referenced here, not re-decided. A bond (ADR-073) is a SIGNAL the adr-075 router reads to decide inheritance — it is not itself a scope an artifact lives in, so the scope axis is 'Base / 'Domain / 'Project, never a fourth 'Bond value.

Decision

Introduce three role-scopes as first-class, adaptive categories, orthogonal to ADR-028's addressing axis and ADR-012's activation axis:

'Base — ontoref as protocol: the ontological+reflection floor every onboarded project inherits (declare what/why, then communicate, validate, document, consistent micro-actions). 'Domain — the specialization surface { schemas + adrs + qa + modes }; dictates the protocol and governing modes for its established implementations, which further adjust. 'Project — local to the host codebase; the default.

Base/Domain/Project are REFERENCE POINTS on an inclusive continuum, not discriminating buckets. An artifact may inhabit one pole cleanly, OR hold several INCLUSIVELY — that is 'Spiral, the same held state ontoref's core tensions carry (pole = 'Spiral). Scope never forces an exclusive assignment; which pole manifests is determined by the querying CONTEXT, not fixed at tag time. The mechanics are inclusive by default: they may route a genuinely-exclusive artifact to its pole, but NEVER exclude a 'Spiral from any lens — a lens for any pole includes it. A polarizing mechanic (forcing exclusivity, or dropping a coexisting artifact) breaks the coexistence ontoref is built on — anti-PAP. In the positioning voice: the axis does not decide or impose a pole; it creates space for both, and the context reveals which — an instant of truth (`narratives/la-coexistencia-que-crea-espacio`). A bond (ADR-073) is NOT a scope; it is the relation-signal the adr-075 router reads.

FOUR MOVES (routing is adr-075, not repeated here):

1. NAME the poles plus the coexistence state as a declarable enum (scope_axis = [| 'Base, 'Domain, 'Project, 'Spiral |]).

2. PLACEMENT IS A SOFT, MIGRATORY PROPERTY. Each artifact declares its current scope and, when in motion, a desired scope with catalyst/blocker — the SAME shape as an FSM dimension (state.ncl transition_type). An ADR may be born in the project and migrate to the domain once it proves domain-governing. No Hard constraint pins the category. The boundary is a gradient with direction of motion — "there is no fixed measure" made structural. A second facet, placement over the flow [ClaimOnly, Populating, Realized, Consumed, Dormant], records HOW realized the migration is.

3. SELF-APPLICATION FIRST. ontoref classifies its own 78 ADRs and its modes across the three scopes before requiring it of consumers — the enforcement-vs-emergence discipline applied to the protocol's own boundary.

4. ALL CONSTRAINTS 'Soft / direction-reporting, except the two structural invariants (bond-is-not- a-scope; placement reuses transition_type rather than a parallel schema).

The representation is optional and defaults to 'Project: an untagged artifact is a project-local artifact, zero adoption cost. Most artifacts stay untagged; scope + direction are declared only for what is actually in motion.

Constraints

  • Hard The scope axis carries the poles 'Base/'Domain/'Project as reference points on an inclusive continuum, plus 'Spiral for an artifact that holds several poles inclusively; a bond (ADR-073) is a relation-signal read by the adr-075 router, never a scope value.
  • Hard A 'Spiral-scoped artifact is read as inhabiting ALL its poles: a lens query for any pole includes it, and no mechanic excludes it. Reading 'Spiral as one exclusive pole is malformed.
  • Soft Scope mechanics (routing, filters) may route a genuinely-exclusive artifact to its pole but NEVER exclude a coexisting ('Spiral) artifact from any lens; they report inclusion, not a discriminatory partition.
  • Soft An artifact's scope is a current value with an optional desired value and catalyst/blocker (the transition_type shape); no Hard constraint pins an artifact to one scope for all time.
  • Hard The migratory scope record reuses state.ncl's transition_type ({ catalyst, blocker, horizon }) rather than introducing a parallel migration schema.
  • Soft The 'Domain surface carries adrs (being) and modes (becoming) together; a domain scope with schemas but no modes, or commands but no ADRs, is malformed.
  • Soft A domain activates by EITHER a managed project's repo_kind match (adr-012) OR the presence of a bond carrier .domains-ontoref/<id>/bonds.ncl (adr-073); the dispatch admits both and removes neither. required_extensions binds ONLY the repo_kind (managed) path — a bond-only consumer ('Linked/'Node, no .ontoref/ spine) is exempt.

Alternatives considered

  • Keep the coupled status quo — domain as a lens over the host .ontoref/.rejected: It leaves the motivating case impossible: you cannot manage a project's domain without adopting ontoref for the project. required_extensions binds the domain's runtime to the host spine; nothing separates the two.
  • A fixed partition: each artifact class MUST live in exactly one scope, checked by Hard constraints.rejected: That is ADR-028's Type1..4 collapse — a Hard measure on a Spiral question. Placement evolves; freezing it forecloses the migration the whole design exists to model.
  • Add 'Bond as a fourth scope value.rejected: A bond (ADR-073) is a RELATION on its own governance/dependency axis, not a place an artifact lives. Making it a scope would duplicate ADR-073's axis and overload the taxonomy — the same anti-pattern ADR-010 forbids for the APA axis. Bond stays the signal the adr-075 router reads.

Related ADRs

ADR-075 · ADR-028 · ADR-012 · ADR-073 · ADR-067 · ADR-025 · ADR-031 · ADR-010

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.