author, logo override); absent → neutral defaults. No project carries another's brand.
-`generate-mdbook` kept as an **alias** delegating to `docsite generate` (not retired);
`generate-docsite` is canonical. The bare `docs generate --fmt mdbook` renderer is unchanged.
## [0.1.7] — current release
### The constellation-memory, viability, and honest-limits arc
**Sessions 2026-06-08 → 06-10**
Nine ADRs (049–057) and five migrations (0034–0038), built on the substrate-view
engine (ADR-046) and scheme-tagged witnesses (ADR-047). One unifying discipline:
every mechanism here **notices, proposes, or verifies** — none **applies**, asserts,
or rules on truth. Authoritative state changes only through the witnessed `approve`
path (ADR-024). Version bump 0.1.6 → 0.1.7.
### ADR-049 — Criteria as a substrate-view describe level (Accepted) + migration 0035
Criteria — the conditions a project holds itself to (release gates, quality bars, coherence rules) — become a first-class describe level mounted through the substrate-view engine (ADR-046), distinguished by typed provenance. Every criterion carries `kind: 'Normative` (declared up front, ontology axis) or `'Discovered` (harvested from insights + the interaction trace, reflection axis); a discovered criterion MUST record the `provenance` it was graduated from. Promotion to normative is GATED behind a novelty-check plus human approval — recurrence alone never promotes; demotion is likewise a proposal, never silent. Registered in `levels.ncl` with `kind = 'Describe`, `eligibility = 'Learned`, so a project declaring no criteria mounts nothing and pays zero (ADR-029). Migration **0035** ships the criteria level. Engages `ontology-vs-reflection` (the typed tag is the legibility seam between asserted and observed) and `formalization-vs-adoption` (opt-in absence).
### ADR-050 — Witnessed validators: structural decidability, never truthfulness (Accepted)
A criterion is eligible to become an executable validator ONLY if it reduces to a bounded, structurally-decidable slice query plus the `state_root` commitment. Truthfulness criteria ("the positioning is honest", "the architecture is sound") are rejected at the eligibility gate and remain QA entries (ADR-049), never validators — a pass/fail verdict on such a claim would be the engine deciding truth. Every `ValidatorDecl` declares a `slice_query` naming exactly the nodes/edges/fields it reads; the `#[onto_validator]` predicate may read ONLY that slice + `state_root`. A validator over a `'Spiral`-poled tension MUST be `'Soft` and report direction of motion, never a Hard biconditional (the ondaod prohibition, applied to validators). Each run emits a witness binding the verdict to the `state_root` (ADR-024). 4 anti-patterns; no migration (internal validator architecture).
A one-directional, propose-only seam from the chronicle (companion-NCL milestones, harvested insights, the interaction trace ADR-037, ADRs-by-date) to the positioning Proof layer (ADR-043). `coder chronicle --as-proof-candidates` emits accepted ADRs and completed milestones as CANDIDATE proofs wired to the four-element framework — a candidate is a proposal, never an accepted Proof, materialized only through positioning's own acceptance path. The positioning audit's five rules verify candidates (one creating a DanglingRef / UnprovenValidatedAudience / AnchorDrift is surfaced, not accepted): the chronicle proposes, the audit verifies, a human accepts. Orphan milestones (shipped work with no positioning home) WARN, never erase — internal work the positioning layer never intended to claim is a legitimate half-state. The seam is outreach-read-only. Engages `ontology-vs-reflection` (history is reflection; a Proof is an ontology-side claim — auto-asserting would collapse the duality).
### ADR-052 — Memory feedback loop: propose, never apply (Accepted)
At `mode complete` the memory feedback loop emits PROPOSED deltas and never applies them. A proposal hook in `run.nu` surfaces three kinds — FSM-transition proposals against `state.ncl`, backlog-close proposals, and proof-citation proposals (ADR-051) — each via `backlog propose-status`, never a direct mutation. The ONLY path to authoritative state is the witnessed `approve` operation (ADR-024); the loop has no write path that bypasses it. Intent-vs-reality divergence (a dimension's blocker gone but catalyst unmet; a milestone shipped that no proof claims) is DESCRIBED as a half-state and proposed, never collapsed or fabricated. The hook always RUNS and SURFACES even when nothing is accepted, so the opposite collapse — decide-and-commit blind to drift — is structurally prevented. Engages `ontology-vs-reflection` (memory is reflection; state/backlog/proofs are ontology).
A presentation-spec (`reflection/schemas/presentation.ncl`) becomes the single declarative panel model the engine reads generically, so adding a panel is dropping an NCL file, never editing Rust. A `Panel` declares `{ id, title, kind ('Timeline | 'Gantt | 'Graph | 'Table | 'Board), data_source (op + params naming a catalog operation), surfaces, reference_links, filters, actors }`; the render path branches on `kind`, not panel identity, through the existing NclCache → JSON pipeline (the `graph.html` precedent). Panels declared as `presentation/panel-*.ncl`, referenced from `config.ncl``quick_actions`, or surfaced from a substrate-view all normalize to one panel list. A `data_source` MUST name a declared catalog operation — a panel is a projection of declared knowledge, never an independent Rust query. Domain projects extend by shipping their own panel NCL with no engine fork. Migration **0036** ships the presentation-spec schema.
### ADR-054 — Desktop/mobile native shell as a consumer surface (Accepted)
**Session 2026-06-09**
Permits a Tauri native shell (`ontoref-desktop`, same lib targeting desktop and mobile) as a strictly separate consumer of the daemon — modeled on `provisioning-desktop`. The shell wraps the existing daemon `/ui/` in a webview and adds the four browser-impossible capabilities: system tray, native OS notifications, local-daemon supervision, and native keyring. No version bump: internal architecture decision, no migration (governs ontoref's own development, not the consumer-visible protocol surface).
- **Dependency direction (Hard)**: the arrow is shell → daemon only. `ontoref-ontology`, `ontoref-reflection`, and `ontoref-daemon` must never depend on the desktop crate (C1–C3, typed `Cargo` checks) — preserves Protocol-Not-Runtime (ADR-001)
- **Placement (Hard)**: the shell lives as its own constellation sub-repo (ADR-048) or a workspace crate excluded from the installed/adopted footprint; consumes the daemon over HTTP/NATS only, may depend on `ontoref-ui` for presentation (C4)
- **Capture seam (Soft, directional)**: when the native surface occupies the `openness-vs-sustainability` seam it does so as a declared positioning consumer audience; tier-0 protocol adoption (ADR-029) stays free and unmetered (C5) — ondaod: Spiral tension gets a direction-reporting Soft constraint, never a Hard biconditional
- **Differentiator**: the drift-watcher (Passive Drift Observation) + notification barrier (ADR-002) give native notifications a first-class event source — the reason the host is more than a reskinned browser
- **ondaod**: engages `openness-vs-sustainability` (claim-only → **populating**: first declared occupant of the capture seam), `ontology-vs-reflection` (pure reflection-axis consumer), `formalization-vs-adoption` (optional layer, lowers daemon-run friction)
- **on+re**: `core.ncl` tension `openness-vs-sustainability` updated (synthesis state + `adrs=['adr-043','adr-054']`); `state.ncl` self-description-coverage catalyst records the incorporation; no Practice node added (shell is unbuilt — avoids a placeholder node)
### ADR-055 — Positioning viability seam: compensation as a second costura (Accepted)
**Session 2026-06-09**
Adds the `ViabilityPath` kind to the positioning layer — a **second costura parallel to `Proof`**, not a fourth orthogonal axis. Where a Proof answers "is the claim real?", a ViabilityPath answers "does the claim sustain its maker?". It converges PARA QUIÉN × CÓMO × (QUÉ×QUIÉN), `directness` (`'Direct`/`'Indirect`) binds the two poles of `openness-vs-sustainability`, and a one-directional `realized ⇒ realized_outcome` gate keeps compensation honest. Purely additive, opt-in (ADR-029), **no migration** (same precedent as ADR-043's four-element kinds — all fields defaulted, zero adoption cost).
- **Number-collision reconciliation**: authored concurrently with ADR-054 (both took `054`, the repo's second double-NNN after the double adr-039). The desktop shell kept `adr-054`; the viability seam took `adr-055`; the two are cross-linked as **occupant ↔ kind** — ADR-054 declared the desktop/mobile surface as the first capture-seam occupant but had no element to model it with, ADR-055 supplies that element
- **Schema/defaults** (`ontology/{schemas,defaults}/positioning.ncl`): `ViabilityPath` + `Directness`/`FlowKind` enums; `make_viability_path` with 4 cross-field invariants — converge-three-axes, anchor-to-graph, one-directional `realized⇒outcome` (Soft, never a Hard biconditional — ondaod), `Live⇒evidence_adr`
- **3 dogfood paths** (`.ontoref/positioning/viability/`, all `'Draft` — present state is claim-only): via-001 (Direct/HostedService governance-audit tail), via-002 (Indirect/Funnel personal-open visibility), via-003 (Direct/Product native-shell occupant citing adr-054 — closes the gap ADR-054's own negative consequence named)
- **Rust walker** (`ontoref-ontology`): `ViabilityPath`/`Directness`/`FlowKind`/`ViabilityConverges` types, `PositioningConfig.viability_paths`, `Positioning` runtime view with `DanglingConverges` referential-integrity checks + `viability_path_by_id` lookup + `viability` dir in the cold-load walk. Daemon `GET /api/positioning` surfaces the list + `viability_paths`/`realized_viability_paths` counts. 39 ontology tests pass; `ontoref-ontology` clippy clean
- **constraints**: 3 Hard (seam-not-axis, converges-three, anchored-to-graph) + 2 Soft on the Spiral question (realized-gate-one-directional, capture-stays-off-protocol-surface); 4 anti-patterns (viability-as-fourth-axis, realized-without-outcome, meter-the-protocol, hard-biconditional-on-viability)
- **on+re**: `core.ncl` positioning-layer node (`adrs += adr-055`, `viability/` dir, second-costura description) + tension node (`adrs=['adr-043','adr-054','adr-055']`, "no viability axis" clause corrected); `state.ncl` catalyst records the incorporation
### ADR-056 — Sufficient verification over complete knowledge (Accepted)
Names a trust model that had been operating across the protocol without ever being stated as one: no actor — human or agent — holds the whole project, and recording everything to approach completeness overflows context and produces more confusion than clarity. A trust model resting on "know it all, keep it all current" fails in both directions. Trust instead rests on **local, partial verification of sufficient knowledge — accredited, not generated**: you verify the slice you need by witness, without holding the whole. It is the only model that scales to real humans and to agent context windows that cannot hold the entire project. Formalises the basis the verifiable substrate (ADR-023) and the witness seam (ADR-031) already assumed.
Makes the outreach discipline architectural: **route each door to a live graph, never argue the core.** Outward communication reveals itself through the same queryable substrate — the positioning graph projected via `spine.ncl` + a generator — rather than bespoke prose, converting per-conversation human mediation into a reproducible projection. Publishing a real personal graph as the rung-3 mediation artifact is a per-artifact privacy decision (cleared for the jpl graph 2026-06-10, never automatic for others). Anchors the `outreach/site` projection work.
### Migrations 0034–0038
- **0034** `substrate-views` — the substrate-view engine (ADR-046): disciplines mount scoped slices of levels.
- **0035** `criteria-level` — the criteria describe level (ADR-049).
- **0036** `presentation-spec` — the config-driven panel model (ADR-053).
- **0037** `memory-surface-fan-out` — the memory loop's proposal surface (ADR-052).
- **0038** `coder-workflow-harvest-criteria` — the coder harvest that graduates discovered criteria (ADR-049/052).
carries `ContainerRegistry` in the distributions catalog. Version bump applied.
Bug fix: `migrate.nu:migrations-dir` used `$env.ONTOREF_ROOT` instead of
`project-root`, causing `onre migrate list` to return `[]` on constellation
layouts (post-ADR-048 spine at parent). Fixed to `(project-root)` — migrations
now resolve from the spine regardless of whether the spine is inside or outside
`ONTOREF_ROOT`.
---
## [0.1.5]
### ADR-048 — Constellation layout: spine at parent, code as sub-repo (Accepted)
**Session 2026-06-02**
Formalizes the decision to move `.ontoref/` from inside `code/` to the constellation parent directory, establishing `code/` as one independent git sub-repo among several (`outreach/`, `vault/`) under a non-versioned umbrella.
- **Bash wrapper** (`code/ontoref`): derives `SPINE_DIR` as `SCRIPT_DIR/../.ontoref/`; sets `ONTOREF_PROJECT_ROOT` to the parent
- **`env.nu`**: `ONTOREF_ROOT` assignment guarded with `is-empty` — preserves the bash wrapper's value at module load time
- **`config.ncl``nickel_import_paths`**: `.ontoref/` entries prefixed with `../` (relative to `ONTOREF_ROOT=code/`)
- **NCL imports in `.ontoref/`**: `card.ncl` and `ontology/{core,state,gate,manifest}.ncl` use `../../code/ontology/` for the data-dir companion
- **Cargo path deps**: peer projects at `Development/` level now resolve via `../../../../` (four hops); stratumiops crates gain `code/` segment (`../../../../stratumiops/code/crates/`)
- **`install.nu`**: `repo_root` derived from `$env.CURRENT_FILE` — robust to arbitrary CWD; constellation fallback for `reflection_src` and `bootstrap_src`
A three-level architecture surfaced in the field (Rustelo builds a website-mode over a Torred domain; the resulting websites are hosted inside a Provisioning workspace) that ADR-018's absolute `Base/Domain/Instance` triad could not express. Two generalisations, both **opt-in and backward-compatible** — a depth≤3 single-chain repo declares nothing new.
- **Relative recursive levels.** `level.index` is reinterpreted as a **role in a sliding window of three** relative to an observation point, not an absolute coordinate. Actual depth is **derived** by walking `level.parent` to a `'Base` and is **uncapped** — `base → Torred → Rustelo → website-mode → website-instance` is a valid depth-5 chain. A depth≤3 chain derives `'Base/'Domain/'Instance` identical to the legacy declaration.
- **Domain co-tenancy.** `manifest.ncl` gains an optional `hosts` array (`{ chain, mount, digest? }`). One repo may host foreign chains from other projects, carrying only their Layer-3 wiring under `mount`, resolved by **witness not clone** (ADR-028/030). The terminal instance of one chain may re-host another chain's instance (instance-as-host is well-formed).
- **Mutation sovereignty (load-bearing).** A host runtime **must not** mutate a hosted chain's authoritative state — enforced by `validate hosts --check mutation-sovereignty` (no local op may `render_paths` into a hosted `mount`). Hosting is placement + wiring, not ownership (protects ADR-024).
- **Observable traversal.** `validate.nu` gains `validate hosts` (five checks — `chain-ref`, `mutation-sovereignty`, `chain-root` Hard; `layer3-tag`, `derived-index` Soft; with a 5-assertion `--self-test`) and `mode resolve` now reports the **full traversal path** and **chain scope**, not a single hop. Schema: `ontology/schemas/manifest.ncl` gains `host_entry_type`/`HostEntry` and the relative-level reinterpretation.
- **ADR-045** carries 5 constraints (3 Hard, 2 Soft — Soft on the `formalization-vs-adoption` Spiral per ondaod), `ontology_check` verdict `'Safe` (invariants at risk: `internal-coherence-enforced`, `protocol-not-runtime`, `voluntary-adoption` — all preserved), and 3 anti-patterns (`host-owns-hosted-state`, `absolute-level-flattening`, `implicit-hosting`). Migration **0033** propagates the schema (protocol-version 0.1.9 → 0.1.10). Graduates the bl-009 level-axis open question; `level-hierarchy-resolution` core node updated with `adrs=['adr-018','adr-045']` and a new `→ formalization-vs-adoption` (Resolves) edge.
---
### ADR-043 — Positioning as a four-element framework (Accepted)
**Session 2026-06-02**
The positioning layer (ADR-035) is reframed from three entangled artefact kinds into a **four-element framework**: three orthogonal axes bound by a validation seam. The work began as a strategic exercise — positioning ontoref against knowledge-graph competitors — and converged on a model that mirrors the protocol's own constitutive duality (ADR-031).
- **Three orthogonal axes, each a first-class typed kind.** QUÉ — `Differentiator` (one file per area of differential value) + `Competitor` (what they do / how ontoref differs). PARA QUIÉN — `Audience` (gains `status`: `Hypothesis` until a Proof validates it). CÓMO — `DifusionMechanism` (`kind`: Web | DocsSite | McpServer | Repo | Content | Talk | Event; persistent vs event). Difusión is the category; a `Campaign` is **one** time-boxed coordination within it, not the whole of it.
- **The fourth element is the costura, not a fourth axis.** VALIDACIÓN — `Proof`: the convergence of a differentiator, an audience and a difusión mechanism, signed by a real outcome. It references the other three axes; nothing references it — self-similar to the `witness-as-axis-seam`. `ValueProp` is the QUÉ×QUIÉN seam (gains `differentiator_ids`).
- **The marketing surface is governed by the mechanism it sells.** `ore positioning audit` now runs **five coherence rules** (local-first, daemon-independent): AnchorDrift, UnprovenValidatedAudience, Live-convergence, DanglingRef, CoverageGap. ADR-drift severity is **gated by value-prop status** — a Draft claim citing a Proposed ADR is informational; only Validated/Live must cite Accepted ADRs (mirroring `_live_requires_evidence_adrs`). Coverage gaps are explicit reminders, never silent.
- **Schema + contracts** — `ontology/schemas/positioning.ncl` gains `Differentiator`, `Competitor`, `DifusionMechanism`, `Proof` (+ enums `MechanismKind`, `ProofKind`, `AudienceStatus`); `ontology/defaults/positioning.ncl` gains `make_*` constructors with five rejecting contracts (`_diff_requires_anchor`, `_diff_requires_vs`, `_mechanism_non_empty`, `_proof_converges_all`, `_live_requires_differentiator`). Purely additive: every new field is defaulted, so existing positioning files validate unchanged.
- **Daemon** — `ontoref-ontology` gains the four structs and the walker loads `differentiators/`, `competitors/`, `difusion/`, `proofs/`; `from_config` enforces Proof referential integrity (rule 4) at load. `GET /api/positioning` serves the new kinds with counts (HTTP + MCP).
- **No migration required** — the schema change is additive and fully defaulted; the positioning layer remains opt-in (ADR-029). A migration is only warranted if the four-element framework is to be actively propagated to consumer projects.
---
### ADR-038 — OCI distribution and installer (Accepted) + migration 0029
**Session 2026-05-29**
ontoref now ships itself through the OCI registry along two paths from one build, modeled entirely in the workflow layer (not standalone scripts). The load-bearing tension was "Protocol, Not Runtime": a runnable daemon image must not make ontoref a runtime dependency. The synthesis (ADR-029): the daemon image is an **optional accelerator**; the `curl|sh` installer installs a daemon-less-capable CLI, so the bundle (protocol surface) and the image (optional service) stay decoupled.
- **Runnable multi-arch image** `reg.librecloud.online/ontoref/ontoref-daemon:VERSION` (linux amd64+arm64) — for running the daemon as a service. Assembled with **buildah FROM the cross-compiled musl binary** (no recompile, no `docker buildx`/QEMU/docker-in-docker), cosign-signed with an attested SBOM.
- **`curl … | sh`** → `install/install.sh` — detects OS/arch, pulls the per-platform bundle from the anonymous-pull `ontoref/dist` namespace via `oras` (curl fallback to the OCI Distribution API), verifies the `.sha256` sidecar, and installs mirroring `install.nu`'s layout (binary + data layer + wrappers with baked `ONTOREF_ROOT` + bundled `nickel`). Linux amd64+arm64 only; macOS gets source-build/container guidance. Flags: `--prefix`, `--version`, `--data-dir`, `--uninstall`/`--purge`.
- **Build-once** — `cross` compiles each arch once; both the bundle and the image consume that same binary.
- **Workflow-layer model** — `build_kind` gains `'Bundle` (`reflection/schemas/workflow.ncl`); `reflection/defaults/workflow.ncl` gains builds (`release-musl-arm64`, `bundle-linux-{x86,arm64}`, `oci-image-build`), the `smoke-bundle` publish gate, and the `distributions` catalog (`oci-image`, `oci-bundle-linux-{x86,arm64}`, `installer`); `ontology/workflow.ncl` gains the `release` layer (trigger `'OnTag`). A 4th generator `generate-distribution` in `reflection/modules/workflow.nu` (alongside PreCommit/Woodpecker/Justfile) emits `.woodpecker/release.yml`, renders `install/install.sh` from `install/install.sh.tmpl` (tokens from the catalog), and writes `justfiles/release.just`. Regenerate with `ore workflow generate --layer release` — never hand-edit the artifacts.
- **Assembler** `install/assemble-bundle.nu` — packages a cross-compiled binary into `ontoref-<os>-<arch>.tar.gz` (+ `.sha256`); `smoke` subcommand extracts and runs the binary (the release gate).
- **Registry** — `manifest.ncl::registry_provides` namespaces extended with `ontoref/ontoref-daemon/` and `ontoref/dist/` (the bundle namespace is anonymous-pull so `curl|sh` needs no credentials). Publishing secrets (cosign key, RW credential) come from the src-vault (ADR-017; self-hosted CI has no Fulcio → key-based signing).
- **Dockerfile** — root `Dockerfile` marked dev/local-only; the release image path is `.woodpecker/release.yml` via buildah.
- **ADR-038** carries 6 constraints (5 Hard, 1 Soft), `ontology_check` verdict `'Safe` (engaged tensions `protocol-not-runtime`, `voluntary-adoption`, `formalization-vs-adoption` — the rare case where more formalization *lowers* adoption friction), and 4 anti-patterns (`daemon-as-mandatory-runtime`, `hand-maintained-distribution-scripts`, `recompile-per-arch-image`, `bundle-carries-project-config`).
- **Migration 0029** `oci-distribution` — additive, opt-in; a project with no `release` layer is unaffected. Protocol delta **0.1.5 → 0.1.6**.
- **FAQ** — `reflection/qa.ncl::oci-distribution-and-install` documents both install paths, the build-once principle, the workflow-layer model, and the forbidden patterns.
Parse-first record of an agent/human session segment, stored as JSONL so reviews filter typed fields (`jq`, `nu where`) instead of mining prose. The opening framing — make the agent emit a *typed and validated* contract over its reasoning — was consciously narrowed: the goal is parseability, not validation of reasoning (undecidable, and an invitation to schema theatre). Typing is kept for filtering; content of free prose is never validated.
- **Schema** `reflection/schemas/interaction.ncl` — `InteractionRecord` + `Event`, `Decision`, `Action`, `InteractionInsight`, `WitnessRef` and the `EventKind`/`Status`/`Outcome`/`ActionKind` enums. Reuses `coder.ncl` vocabularies (`ActorKind`, `Kind`, `Domain`, optional `Category`) via import rather than forking. Every filterable dimension is an enum or typed array; free prose is confined to `summary`, `Decision.rationale`, `Event.note` — never a filter axis.
- **Module** `reflection/modules/interaction.nu` — `ore interaction record|validate|list|filter|decisions|insights` (alias `ix`). Two emission paths: `record` (validated append — forced) and direct JSONL write audited post-hoc by `validate` (CI/pre-commit gate). The structural validator derives enum allowlists from the schema files at runtime (single source of truth); validation is structural only and never inspects prose content.
- **Optional witness** (`WitnessRef`: `op_id`/`state_root`/`signature`) makes the layer tier-orthogonal: absent at tier-0 (review aid), present at tier-1/2 (reflection-side companion of witnessed acts — the ADR-031 seam). Opt-in per ADR-029; projects that never emit interaction JSONL pay zero adoption cost.
- **`Decision`** materialises the `adr?` criteria as filterable data (`alternatives_rejected`, `reversible`, `adr_candidate`, `tensions_engaged`) — ADR candidates surface across sessions in one query.
- **Migration 0028** `interaction-record-schema` ships the schema to consumer data dirs (additive, opt-in) — lands within 0.1.5, no version bump of its own.
- **Ontology** core.ncl gains the `interaction-trace` Practice node (`pole = 'Spiral`, `axis = 'Act`, 6 edges including `Complements` to `coder-process-memory` and `SpiralsWith` from `witness-as-axis-seam`).
- **ADR-037** carries 5 constraints (3 Hard, 2 Soft), `ontology_check` verdict `'Safe`, and 3 anti-patterns (`prose-truthfulness-gate`, `prose-as-filter-axis`, `forked-session-vocabulary`). All three Hard constraints pass `ore adr validate`.
- **Web surface** — `interaction export-html` renders `assets/web/interactions.html` (parse-first: structural fields only, never prose); `src/index.html` gains an 8th protocol-layer card (rose) linking to it. `.coder/interactions.jsonl` seeded with this session's own three real records (the feature documenting itself).
- **FAQ** — `reflection/qa.ncl::interaction-trace-howto` (queryable via `ore q interaction trace`): emission paths, minimal record, filtering, adoption, and the FORBIDDEN structural-only discipline.
- **Bug fix (ADR-032 drift)** — `describe.nu::qa search` loaded `(project-root)/reflection/qa.ncl`; ADR-032 moved the store under `.ontoref/`, so it now resolves via `(instance-root)` like `coder.nu`. The whole Q&A knowledge base was unreachable via `ore q` in self-hosted layout; one line restores it. Runtime change (`reflection/modules/`), no migration needed.
`cargo update --workspace --offline` confirms all 14 crates resolve to `0.1.5`.
---
### Version bump 0.1.0 → 0.1.5 — single workspace source of truth
**Session 2026-05-27**
-`[workspace.package].version = "0.1.5"` added to `Cargo.toml`; all 14 member crates switched to `version.workspace = true` (also `edition` and `license`).
-`.ontoref/card.ncl` no longer declares a `version` field — the daemon and downstream renderers read the canonical version from `Cargo.toml`. ProjectCard schema's `version | String | default = ""` makes the field optional.
- Accumulated protocol-surface deltas now reflected in machine-readable artefacts:
- within 0.1.5 — migration 0028 (interaction record schema, ADR-037; additive, no further bump)
-`cargo metadata --no-deps` confirms all 14 crates resolve to `0.1.5`.
Resolves the coherence gap where migrations narrated version bumps but `Cargo.toml` and `card.ncl` remained at `0.1.0`. Future bumps land in one place: `[workspace.package].version` in the root `Cargo.toml`.
---
### ADR-035 — Positioning layer (Accepted)
**Session 2026-05-26/27**
**ADR-035 — Positioning Layer: Marketing as Queryable Protocol Surface (Accepted)**
- Outward-facing surface formalised as queryable NCL. Three artefact kinds: `Audience`, `ValueProp`, `Campaign` — typed by schemas installed to the user data dir, instantiated per-project under `.ontoref/positioning/`.
-`LaunchCheck` tagged record (`'Grep | 'NuCmd | 'ApiCall | 'FileExists`) — structurally identical to `ConstraintCheck` in `.ontoref/adrs/adr-schema.ncl`; lift-out tracked as soft constraint `shared-check-lift-out-pending`.
- Cross-field contracts in `ontology/defaults/positioning.ncl`: `non_empty_audience_ids`, `live_requires_evidence_adrs`, `retired_has_date`, `superseded_implies_retired`, `each_launch_check_well_formed`. Enforced at nickel-export time via `make_audience` / `make_value_prop` / `make_campaign` helpers.
-`ProjectCard` schema extended with optional `primary_value_prop_id` field — zero-migration: every existing `card.ncl` typechecks unchanged. When present, MUST resolve to `.ontoref/positioning/value-props/<id>.ncl`.
- 6 Hard + 1 Soft constraint: `positioning-schema-installed`, `positioning-defaults-installed`, `audiences-not-inlined-in-value-props` (Grep on `primary_pain` in value-props), `card-primary-vp-resolves-when-set`, `live-value-props-cite-evidence-adrs`, `narrative-paths-resolve-when-declared`, `shared-check-lift-out-pending` (Soft).
- Anti-patterns recorded: `live-claim-without-evidence`, `audience-inlining`, `marketing-architecture-drift`. The drift anti-pattern is closed by `ore positioning audit` cross-referencing `evidence_adrs` against ADR status.
**Witness-seam (per ADR-031)**
-`evidence_adrs` on every `Live` value-prop is the substance-anchoring seam. A `Live` claim without `evidence_adrs` is a structural contract violation, not a stylistic concern. This is what distinguishes positioning-as-protocol-layer from positioning-as-CMS.
**Migration 0027 — positioning-layer**
- Schema additions to data dir (`ontology/schemas/positioning.ncl`, `ontology/defaults/positioning.ncl`).
- Optional extension to local `project-card.ncl` schemas (`primary_value_prop_id` field). Projects that import the protocol-shipped schema via `NICKEL_IMPORT_PATH` receive the extension automatically.
- Adopting the positioning layer (creating `.ontoref/positioning/{audiences,value-props,campaigns,narratives}/`) is OPT-IN per ADR-029. Tier-0 floor cost unchanged.
-`.ontoref/reflection/nulib/help.nu` — help text + capabilities surface include positioning.
-`assets/web/positioning.html` — landing page for the positioning surface (hand-edited until a follow-up generator ADR replaces it with Jinja from the NCL tree, per ADR-035 §ASSETS/WEB/ DERIVATION).
**On+re update**
-`.ontoref/ontology/core.ncl` — new `positioning-layer` Practice node (axis=Act, adrs=['adr-035']) with artifact paths to schemas, defaults, consumer layout, module, migration, card, and web page. 11 edges anchor it to: `reflection-axis-act` (ManifestsIn), `witness-as-axis-seam` (ManifestsIn via evidence_adrs), `formalization-vs-adoption` (Resolves), `ontology-vs-reflection` (Resolves), `voluntary-adoption` (ManifestsIn), `dag-formalized` (ManifestsIn), `adr-node-linkage` (Complements), `describe-query-layer` (ManifestsIn), `mcp-surface` (Complements), `domain-extension-system` (Complements), `personal-ontology-schemas` (Complements). Plus reverse edge from `tier-coexistence-permanent-design` (Complements) — positioning is the canonical example of an additive opt-in layer admitted by ADR-029.
-`.ontoref/ontology/state.ncl` — `protocol-maturity` blocker extended with session 2026-05-26/27 entry (positioning-layer addition, schema + defaults + migration 0027 + consumer instances + Nu module). `self-description-coverage` catalyst extended; total ADR count: 35 (ADR-021 → ADR-035 since session 2026-05-01).
**Ondaod synthesis (recorded in ADR-035 `ontology_check`)**
-`ontology-vs-reflection` (Spiral, Tension) engaged. Synthesis state: realised — positioning lives on the reflection axis; `evidence_adrs` deposits the witness-seam to substance. Per ADR-031, the seam extends outward to the marketing surface. Both Spirals stay open; verdict `'Safe`.
- Dual-surface `transition_tier`: `ontoref tier set <T>` CLI (every tier) + tier-2 catalogued op, both routing through a single Rust function that invokes `enforce_tier_transition_guard` from `crates/ontoref-daemon/src/tier_guard.rs` (the pure validator already shipped under ADR-029).
- Downgrade behaviour: substrate (oplog, commit_layer, state_root, signing keys) marked dormant immutable; past witnesses verify forever. Tier-2 descent emits a final `tier_descent` Ed25519 witness as the closing event.
- Transactional atomicity per direction — every transition produces exactly one of two outcomes: the project is at the requested tier OR at the original tier. No intermediate partial-substrate state ever visible.
- 8 Hard constraints + 1 Soft. `piloto-declares-its-tier` couples the mechanism to its canonical instance: ontoref's own `.ontoref/config.ncl` declares `ops.tier = 'Tier2` as part of this ADR (deferred to implementation per `'Proposed` status).
- Hard constraint `non-rust-kinds-require-ondaod-pre`: every non-Rust op MUST list `"evaluate_ondaod"` in `constraints.pre`. Enforced as a Nickel contract at typecheck time — ADR-024 ondaod discipline becomes structural rather than behavioural for the non-Rust path.
-`wasmtime` MUST NOT enter the default daemon build (`wasmtime-not-in-default-daemon-build`) — `protocol-not-runtime` axiom (invariant=true) preserved.
-`reflection/migrations/0024-tier-transition-mechanism.ncl` — documents the CLI + op surfaces, recommends explicit `ops` block in `.ontoref/config.ncl`. Protocol bump 0.1.1 → 0.1.2.
-`reflection/migrations/0025-catalog-kind-field.ncl` — schema bump for the four `kind`s with default `'Rust`. Backward-compatible: existing declarations typecheck unchanged. Protocol bump 0.1.2 → 0.1.3.
**QA additions**
-`reflection/qa.ncl::ontoref-catalog-extension-howto` — end-to-end how-to covering all four paths with decision tree, authoring steps, hard rules, witness-shape honesty per kind, when-you're-blocked triage.
- Reverse links added: `ontoref-tier-transition`, `ontoref-tier-downgrade-asymmetry`, `ontoref-multi-tier-management`, `ontoref-catalog-discovery-shared-domain` now reference ADR-033 / ADR-034 in their `related` arrays.
- 16 files demonstrating all four `kind`s end-to-end.
-`schema-future.ncl` co-locates the post-migration-0025 contract so all four examples typecheck today, even though the protocol schema is still pre-bump. Ondaod-pre Hard contract verified to fire on the negative case.
-`01-rust/` — declaration + handler skeleton for `greet_actor`.
-`03-ncl-transform/` — declaration of `rename_ontology_node`; declarable today, dispatch returns 501.
-`04-wasm/` — declaration of `render_provisioning_report` + WIT interface skeleton; declarable today, dispatch returns 501 until ADR-030 T3/T4/T5 fires.
**Ondaod synthesis (recorded in both ADRs' `ontology_check`)**
- ADR-033 engages `ontology-vs-reflection` (tier change is an act mutating substance; witness emitted at tier-2 boundaries is the seam) and `formalization-vs-adoption` (dual-surface CLI+op preserves both poles). Both Spirals stay open.
- ADR-034 engages `formalization-vs-adoption` (Rust strongest guarantees, NCL/Wasm/Sidecar lower barrier with weaker guarantees — schema admits all four without collapse) and the `protocol-not-runtime` axiom (preserved by deferring executive impls per ADR-030 triggers). Both poles continue in dialectic.
**Second-consumer validation of `ontoref-auth`, `ontoref-ui`, `ontoref-compute`, `ontoref-dns`**
-γ-auth: SUCCESS — lian-build delegates password hashing and session creation to `ontoref_auth::password::*`; `SessionStore` and `AuthUser` re-exported unchanged.
-γ-ui: SUCCESS — lian-build and `ontoref-panel` both adopt `ontoref_ui::init_tera`; `TeraEnv::Deref<Tera>` means zero call-site changes in either consumer.
-γ-compute: PARTIAL — lifecycle surface (`spawn`/`destroy`/`status`/`list`/`health`) validated by two consumers; `ScriptProvider` tagged-enum envelope structurally incompatible with lian-build's flat-JSON Nu scripts (documented gap, adapter path exists).
-γ-dns: SUCCESS — orchestrator replaces `coredns_client.rs` with `Arc<dyn DnsProvider>`; two independent consumers confirmed; trait locked.
**`ontoref-compute` — public constructors for non-exhaustive structs**
- Added `Instance::new(handle, provider)`, `ProviderHealth::healthy(latency_ms)`, `ProviderHealth::unhealthy(latency_ms, reason)` to resolve E0639 (`#[non_exhaustive]` blocks struct literal construction in external crates).
- Named constructors are the stable external API; `#[non_exhaustive]` retained so future optional fields do not break consumers.
**`ontoref-panel` C.5 — static asset pipeline and deployment architecture**
-`public_dir` and `templates_dir` added to `DaemonConfig`; surfaced as `PANEL_PUBLIC_DIR` / `PANEL_TEMPLATES_DIR` env vars and CLI args.
-`ServeDir` mounted at `/public` in Axum router (tower-http); attached before `.with_state(state)` in routes builder.
- UnoCSS + DaisyUI + HTMX build pipeline: `package.json`, `uno.config.ts`, multi-stage `Dockerfile` (`node-build` + `rust-build` + `runtime`). Docker build context must be the parent directory of all sibling repos — required for path deps to resolve.
`.ontology/state.ncl` — `protocol-stable` transition note: γ-posture validation results recorded per consumer; ScriptProvider envelope gap documented as known partial finding with adapter path (`LianBuildScriptProvider`).
`.ontology/core.ncl` — `unified-auth-model` updated with γ-posture verdicts for all four foundation crates; `ontoref-daemon` updated with handlers/ split note, `TeraEnv` migration note, panel C.5 CSS pipeline description.
| `.ontology/core.ncl` | `protocol-migration-system` node added; `adopt-ontoref-tooling` artifacts updated; `adr-lifecycle` updated with ADR-010; 4 new edges |
| `.ontology/state.ncl` | `protocol-maturity` catalyst updated (10 consumers, all features complete); blocker narrowed to `ontoref.dev not yet published` |