---
feat: API catalog surface, protocol v2 tooling, MCP expansion, on+re update
## Summary
Session 2026-03-23. Closes the loop between handler code and discoverability
across all three surfaces (browser, CLI, MCP agent) via compile-time inventory
registration. Adds protocol v2 update tooling, extends MCP from 21 to 29 tools,
and brings the self-description up to date.
## API Catalog Surface (#[onto_api] proc-macro)
- crates/ontoref-derive: new proc-macro crate; `#[onto_api(method, path,
description, auth, actors, params, tags)]` emits `inventory::submit!(ApiRouteEntry{...})`
at link time
- crates/ontoref-daemon/src/api_catalog.rs: `catalog()` — pure fn over
`inventory::iter::<ApiRouteEntry>()`, zero runtime allocation
- GET /api/catalog: returns full annotated HTTP surface as JSON
- templates/pages/api_catalog.html: new page with client-side filtering by
method, auth, path/description; detail panel per route (params table,
feature flag); linked from dashboard card and nav
- UI nav: "API" link (</> icon) added to mobile dropdown and desktop bar
- inventory = "0.3" added to workspace.dependencies (MIT, zero transitive deps)
## Protocol Update Mode
- reflection/modes/update_ontoref.ncl: 9-step DAG (5 detect parallel, 2 update
idempotent, 2 validate, 1 report) — brings any project from protocol v1 to v2
by adding manifest.ncl and connections.ncl if absent, scanning ADRs for
deprecated check_hint, validating with nickel export
- reflection/templates/update-ontology-prompt.md: 8-phase reusable prompt for
agent-driven ontology enrichment (infrastructure → audit → core.ncl →
state.ncl → manifest.ncl → connections.ncl → ADR migration → validation)
## CLI — describe group extensions
- reflection/bin/ontoref.nu: `describe diff [--fmt] [--file]` and
`describe api [--actor] [--tag] [--auth] [--fmt]` registered as canonical
subcommands with log-action; aliases `df` and `da` added; QUICK REFERENCE
and ALIASES sections updated
## MCP — two new tools (21 → 29 total)
- ontoref_api_catalog: filters catalog() output by actor/tag/auth; returns
{ routes, total } — no HTTP roundtrip, calls inventory directly
- ontoref_file_versions: reads ProjectContext.file_versions DashMap per slug;
returns BTreeMap<filename, u64> reload counters
- insert_mcp_ctx: audited and updated from 15 to 28 entries in 6 groups
- HelpTool JSON: 8 new entries (validate_adrs, validate, impact, guides,
bookmark_list, bookmark_add, api_catalog, file_versions)
- ServerHandler::get_info instructions updated to mention new tools
## Web UI — dashboard additions
- Dashboard: "API Catalog" card (9th); "Ontology File Versions" section showing
per-file reload counters from file_versions DashMap
- dashboard_mp: builds BTreeMap<String, u64> from ctx.file_versions and injects
into Tera context
## on+re update
- .ontology/core.ncl: describe-query-layer and adopt-ontoref-tooling descriptions
updated; ontoref-daemon updated ("11 pages", "29 tools", API catalog,
per-file versioning, #[onto_api]); new node api-catalog-surface (Yang/Practice)
with 3 edges; artifact_paths extended across 3 nodes
- .ontology/state.ncl: protocol-maturity blocker updated (protocol v2 complete);
self-description-coverage catalyst updated with session 2026-03-23 additions
- ADR-007: "API Surface Discoverability via #[onto_api] Proc-Macro" — Accepted
## Documentation
- README.md: crates table updated (11 pages, 29 MCP tools, ontoref-derive row);
MCP representative table expanded; API Catalog, Semantic Diff, Per-File
Versioning paragraphs added; update_ontoref onboarding section added
- CHANGELOG.md: [Unreleased] section with 4 change groups
- assets/web/src/index.html: tool counts 19→29 (EN+ES), page counts 12→11
(EN+ES), daemon description paragraph updated with API catalog + #[onto_api]
2026-03-23 00:58:27 +01:00
|
|
|
let content = import "content.ncl" in
|
|
|
|
|
|
2026-03-13 00:21:04 +00:00
|
|
|
let repo_kind_type = [|
|
|
|
|
|
'DevWorkspace,
|
|
|
|
|
'PublishedCrate,
|
|
|
|
|
'Service,
|
|
|
|
|
'Library,
|
|
|
|
|
'AgentResource,
|
|
|
|
|
'Mixed,
|
2026-03-16 01:48:17 +00:00
|
|
|
'PersonalOntology,
|
2026-03-13 00:21:04 +00:00
|
|
|
|] in
|
|
|
|
|
|
|
|
|
|
let consumer_type = [|
|
|
|
|
|
'Developer,
|
|
|
|
|
'Agent,
|
|
|
|
|
'EndUser,
|
|
|
|
|
'CI,
|
|
|
|
|
'Downstream,
|
|
|
|
|
|] in
|
|
|
|
|
|
|
|
|
|
let artifact_kind_type = [|
|
|
|
|
|
'RustDoc,
|
|
|
|
|
'JsonSchema,
|
|
|
|
|
'ContainerImage,
|
|
|
|
|
'CratePackage,
|
|
|
|
|
'StaticSite,
|
|
|
|
|
'NuPlugin,
|
|
|
|
|
'OntologyExport,
|
|
|
|
|
|] in
|
|
|
|
|
|
|
|
|
|
let audit_level_type = [|
|
|
|
|
|
'Quick,
|
|
|
|
|
'Standard,
|
|
|
|
|
'Strict,
|
|
|
|
|
|] in
|
|
|
|
|
|
|
|
|
|
# ── Operational layers ──────────────────────────────────────────────────────
|
|
|
|
|
# A layer is a named region of the repo with visibility rules per mode.
|
|
|
|
|
# The `committed` flag distinguishes product (true) from process (false).
|
|
|
|
|
|
|
|
|
|
let layer_type = {
|
|
|
|
|
id | String,
|
|
|
|
|
paths | Array String,
|
|
|
|
|
committed | Bool,
|
|
|
|
|
description | String | default = "",
|
|
|
|
|
} in
|
|
|
|
|
|
|
|
|
|
# ── Operational modes ───────────────────────────────────────────────────────
|
|
|
|
|
# A mode is an active perspective the developer/agent switches into.
|
|
|
|
|
# It determines which layers are visible and what audit level applies.
|
|
|
|
|
|
|
|
|
|
let op_mode_type = {
|
|
|
|
|
id | String,
|
|
|
|
|
description | String | default = "",
|
|
|
|
|
visible_layers | Array String,
|
|
|
|
|
audit_level | audit_level_type | default = 'Standard,
|
|
|
|
|
pre_activate | Array String | default = [],
|
|
|
|
|
post_activate | Array String | default = [],
|
|
|
|
|
} in
|
|
|
|
|
|
|
|
|
|
# ── Publication service ─────────────────────────────────────────────────────
|
|
|
|
|
# Where artifacts go and what operations surround the publish action.
|
|
|
|
|
|
|
|
|
|
let auth_method_type = [|
|
|
|
|
|
'SSH,
|
|
|
|
|
'Token,
|
|
|
|
|
'OIDC,
|
|
|
|
|
'None,
|
|
|
|
|
|] in
|
|
|
|
|
|
|
|
|
|
let service_scope_type = [|
|
|
|
|
|
'Public,
|
|
|
|
|
'PrivateNetwork,
|
|
|
|
|
'LocalRegistry,
|
|
|
|
|
'SelfHosted,
|
|
|
|
|
|] in
|
|
|
|
|
|
|
|
|
|
let publication_service_type = {
|
|
|
|
|
id | String,
|
|
|
|
|
artifact | artifact_kind_type,
|
|
|
|
|
scope | service_scope_type,
|
|
|
|
|
registry_url | String | default = "",
|
|
|
|
|
auth_method | auth_method_type | default = 'None,
|
|
|
|
|
pre_publish | Array String | default = [],
|
|
|
|
|
post_publish | Array String | default = [],
|
|
|
|
|
condition | String | default = "",
|
|
|
|
|
trigger | String,
|
|
|
|
|
} in
|
|
|
|
|
|
|
|
|
|
# ── Consumption modes (who consumes, what they need) ────────────────────────
|
|
|
|
|
|
|
|
|
|
let consumption_mode_type = {
|
|
|
|
|
consumer | consumer_type,
|
|
|
|
|
needs | Array artifact_kind_type,
|
|
|
|
|
audit_level | audit_level_type | default = 'Standard,
|
|
|
|
|
description | String | default = "",
|
|
|
|
|
} in
|
|
|
|
|
|
|
|
|
|
# ── Tool requirements ─────────────────────────────────────────────────────
|
|
|
|
|
# Declares what tools the project needs. install-tools.nu and sync audit
|
|
|
|
|
# consume this to verify availability or trigger installation.
|
|
|
|
|
|
|
|
|
|
let install_method_type = [|
|
|
|
|
|
'Builtin,
|
|
|
|
|
'Cargo,
|
|
|
|
|
'Npm,
|
|
|
|
|
'Brew,
|
|
|
|
|
'Pip,
|
|
|
|
|
'Manual,
|
|
|
|
|
|] in
|
|
|
|
|
|
|
|
|
|
let tool_requirement_type = {
|
|
|
|
|
name | String,
|
|
|
|
|
install_method | install_method_type | default = 'Builtin,
|
|
|
|
|
version | String | default = "",
|
|
|
|
|
required | Bool | default = true,
|
|
|
|
|
} in
|
|
|
|
|
|
|
|
|
|
# ── Justfile convention ──────────────────────────────────────────────────
|
|
|
|
|
# Declares expected justfile structure so sync audit can verify completeness.
|
|
|
|
|
|
|
|
|
|
let justfile_system_type = [| 'Import, 'Mod, 'Hybrid, 'Flat, 'None |] in
|
|
|
|
|
|
|
|
|
|
let justfile_convention_type = {
|
|
|
|
|
system | justfile_system_type | default = 'Mod,
|
|
|
|
|
required_modules | Array String | default = ["build", "test", "dev", "ci"],
|
|
|
|
|
required_recipes | Array String | default = ["default", "help"],
|
|
|
|
|
} in
|
|
|
|
|
|
feat: config surface, NCL contracts, override-layer mutation, on+re update
Config surface — per-project config introspection, coherence verification, and
audited mutation without destroying NCL structure (ADR-008):
- crates/ontoref-daemon/src/config.rs — typed DaemonNclConfig (parse-at-boundary
pattern); all section structs derive ConfigFields + config_section(id, ncl_file)
emitting inventory::submit!(ConfigFieldsEntry{...}) at link time
- crates/ontoref-derive/src/lib.rs — #[derive(ConfigFields)] proc-macro; serde
rename support; serde_rename_of() helper extracted to fix excessive_nesting
- crates/ontoref-daemon/src/main.rs — 3-tuple bootstrap block (nickel_import_path,
loaded_ncl_config: Option<DaemonNclConfig>, stdin_raw); apply_ui_config takes
&UiConfig; NATS call site typed; resolve_asset_dir cfg(feature = "ui")
- crates/ontoref-daemon/src/api.rs — config GET/PUT endpoints, quickref, coherence,
cross-project comparison; index_section_fields() extracted (excessive_nesting)
- crates/ontoref-daemon/src/config_coherence.rs — multi-consumer coherence;
merge_meta_into_section() extracted; and() replaces unnecessary and_then
NCL contracts for ontoref's own config:
- .ontoref/contracts.ncl — LogConfig (LogLevel, LogRotation, PositiveInt) and
DaemonConfig (Port, optional overrides); std.contract.from_validator throughout
- .ontoref/config.ncl — log | C.LogConfig applied
- .ontology/manifest.ncl — contracts_path, log/daemon contract refs, daemon section
with DaemonRuntimeConfig consumer and 7 declared fields
Protocol:
- adrs/adr-008-ncl-first-config-validation-and-override-layer.ncl — NCL contracts
as single validation gate; Rust structs are contract-trusted; override-layer
mutation writes {section}.overrides.ncl + _overrides_meta, never touches source
on+re update:
- .ontology/core.ncl — config-surface node (28 practices); adr-lifecycle extended
to adr-007 + adr-008; 6 new edges (ManifestsIn daemon, DependsOn ontology-crate,
Complements api-catalog-surface/dag-formalized/self-describing/adopt-ontoref)
- .ontology/state.ncl — protocol-maturity blocker and self-description-coverage
catalyst updated for session 2026-03-26
- README.md / CHANGELOG.md updated
2026-03-26 20:20:22 +00:00
|
|
|
# ── Config surface ──────────────────────────────────────────────────────
|
|
|
|
|
# Describes the project's configuration system: where the NCL config lives,
|
|
|
|
|
# how it is structured, and which consumers (Rust structs, Nushell scripts,
|
|
|
|
|
# CI pipelines, external tools) read each section.
|
|
|
|
|
#
|
|
|
|
|
# A field in a section is "unclaimed" only if no consumer declares it —
|
|
|
|
|
# not merely absent from the Rust struct. CI/CD scripts and external tooling
|
|
|
|
|
# are first-class consumers.
|
|
|
|
|
#
|
|
|
|
|
# Mutation uses an override layer: original NCL files are never modified.
|
|
|
|
|
# Changes are written to {section}.overrides.ncl and merged via & at the
|
|
|
|
|
# entry point. Comments, contracts, and formatting in originals are preserved.
|
|
|
|
|
|
|
|
|
|
let config_kind_type = [|
|
|
|
|
|
'NclMerge, # multiple .ncl files merged via & operator
|
|
|
|
|
'TypeDialog, # .typedialog/ structure with form.toml + validators + fragments
|
|
|
|
|
'SingleFile, # single monolithic .ncl file
|
|
|
|
|
|] in
|
|
|
|
|
|
|
|
|
|
let consumer_kind_type = [|
|
|
|
|
|
'RustStruct, # serde::Deserialize struct in a Rust crate
|
|
|
|
|
'NuScript, # Nushell script accessing $config.field paths
|
|
|
|
|
'CiPipeline, # CI pipeline (Woodpecker, GitHub Actions, etc.)
|
|
|
|
|
'External, # external tool or process reading config JSON
|
|
|
|
|
|] in
|
|
|
|
|
|
|
|
|
|
let config_consumer_type = {
|
|
|
|
|
# Identifier for this consumer (e.g. "vapora-backend", "deploy-script").
|
|
|
|
|
id | String,
|
|
|
|
|
kind | consumer_kind_type,
|
|
|
|
|
# Reference path: Rust fully-qualified type or script path.
|
|
|
|
|
# e.g. "vapora_backend::config::ServerConfig" or "scripts/deploy.nu"
|
|
|
|
|
ref | String | default = "",
|
|
|
|
|
# Fields this consumer reads. Empty means the consumer reads all fields,
|
|
|
|
|
# which is treated as claiming all NCL keys for orphan analysis.
|
|
|
|
|
fields | Array String | default = [],
|
|
|
|
|
} in
|
|
|
|
|
|
|
|
|
|
let config_section_type = {
|
|
|
|
|
# Section identifier, must match the top-level NCL key (e.g. "server").
|
|
|
|
|
id | String,
|
|
|
|
|
# Path to the NCL file for this section, relative to config_root.
|
|
|
|
|
file | String,
|
|
|
|
|
# Path to the NCL contract file that types this section. Relative to
|
|
|
|
|
# contracts_path (or project root if contracts_path is empty).
|
|
|
|
|
contract | String | default = "",
|
|
|
|
|
description | String | default = "",
|
|
|
|
|
# Why this section exists and why the current values were chosen.
|
|
|
|
|
# Consumed by the quickref generator to explain decisions, not just values.
|
|
|
|
|
rationale | String | default = "",
|
|
|
|
|
# When false: ontoref will only read, never write, this section.
|
|
|
|
|
mutable | Bool | default = true,
|
|
|
|
|
# All consumers of this section. A NCL field present in no consumer is
|
|
|
|
|
# flagged as unclaimed in the coherence report.
|
|
|
|
|
consumers | Array config_consumer_type | default = [],
|
|
|
|
|
} in
|
|
|
|
|
|
|
|
|
|
let config_surface_type = {
|
|
|
|
|
# Directory containing config NCL files, relative to project root.
|
|
|
|
|
# e.g. "config/", "site/config/", ".typedialog/provisioning/"
|
|
|
|
|
config_root | String,
|
|
|
|
|
# Main NCL file that merges all sections (entry point for nickel export).
|
|
|
|
|
entry_point | String | default = "config.ncl",
|
|
|
|
|
kind | config_kind_type | default = 'NclMerge,
|
|
|
|
|
# Directory containing NCL contract files. Relative to project root.
|
|
|
|
|
# Passed as NICKEL_IMPORT_PATH component when exporting.
|
|
|
|
|
contracts_path | String | default = "",
|
|
|
|
|
# Directory where ontoref writes {section}.overrides.ncl files.
|
|
|
|
|
# Defaults to config_root when empty.
|
|
|
|
|
overrides_dir | String | default = "",
|
|
|
|
|
sections | Array config_section_type | default = [],
|
|
|
|
|
} in
|
|
|
|
|
|
2026-03-13 00:21:04 +00:00
|
|
|
# ── Claude baseline ─────────────────────────────────────────────────────
|
|
|
|
|
# Declares expected .claude/ structure per project.
|
|
|
|
|
|
|
|
|
|
let claude_baseline_type = {
|
|
|
|
|
guidelines | Array String | default = ["bash", "nushell"],
|
|
|
|
|
session_hook | Bool | default = true,
|
|
|
|
|
stratum_commands | Bool | default = true,
|
|
|
|
|
} in
|
|
|
|
|
|
|
|
|
|
# ── Root manifest ───────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
let manifest_type = {
|
|
|
|
|
project | String,
|
|
|
|
|
repo_kind | repo_kind_type,
|
|
|
|
|
layers | Array layer_type | default = [],
|
|
|
|
|
operational_modes | Array op_mode_type | default = [],
|
|
|
|
|
consumption_modes | Array consumption_mode_type,
|
|
|
|
|
publication_services | Array publication_service_type | default = [],
|
|
|
|
|
tools | Array tool_requirement_type | default = [],
|
|
|
|
|
justfile | justfile_convention_type | default = {},
|
|
|
|
|
claude | claude_baseline_type | default = {},
|
|
|
|
|
default_audit | audit_level_type | default = 'Standard,
|
|
|
|
|
default_mode | String | default = "dev",
|
2026-03-16 01:48:17 +00:00
|
|
|
# Node ID this project maps to in the ontology DAG.
|
|
|
|
|
# Used by portfolio tooling to cross-reference publication cards.
|
|
|
|
|
ontology_node | String | default = "",
|
---
feat: API catalog surface, protocol v2 tooling, MCP expansion, on+re update
## Summary
Session 2026-03-23. Closes the loop between handler code and discoverability
across all three surfaces (browser, CLI, MCP agent) via compile-time inventory
registration. Adds protocol v2 update tooling, extends MCP from 21 to 29 tools,
and brings the self-description up to date.
## API Catalog Surface (#[onto_api] proc-macro)
- crates/ontoref-derive: new proc-macro crate; `#[onto_api(method, path,
description, auth, actors, params, tags)]` emits `inventory::submit!(ApiRouteEntry{...})`
at link time
- crates/ontoref-daemon/src/api_catalog.rs: `catalog()` — pure fn over
`inventory::iter::<ApiRouteEntry>()`, zero runtime allocation
- GET /api/catalog: returns full annotated HTTP surface as JSON
- templates/pages/api_catalog.html: new page with client-side filtering by
method, auth, path/description; detail panel per route (params table,
feature flag); linked from dashboard card and nav
- UI nav: "API" link (</> icon) added to mobile dropdown and desktop bar
- inventory = "0.3" added to workspace.dependencies (MIT, zero transitive deps)
## Protocol Update Mode
- reflection/modes/update_ontoref.ncl: 9-step DAG (5 detect parallel, 2 update
idempotent, 2 validate, 1 report) — brings any project from protocol v1 to v2
by adding manifest.ncl and connections.ncl if absent, scanning ADRs for
deprecated check_hint, validating with nickel export
- reflection/templates/update-ontology-prompt.md: 8-phase reusable prompt for
agent-driven ontology enrichment (infrastructure → audit → core.ncl →
state.ncl → manifest.ncl → connections.ncl → ADR migration → validation)
## CLI — describe group extensions
- reflection/bin/ontoref.nu: `describe diff [--fmt] [--file]` and
`describe api [--actor] [--tag] [--auth] [--fmt]` registered as canonical
subcommands with log-action; aliases `df` and `da` added; QUICK REFERENCE
and ALIASES sections updated
## MCP — two new tools (21 → 29 total)
- ontoref_api_catalog: filters catalog() output by actor/tag/auth; returns
{ routes, total } — no HTTP roundtrip, calls inventory directly
- ontoref_file_versions: reads ProjectContext.file_versions DashMap per slug;
returns BTreeMap<filename, u64> reload counters
- insert_mcp_ctx: audited and updated from 15 to 28 entries in 6 groups
- HelpTool JSON: 8 new entries (validate_adrs, validate, impact, guides,
bookmark_list, bookmark_add, api_catalog, file_versions)
- ServerHandler::get_info instructions updated to mention new tools
## Web UI — dashboard additions
- Dashboard: "API Catalog" card (9th); "Ontology File Versions" section showing
per-file reload counters from file_versions DashMap
- dashboard_mp: builds BTreeMap<String, u64> from ctx.file_versions and injects
into Tera context
## on+re update
- .ontology/core.ncl: describe-query-layer and adopt-ontoref-tooling descriptions
updated; ontoref-daemon updated ("11 pages", "29 tools", API catalog,
per-file versioning, #[onto_api]); new node api-catalog-surface (Yang/Practice)
with 3 edges; artifact_paths extended across 3 nodes
- .ontology/state.ncl: protocol-maturity blocker updated (protocol v2 complete);
self-description-coverage catalyst updated with session 2026-03-23 additions
- ADR-007: "API Surface Discoverability via #[onto_api] Proc-Macro" — Accepted
## Documentation
- README.md: crates table updated (11 pages, 29 MCP tools, ontoref-derive row);
MCP representative table expanded; API Catalog, Semantic Diff, Per-File
Versioning paragraphs added; update_ontoref onboarding section added
- CHANGELOG.md: [Unreleased] section with 4 change groups
- assets/web/src/index.html: tool counts 19→29 (EN+ES), page counts 12→11
(EN+ES), daemon description paragraph updated with API catalog + #[onto_api]
2026-03-23 00:58:27 +01:00
|
|
|
# Publishable content assets (logos, diagrams, web pages).
|
|
|
|
|
# Declares source paths and publication targets; consumed by publish modes
|
|
|
|
|
# and sync drift detection to verify assets exist and are deployed correctly.
|
|
|
|
|
content_assets | Array content.ContentAsset | default = [],
|
|
|
|
|
# Reusable NCL templates for mode steps, agent prompts, and publication cards.
|
|
|
|
|
# Each template is a parameterised NCL function at source_path.
|
|
|
|
|
templates | Array content.ContentTemplate | default = [],
|
feat: config surface, NCL contracts, override-layer mutation, on+re update
Config surface — per-project config introspection, coherence verification, and
audited mutation without destroying NCL structure (ADR-008):
- crates/ontoref-daemon/src/config.rs — typed DaemonNclConfig (parse-at-boundary
pattern); all section structs derive ConfigFields + config_section(id, ncl_file)
emitting inventory::submit!(ConfigFieldsEntry{...}) at link time
- crates/ontoref-derive/src/lib.rs — #[derive(ConfigFields)] proc-macro; serde
rename support; serde_rename_of() helper extracted to fix excessive_nesting
- crates/ontoref-daemon/src/main.rs — 3-tuple bootstrap block (nickel_import_path,
loaded_ncl_config: Option<DaemonNclConfig>, stdin_raw); apply_ui_config takes
&UiConfig; NATS call site typed; resolve_asset_dir cfg(feature = "ui")
- crates/ontoref-daemon/src/api.rs — config GET/PUT endpoints, quickref, coherence,
cross-project comparison; index_section_fields() extracted (excessive_nesting)
- crates/ontoref-daemon/src/config_coherence.rs — multi-consumer coherence;
merge_meta_into_section() extracted; and() replaces unnecessary and_then
NCL contracts for ontoref's own config:
- .ontoref/contracts.ncl — LogConfig (LogLevel, LogRotation, PositiveInt) and
DaemonConfig (Port, optional overrides); std.contract.from_validator throughout
- .ontoref/config.ncl — log | C.LogConfig applied
- .ontology/manifest.ncl — contracts_path, log/daemon contract refs, daemon section
with DaemonRuntimeConfig consumer and 7 declared fields
Protocol:
- adrs/adr-008-ncl-first-config-validation-and-override-layer.ncl — NCL contracts
as single validation gate; Rust structs are contract-trusted; override-layer
mutation writes {section}.overrides.ncl + _overrides_meta, never touches source
on+re update:
- .ontology/core.ncl — config-surface node (28 practices); adr-lifecycle extended
to adr-007 + adr-008; 6 new edges (ManifestsIn daemon, DependsOn ontology-crate,
Complements api-catalog-surface/dag-formalized/self-describing/adopt-ontoref)
- .ontology/state.ncl — protocol-maturity blocker and self-description-coverage
catalyst updated for session 2026-03-26
- README.md / CHANGELOG.md updated
2026-03-26 20:20:22 +00:00
|
|
|
# Configuration surface: where the project's NCL config lives, which
|
|
|
|
|
# consumers read each section, and mutation rules. Optional — projects
|
|
|
|
|
# without a structured config system omit this field.
|
|
|
|
|
config_surface | config_surface_type | optional,
|
2026-03-13 00:21:04 +00:00
|
|
|
} in
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
RepoKind = repo_kind_type,
|
|
|
|
|
ConsumerType = consumer_type,
|
|
|
|
|
ArtifactKind = artifact_kind_type,
|
|
|
|
|
AuditLevel = audit_level_type,
|
|
|
|
|
AuthMethod = auth_method_type,
|
|
|
|
|
ServiceScope = service_scope_type,
|
|
|
|
|
InstallMethod = install_method_type,
|
|
|
|
|
JustfileSystem = justfile_system_type,
|
|
|
|
|
Layer = layer_type,
|
|
|
|
|
OperationalMode = op_mode_type,
|
|
|
|
|
ConsumptionMode = consumption_mode_type,
|
|
|
|
|
PublicationService = publication_service_type,
|
|
|
|
|
ToolRequirement = tool_requirement_type,
|
|
|
|
|
JustfileConvention = justfile_convention_type,
|
|
|
|
|
ClaudeBaseline = claude_baseline_type,
|
|
|
|
|
ProjectManifest = manifest_type,
|
feat: config surface, NCL contracts, override-layer mutation, on+re update
Config surface — per-project config introspection, coherence verification, and
audited mutation without destroying NCL structure (ADR-008):
- crates/ontoref-daemon/src/config.rs — typed DaemonNclConfig (parse-at-boundary
pattern); all section structs derive ConfigFields + config_section(id, ncl_file)
emitting inventory::submit!(ConfigFieldsEntry{...}) at link time
- crates/ontoref-derive/src/lib.rs — #[derive(ConfigFields)] proc-macro; serde
rename support; serde_rename_of() helper extracted to fix excessive_nesting
- crates/ontoref-daemon/src/main.rs — 3-tuple bootstrap block (nickel_import_path,
loaded_ncl_config: Option<DaemonNclConfig>, stdin_raw); apply_ui_config takes
&UiConfig; NATS call site typed; resolve_asset_dir cfg(feature = "ui")
- crates/ontoref-daemon/src/api.rs — config GET/PUT endpoints, quickref, coherence,
cross-project comparison; index_section_fields() extracted (excessive_nesting)
- crates/ontoref-daemon/src/config_coherence.rs — multi-consumer coherence;
merge_meta_into_section() extracted; and() replaces unnecessary and_then
NCL contracts for ontoref's own config:
- .ontoref/contracts.ncl — LogConfig (LogLevel, LogRotation, PositiveInt) and
DaemonConfig (Port, optional overrides); std.contract.from_validator throughout
- .ontoref/config.ncl — log | C.LogConfig applied
- .ontology/manifest.ncl — contracts_path, log/daemon contract refs, daemon section
with DaemonRuntimeConfig consumer and 7 declared fields
Protocol:
- adrs/adr-008-ncl-first-config-validation-and-override-layer.ncl — NCL contracts
as single validation gate; Rust structs are contract-trusted; override-layer
mutation writes {section}.overrides.ncl + _overrides_meta, never touches source
on+re update:
- .ontology/core.ncl — config-surface node (28 practices); adr-lifecycle extended
to adr-007 + adr-008; 6 new edges (ManifestsIn daemon, DependsOn ontology-crate,
Complements api-catalog-surface/dag-formalized/self-describing/adopt-ontoref)
- .ontology/state.ncl — protocol-maturity blocker and self-description-coverage
catalyst updated for session 2026-03-26
- README.md / CHANGELOG.md updated
2026-03-26 20:20:22 +00:00
|
|
|
ConfigKind = config_kind_type,
|
|
|
|
|
ConsumerKind = consumer_kind_type,
|
|
|
|
|
ConfigConsumer = config_consumer_type,
|
|
|
|
|
ConfigSection = config_section_type,
|
|
|
|
|
ConfigSurface = config_surface_type,
|
2026-03-13 00:21:04 +00:00
|
|
|
}
|