Constellation Layout — Spine at Parent, Code as Sub-Repo
Accepted
Context
As ontoref grew it accumulated a second git-tracked surface beyond the Rust implementation: brand assets, web site source, outreach presentations, private strategy notes, and the protocol spine itself (.ontoref/). All lived inside one flat git repo. The problems: (1) publication boundaries — code has one remote/visibility, the web site another, private strategy a third; forcing all three through one repo required either over-exposing private content or fragmenting git history with submodules. (2) spine ownership — with .ontoref/ inside code/, every change to the protocol spine became a Rust-repo commit, coupling protocol evolution to the implementation release cadence. (3) cross-area navigation — an agent scoped to code/ could not reach outreach/ or vault/ without leaving the repo; paths like '../outreach' were outside git scope. Three layout options were evaluated: (A) monorepo with subdirectories (code/, outreach/, vault/ all under one git root), (B) constellation (a parent holding independent git sub-repos), (C) external paths (each sub-repo anywhere, cross-references via absolute paths). Option B was chosen because it provides clean per-area publication boundaries — each folder is its own repo with its own remote and visibility — while keeping the spine at a level that governs all sub-repos without fragmenting it across satellites.
Decision
Adopt a constellation layout: a parent directory holds three to five independent git sub-repos — code/, outreach/, vault/, and an assets/ directory that is not itself a git repo. The .ontoref/ protocol spine lives at the parent level, not inside code/. The bash wrapper (code/ontoref) derives SPINE_DIR from SCRIPT_DIR/../.ontoref/; env.nu guards the ONTOREF_ROOT assignment with an is-empty check so the bash wrapper's value is not overridden at module load time; nickel_import_paths in config.ncl uses ../.ontoref/... (relative to ONTOREF_ROOT=code/); NCL files in .ontoref/ that import the data-dir companion (code/ontology/) use ../../code/ontology/... relative to the spine location. Cross-project Rust path dependencies that previously resolved via ../../../ now resolve via ../../../../ (one extra hop through code/). install.nu derives repo_root from $env.CURRENT_FILE rather than $env.PWD so it is robust to invocation from an arbitrary CWD.
Constraints
- Hard The .ontoref/ spine lives at the constellation parent, not inside code/; code/ontoref derives SPINE_DIR as SCRIPT_DIR/../.ontoref/
- Hard env.nu assigns ONTOREF_ROOT only when it is not already set, preserving the bash wrapper's value
- Hard nickel_import_paths entries for .ontoref/ content use ../.ontoref/... (relative to ONTOREF_ROOT=code/), not .ontoref/...
- Hard NCL files in .ontoref/ that import the data-dir companion use ../../code/ontology/... not ../../ontology/...
Alternatives considered
- Monorepo subdirectories (option A): one git repo, code/ outreach/ vault/ as subdirs — rejected: Cannot provide independent git remotes with different visibility per area without submodules or sparse-checkout. All areas share the same git history and commit graph, which pollutes code/ history with brand/outreach changes and prevents per-area release tagging.
- External paths (option C): each sub-repo anywhere on the filesystem, cross-references via absolute paths — rejected: Absolute paths are machine-specific and cannot be committed to the repo. Cross-repo navigation from an agent scoped to one repo requires the user to set environment variables per machine. The spine would have to live inside one of the repos (satellite problem: others reference it via absolute path and drift when it moves).
- Keep spine inside code/, model outreach/vault as satellite repos referencing it — rejected: Forces outreach/ and vault/ to carry a reference to code/'s absolute path for spine resolution. Moving code/ to a new machine or renaming it breaks the satellites. The spine's authority extends beyond code/; its location should reflect that.
Anti-patterns
- Spine as satellite — Keeping .ontoref/ inside one sub-repo (code/) and referencing it from sibling repos (outreach/, vault/) via absolute or relative cross-repo paths. The spine's authority extends to all sub-repos; scoping it to one creates a satellite dependency where moving or renaming that repo breaks all siblings.
- Unconstrained env.nu ONTOREF_ROOT override — env.nu unconditionally sets ONTOREF_ROOT from the file-derived path at module load time, silently overriding the bash wrapper's correctly computed value. In constellation layout this produces a wrong ONTOREF_ROOT (.ontoref/ instead of code/) that causes sync, install, and asset commands to target the wrong directory.
- Three-hop cross-project Cargo path dependencies — Using ../../../<peer> in Cargo.toml path deps when the crate is inside code/crates/<crate>/. With constellation, three hops reach the constellation parent (ontoref/), not the development root (Development/); peer projects are siblings of ontoref/, so four hops are required.