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
249 lines
10 KiB
Plaintext
249 lines
10 KiB
Plaintext
let m = import "../ontology/defaults/manifest.ncl" in
|
|
|
|
m.make_manifest {
|
|
project = "ontoref",
|
|
repo_kind = 'DevWorkspace,
|
|
|
|
content_assets = [
|
|
m.make_asset {
|
|
id = "logo-horizontal",
|
|
kind = 'Logo,
|
|
source_path = "assets/branding/ontoref-h.svg",
|
|
variants = ["assets/branding/ontoref-h-static.svg", "assets/branding/ontoref-dark-h.svg", "assets/branding/ontoref-mono-black-h.svg", "assets/branding/ontoref-mono-white-h.svg"],
|
|
description = "Primary horizontal logo — animated SVG with static and dark/mono variants.",
|
|
},
|
|
m.make_asset {
|
|
id = "logo-vertical",
|
|
kind = 'Logo,
|
|
source_path = "assets/branding/ontoref-v.svg",
|
|
variants = ["assets/branding/ontoref-v-static.svg", "assets/branding/ontoref-dark-v.svg", "assets/branding/ontoref-mono-black-v.svg", "assets/branding/ontoref-mono-white-v.svg"],
|
|
description = "Vertical logo — animated SVG with static and dark/mono variants.",
|
|
},
|
|
m.make_asset {
|
|
id = "logo-icon",
|
|
kind = 'Icon,
|
|
source_path = "assets/branding/ontoref-icon.svg",
|
|
variants = ["assets/branding/ontoref-icon-static.svg"],
|
|
description = "Square icon mark — animated and static variants.",
|
|
},
|
|
m.make_asset {
|
|
id = "logo-text",
|
|
kind = 'Logo,
|
|
source_path = "assets/branding/ontoref-text.svg",
|
|
description = "Logotype text-only mark.",
|
|
},
|
|
m.make_asset {
|
|
id = "logo-pakua",
|
|
kind = 'Logo,
|
|
source_path = "assets/branding/pakua/ontoref_pakua_img.svg",
|
|
variants = ["assets/branding/pakua/ontoref-pakua-dark-v.svg"],
|
|
description = "Pakua symbol variant of the logo.",
|
|
},
|
|
m.make_asset {
|
|
id = "diagram-architecture",
|
|
kind = 'Diagram,
|
|
source_path = "assets/architecture.svg",
|
|
description = "Current architecture diagram showing the three-layer protocol model.",
|
|
},
|
|
m.make_asset {
|
|
id = "screenshot-graph-dark",
|
|
kind = 'Screenshot,
|
|
source_path = "assets/ontoref_graph_view-dark.png",
|
|
variants = ["assets/ontoref_graph_view-light.png"],
|
|
description = "Graph view UI screenshot — dark and light variants.",
|
|
},
|
|
m.make_asset {
|
|
id = "presentation-deck",
|
|
kind = 'Document,
|
|
source_path = "assets/presentation/slides.md",
|
|
description = "Slidev presentation deck for ontoref protocol introduction.",
|
|
},
|
|
],
|
|
|
|
consumption_modes = [
|
|
m.make_consumption_mode {
|
|
consumer = 'Developer,
|
|
needs = ['OntologyExport],
|
|
audit_level = 'Standard,
|
|
description = "Clones repo, runs ./ontoref, imports Nushell modules. Uses reflection tooling to manage project self-description.",
|
|
},
|
|
m.make_consumption_mode {
|
|
consumer = 'Agent,
|
|
needs = ['OntologyExport, 'JsonSchema],
|
|
audit_level = 'Quick,
|
|
description = "Reads .ontology/core.ncl via nickel export. Queries nodes, edges, and ADRs to understand project constraints before acting.",
|
|
},
|
|
],
|
|
|
|
config_surface = m.make_config_surface {
|
|
config_root = ".ontoref",
|
|
entry_point = "config.ncl",
|
|
kind = 'SingleFile,
|
|
contracts_path = ".ontoref",
|
|
|
|
sections = [
|
|
m.make_config_section {
|
|
id = "nickel_import_paths",
|
|
file = "config.ncl",
|
|
description = "Ordered list of directories added to NICKEL_IMPORT_PATH when invoking nickel.",
|
|
rationale = "Ontoref resolves ontology schemas, ADRs, and reflection schemas through this path list. Order matters: earlier entries shadow later ones.",
|
|
mutable = true,
|
|
consumers = [
|
|
m.make_config_consumer {
|
|
id = "env",
|
|
kind = 'NuScript,
|
|
ref = "reflection/modules/env.nu",
|
|
fields = ["nickel_import_paths"],
|
|
},
|
|
m.make_config_consumer {
|
|
id = "daemon-main",
|
|
kind = 'RustStruct,
|
|
ref = "crates/ontoref-daemon/src/main.rs",
|
|
fields = ["nickel_import_paths"],
|
|
},
|
|
],
|
|
},
|
|
m.make_config_section {
|
|
id = "ui",
|
|
file = "config.ncl",
|
|
description = "Daemon HTTP/UI settings: template directory, static assets, TLS certs, logo override.",
|
|
rationale = "Allows dev-mode templates to be served from the source tree instead of the installed path, and TLS to be toggled without recompiling.",
|
|
mutable = true,
|
|
consumers = [
|
|
m.make_config_consumer {
|
|
id = "daemon-main",
|
|
kind = 'RustStruct,
|
|
ref = "crates/ontoref-daemon/src/main.rs",
|
|
fields = ["templates_dir", "public_dir", "tls_cert", "tls_key", "logo"],
|
|
},
|
|
],
|
|
},
|
|
m.make_config_section {
|
|
id = "log",
|
|
file = "config.ncl",
|
|
contract = "contracts.ncl → LogConfig",
|
|
description = "Daemon structured logging: level, rotation policy, archive and retention.",
|
|
rationale = "Daily rotation with 7-file retention keeps log footprint bounded; separate archive path allows cold storage without disrupting active logs.",
|
|
mutable = true,
|
|
consumers = [
|
|
m.make_config_consumer {
|
|
id = "daemon-main",
|
|
kind = 'RustStruct,
|
|
ref = "crates/ontoref-daemon/src/main.rs",
|
|
fields = ["level", "path", "rotation", "compress", "archive", "max_files"],
|
|
},
|
|
],
|
|
},
|
|
m.make_config_section {
|
|
id = "mode_run",
|
|
file = "config.ncl",
|
|
description = "ACL rules for which actors may execute which reflection modes.",
|
|
rationale = "Agent and CI actors need unrestricted mode access; human actors are gated per mode to prevent accidental destructive operations.",
|
|
mutable = true,
|
|
consumers = [
|
|
m.make_config_consumer {
|
|
id = "daemon-main",
|
|
kind = 'RustStruct,
|
|
ref = "crates/ontoref-daemon/src/main.rs",
|
|
fields = ["rules"],
|
|
},
|
|
],
|
|
},
|
|
m.make_config_section {
|
|
id = "nats_events",
|
|
file = "config.ncl",
|
|
description = "NATS event bus integration: enabled flag, server URL, emit/subscribe topic lists, handlers directory.",
|
|
rationale = "Disabled by default to keep ontoref zero-dependency for projects without a NATS deployment. Feature-gated in the daemon crate.",
|
|
mutable = true,
|
|
consumers = [
|
|
m.make_config_consumer {
|
|
id = "daemon-main",
|
|
kind = 'RustStruct,
|
|
ref = "crates/ontoref-daemon/src/main.rs",
|
|
fields = ["enabled", "url", "emit", "subscribe", "handlers_dir"],
|
|
},
|
|
],
|
|
},
|
|
m.make_config_section {
|
|
id = "actor_init",
|
|
file = "config.ncl",
|
|
description = "Per-actor bootstrap: which reflection mode to auto-run on first invocation.",
|
|
rationale = "Agents always auto-run 'describe capabilities' so they orient themselves before acting; developers and CI start clean.",
|
|
mutable = true,
|
|
consumers = [
|
|
m.make_config_consumer {
|
|
id = "env",
|
|
kind = 'NuScript,
|
|
ref = "reflection/modules/env.nu",
|
|
fields = ["actor", "mode", "auto_run"],
|
|
},
|
|
],
|
|
},
|
|
m.make_config_section {
|
|
id = "quick_actions",
|
|
file = "config.ncl",
|
|
description = "Shortcut actions surfaced in the daemon UI dashboard: id, label, icon, category, mode, allowed actors.",
|
|
rationale = "Frequently used modes (generate-mdbook, sync-ontology, coder-workflow) promoted to one-click access without navigating the modes list.",
|
|
mutable = true,
|
|
consumers = [
|
|
m.make_config_consumer {
|
|
id = "daemon-ui",
|
|
kind = 'RustStruct,
|
|
ref = "crates/ontoref-daemon/src/ui/handlers.rs",
|
|
fields = ["id", "label", "icon", "category", "mode", "actors"],
|
|
},
|
|
],
|
|
},
|
|
m.make_config_section {
|
|
id = "daemon",
|
|
file = "config.ncl",
|
|
contract = "contracts.ncl → DaemonConfig",
|
|
description = "Runtime overrides for daemon CLI defaults: port, timeouts, sweep intervals, notification limits.",
|
|
rationale = "All fields are optional — absent fields use the daemon's built-in CLI defaults. Set only when the defaults need project-specific tuning without rebuilding the binary.",
|
|
mutable = true,
|
|
consumers = [
|
|
m.make_config_consumer {
|
|
id = "daemon-config",
|
|
kind = 'RustStruct,
|
|
ref = "crates/ontoref-daemon/src/config.rs → DaemonRuntimeConfig",
|
|
fields = ["port", "idle_timeout", "invalidation_interval", "actor_sweep_interval", "actor_stale_timeout", "max_notifications", "notification_ack_required"],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
|
|
layers = [
|
|
m.make_layer {
|
|
id = "protocol",
|
|
paths = ["ontology/", "adrs/", "reflection/schemas/"],
|
|
committed = true,
|
|
description = "Protocol specification: Nickel schemas, ADR tooling, and reflection schemas. The contract layer that projects implement.",
|
|
},
|
|
m.make_layer {
|
|
id = "tooling",
|
|
paths = ["reflection/", "install/", "nats/", "templates/", "ontoref"],
|
|
committed = true,
|
|
description = "Operational tooling: Nushell modules, modes, forms, dispatcher, bash entry point, install scripts, default config resources, and NATS stream topology.",
|
|
},
|
|
m.make_layer {
|
|
id = "crates",
|
|
paths = ["crates/", "Cargo.toml"],
|
|
committed = true,
|
|
description = "Rust implementation: ontoref-ontology (load/query .ontology/ as typed structs) and ontoref-reflection (execute reflection modes against project state).",
|
|
},
|
|
m.make_layer {
|
|
id = "self-description",
|
|
paths = [".ontology/"],
|
|
committed = true,
|
|
description = "Ontoref consuming ontoref: the project's own ontology, state, gate, and manifest.",
|
|
},
|
|
m.make_layer {
|
|
id = "process",
|
|
paths = [".coder/"],
|
|
committed = false,
|
|
description = "Session artifacts: plans, investigations, summaries. Process memory for actors.",
|
|
},
|
|
],
|
|
}
|