ontoref/.ontology/core.ncl

428 lines
25 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

let d = import "../ontology/defaults/core.ncl" in
{
nodes = [
# ── Axioms (invariant = true) ─────────────────────────────────────────────
d.make_node {
id = "protocol-not-runtime",
name = "Protocol, Not Runtime",
pole = 'Yang,
level = 'Axiom,
description = "Onref is a protocol specification and tooling layer. It is never a runtime dependency. Projects implement the protocol; onref provides the schemas and modules to do so.",
invariant = true,
},
d.make_node {
id = "self-describing",
name = "Self-Describing",
pole = 'Yang,
level = 'Axiom,
description = "Onref describes itself using its own protocol. The .ontology/, adrs/, and reflection/ directories in this repository are onref consuming ontoref.",
invariant = true,
artifact_paths = [".ontology/core.ncl", ".ontology/state.ncl", "adrs/"],
},
d.make_node {
id = "no-enforcement",
name = "No Enforcement",
pole = 'Yang,
level = 'Axiom,
description = "Onref defines contracts and patterns. There is no enforcement mechanism. Coherence is voluntary and emerges from justified adoption.",
invariant = true,
},
d.make_node {
id = "dag-formalized",
name = "DAG-Formalized Knowledge",
pole = 'Yin,
level = 'Axiom,
description = "All project knowledge — concepts, tensions, decisions, state — is formalized as directed acyclic graphs. This enables transversal queries, impact analysis, and ecosystem-level visibility.",
invariant = true,
artifact_paths = ["ontology/schemas/", "crates/ontoref-ontology/"],
},
# ── Tensions ──────────────────────────────────────────────────────────────
d.make_node {
id = "formalization-vs-adoption",
name = "Formalization vs Adoption Friction",
pole = 'Spiral,
level = 'Tension,
description = "Richer formalization produces better ecosystem visibility but increases the cost of adoption. The balance: schemas are optional layers, not mandatory gates.",
},
d.make_node {
id = "ontology-vs-reflection",
name = "Ontology vs Reflection",
pole = 'Spiral,
level = 'Tension,
description = "Ontology captures what IS (invariants, structure, being). Reflection captures what BECOMES (operations, drift, memory). Both must coexist without one dominating. This tension is onref's core identity.",
},
# ── Practices ─────────────────────────────────────────────────────────────
d.make_node {
id = "adr-lifecycle",
name = "ADR Lifecycle",
pole = 'Yang,
level = 'Practice,
description = "Architectural decisions follow: Proposed → Accepted → Superseded. Superseded ADRs retain constraints for historical reconstruction. Active Hard constraints drive the constraint set. Nodes declare which ADRs validate them via the adrs field — surfaced by describe and the daemon graph UI.",
artifact_paths = [
"adrs/schema.ncl",
"adrs/reflection.ncl",
"adrs/_template.ncl",
"adrs/adr-001-protocol-as-standalone-project.ncl",
"adrs/adr-002-daemon-for-caching-and-notification-barrier.ncl",
"adrs/adr-003-qa-and-knowledge-persistence-as-ncl.ncl",
"adrs/adr-004-ncl-pipe-bootstrap-pattern.ncl",
"adrs/adr-005-unified-auth-session-model.ncl",
"adrs/adr-006-nushell-0111-string-interpolation-compat.ncl",
"CHANGELOG.md",
],
adrs = ["adr-001", "adr-002", "adr-003", "adr-004", "adr-005", "adr-006"],
},
d.make_node {
id = "reflection-modes",
name = "Reflection Modes",
pole = 'Yang,
level = 'Practice,
description = "Operational procedures are first-class artifacts encoded as NCL DAG contracts. Modes declare actors, steps, dependencies, and error strategies — not prose.",
artifact_paths = ["reflection/modes/", "reflection/schemas/", "crates/ontoref-reflection/"],
},
d.make_node {
id = "coder-process-memory",
name = "Coder Process Memory",
pole = 'Yin,
level = 'Practice,
description = "Session knowledge is captured as structured JSONL via coder record. Queryable, exportable, and promotable to reflection/knowledge/. The memory layer between sessions.",
artifact_paths = ["reflection/modules/coder.nu", "reflection/schemas/coder.ncl"],
},
d.make_node {
id = "describe-query-layer",
name = "Describe Query Layer",
pole = 'Yang,
level = 'Practice,
description = "describe.nu aggregates all project sources and answers self-knowledge queries: what IS this, what can I DO, what can I NOT do, what tools exist, what is the impact of changing X. Renders Validated by section when a node declares adrs — surfacing declared ADR constraints alongside source, examples, and connections.",
artifact_paths = ["reflection/modules/describe.nu"],
},
d.make_node {
id = "ontoref-ontology-crate",
name = "Ontoref Ontology Crate",
pole = 'Yang,
level = 'Practice,
description = "Rust implementation for loading and querying .ontology/ NCL files as typed structs. Provides Core, Gate, and State types for ecosystem-level introspection. Node carries artifact_paths (Vec<String>) and adrs (Vec<String>) — both serde(default) for zero-migration backward compatibility.",
artifact_paths = ["crates/ontoref-ontology/"],
adrs = ["adr-001"],
},
d.make_node {
id = "ontoref-reflection-crate",
name = "Ontoref Reflection Crate",
pole = 'Yang,
level = 'Practice,
description = "Rust implementation for loading, validating, and executing Reflection modes as NCL DAG contracts against project state.",
artifact_paths = ["crates/ontoref-reflection/"],
},
d.make_node {
id = "adopt-ontoref-tooling",
name = "Adopt Ontoref Tooling",
pole = 'Yang,
level = 'Practice,
description = "Migration system for onboarding existing projects into the ontoref protocol. Provides .ontology/ stub templates, .ontoref/config.ncl template, scripts/ontoref thin wrapper, and the adopt_ontoref mode+form+script that wire everything up idempotently.",
artifact_paths = [
"ontoref",
"justfile",
"justfiles/ci.just",
"templates/ontology/",
"templates/ontoref-config.ncl",
"templates/scripts-ontoref",
"reflection/modes/adopt_ontoref.ncl",
"reflection/forms/adopt_ontoref.ncl",
"reflection/templates/adopt_ontoref.nu.j2",
],
},
d.make_node {
id = "ontology-three-file-split",
name = "Ontology Three-File Split",
pole = 'Yang,
level = 'Practice,
description = "The .ontology/ directory separates three orthogonal concerns into three files. core.ncl captures what the project IS — invariant axioms and structural tensions; touching invariant=true nodes requires a new ADR. state.ncl captures where it IS vs where it wants to BE — current and desired state per dimension. gate.ncl defines when it is READY to cross a boundary — active membranes protecting key conditions. reflection/ reads all three and answers self-knowledge queries. This separation lets an agent understand a project without reading code — only by consulting the declarative graph.",
invariant = false,
artifact_paths = [".ontology/core.ncl", ".ontology/state.ncl", ".ontology/gate.ncl"],
},
d.make_node {
id = "adr-node-linkage",
name = "ADRNode Declared Linkage",
pole = 'Yang,
level = 'Practice,
description = "Nodes declare which ADRs validate them via the adrs field (Array String). This makes the ADR→Node relationship explicit in the graph rather than implicit in prose. describe surfaces a Validated by section per node. The daemon graph UI renders each ADR as a clickable link opening the full ADR via GET /api/adr/{id}. Field is serde(default) and Nickel default=[] — zero migration cost for existing nodes.",
artifact_paths = [
"ontology/schemas/core.ncl",
"crates/ontoref-ontology/src/types.rs",
"reflection/modules/describe.nu",
"crates/ontoref-daemon/templates/pages/graph.html",
"crates/ontoref-daemon/src/api.rs",
],
},
d.make_node {
id = "web-presence",
name = "Web Presence",
pole = 'Yang,
level = 'Practice,
description = "Landing page at assets/web/ describing the ontoref protocol to external audiences. Bilingual (EN/ES), covers protocol layers, yin/yang duality, crates, and adoption path. Self-description artifact.",
artifact_paths = ["assets/web/src/index.html", "assets/web/index.html", "README.md", "assets/architecture.svg"],
},
d.make_node {
id = "ontoref-daemon",
name = "Ontoref Daemon",
pole = 'Yang,
level = 'Practice,
description = "Runtime support daemon for the ontoref protocol. Provides NCL export caching, file watching, actor registry, notification barrier, HTTP API, MCP server (stdio + streamable-HTTP), Q&A NCL persistence, quick-actions catalog, passive drift observation, and unified auth/session management (key exchange, Bearer tokens, per-project and daemon-level admin, session list/revoke). Launched via ADR-004 NCL pipe bootstrap: nickel export config.ncl | ontoref-daemon.bin --config-stdin. Binary installed as ontoref-daemon.bin; bootstrapper as ontoref-daemon.",
invariant = false,
artifact_paths = [
"crates/ontoref-daemon/",
"install/ontoref-daemon-boot",
"install/install.nu",
"nats/streams.json",
"reflection/modules/services.nu",
"crates/ontoref-daemon/src/ui/qa_ncl.rs",
"crates/ontoref-daemon/src/ui/drift_watcher.rs",
"crates/ontoref-daemon/src/mcp/mod.rs",
"crates/ontoref-daemon/src/session.rs",
"crates/ontoref-daemon/src/ui/auth.rs",
"crates/ontoref-daemon/src/ui/login.rs",
"crates/ontoref-daemon/src/ui/search_bookmarks_ncl.rs",
"justfiles/ci.just",
],
},
d.make_node {
id = "unified-auth-model",
name = "Unified Auth Model",
pole = 'Yang,
level = 'Practice,
description = "All surfaces (CLI, UI, MCP) exchange a raw key for a UUID v4 session token via POST /sessions (30-day lifetime, O(1) lookup vs O(~100ms) argon2 per request). Project keys carry role (admin|viewer) and label for audit trail. Daemon admin sessions use virtual slug '_daemon'. ONTOREF_TOKEN injected as Bearer by CLI automatically. Sessions have a stable public id (distinct from bearer token) for safe list/revoke operations. Key rotation revokes all sessions for the rotated project.",
invariant = false,
artifact_paths = [
"crates/ontoref-daemon/src/session.rs",
"crates/ontoref-daemon/src/api.rs",
"crates/ontoref-daemon/src/registry.rs",
"crates/ontoref-daemon/src/ui/login.rs",
"crates/ontoref-daemon/src/ui/auth.rs",
"reflection/modules/store.nu",
"install/resources/schemas/ontoref-project.ncl",
],
},
d.make_node {
id = "project-onboarding",
name = "Project Onboarding",
pole = 'Yang,
level = 'Practice,
description = "Idempotent onboarding via `ontoref setup`. Creates .ontoref/project.ncl, .ontoref/config.ncl (with logo auto-detection in assets/), .ontology/ scaffold, adrs/, reflection/modes/, backlog.ncl, qa.ncl, git hooks, and registers in projects.ncl. Supports --kind (repo_kind) and --parent (framework layers + browse modes for implementation children). Bootstrap key generation via --gen-keys ['admin:label' 'viewer:label']: idempotent (no-op if keys exist), hashes via daemon binary, prints passwords once.",
invariant = false,
artifact_paths = [
"reflection/bin/ontoref.nu",
"templates/project.ncl",
"templates/ontoref-config.ncl",
"templates/ontology/",
"install/gen-projects.nu",
"install/resources/schemas/ontoref-project.ncl",
],
},
d.make_node {
id = "daemon-config-management",
name = "Daemon Config Management",
pole = 'Yang,
level = 'Practice,
description = "Install and configuration infrastructure for ontoref-daemon. Global config at ~/.config/ontoref/config.ncl (Nickel, type-checked). Browser-based editing via typedialog roundtrip: form (config.ncl) → browser → Tera template (config.ncl.j2) → updated config.ncl. CI guard (check-config-sync.nu) enforces form/template parity on every commit. Global NATS topology at ~/.config/ontoref/streams.json; project-local override via nats/streams.json and NATS_STREAMS_CONFIG env var. Config validation + liveness probes via config-setup.nu.",
invariant = false,
artifact_paths = [
"install/resources/config.ncl",
"install/resources/streams.json",
"install/config-setup.nu",
"install/check-config-sync.nu",
"reflection/forms/config.ncl",
"reflection/forms/config.ncl.j2",
"reflection/nulib/bootstrap.nu",
],
},
d.make_node {
id = "qa-knowledge-store",
name = "Q&A Knowledge Store",
pole = 'Yin,
level = 'Practice,
description = "Accumulated Q&A entries persisted as NCL — questions and answers captured during development sessions, AI interactions, and architectural reviews. Git-versioned, typed by QaEntry schema, queryable via MCP (ontoref_qa_list/add) and HTTP (/qa-json). Bridges session boundaries: knowledge is never lost between actor sessions.",
artifact_paths = [
"reflection/qa.ncl",
"reflection/schemas/qa.ncl",
"crates/ontoref-daemon/src/ui/qa_ncl.rs",
],
},
d.make_node {
id = "quick-actions",
name = "Quick Actions Catalog",
pole = 'Yang,
level = 'Practice,
description = "Runnable shortcuts over existing reflection modes. Configured as quick_actions in .ontoref/config.ncl (id, label, icon, category, mode, actors). Accessible from UI (/actions), CLI (./ontoref), and MCP (ontoref_action_list/add). New modes created via ontoref_action_add are immediately available as actions. Reduces friction between knowing a mode exists and executing it.",
artifact_paths = [
".ontoref/config.ncl",
"crates/ontoref-daemon/templates/pages/actions.html",
"reflection/modes/",
],
},
d.make_node {
id = "personal-ontology-schemas",
name = "Personal Ontology Schemas",
pole = 'Yin,
level = 'Practice,
description = "Typed NCL schema layer for personal and career artifacts: career.ncl (Skills, WorkExperience, Talks, Positioning, CompanyTargets, PublicationCards), personal.ncl (Content and Opportunity lifecycle — BlogPost to CV to Application, Job to Conference to Grant), project-card.ncl (canonical display metadata for portfolio and cv_repo publication). All types carry linked_nodes referencing .ontology/core.ncl node IDs — bridging career artifacts into the DAG.",
invariant = false,
artifact_paths = [
"ontology/schemas/career.ncl",
"ontology/schemas/personal.ncl",
"ontology/schemas/project-card.ncl",
"ontology/defaults/career.ncl",
"ontology/defaults/personal.ncl",
"ontology/defaults/project-card.ncl",
],
},
d.make_node {
id = "content-modes",
name = "Content & Career Reflection Modes",
pole = 'Yang,
level = 'Practice,
description = "NCL DAG modes for personal content and career operations: draft-application (job/grant/collaboration application anchored in personal ontology — gate alignment check, node selection, career trajectory render), draft-email, generate-article, update-cv, write-cfp. Each mode queries personal.ncl and core.ncl nodes to ground output in declared project artifacts rather than free-form prose.",
invariant = false,
artifact_paths = [
"reflection/modes/draft-application.ncl",
"reflection/modes/draft-email.ncl",
"reflection/modes/generate-article.ncl",
"reflection/modes/update-cv.ncl",
"reflection/modes/write-cfp.ncl",
],
},
d.make_node {
id = "search-bookmarks",
name = "Search Bookmarks",
pole = 'Yin,
level = 'Practice,
description = "Persistent bookmark store for search results over the ontology graph. Entries typed as BookmarkEntry (id, node_id, kind, title, level, term, actor, created_at, tags) and persisted to reflection/search_bookmarks.ncl via line-level NCL surgery — same atomic-write pattern as qa_ncl.rs. IDs are sequential sb-NNN, zero-padded. Concurrency-safe via NclWriteLock. Supports add and remove; accessible from the daemon search UI.",
invariant = false,
artifact_paths = [
"reflection/search_bookmarks.ncl",
"reflection/schemas/search_bookmarks.ncl",
"crates/ontoref-daemon/src/ui/search_bookmarks_ncl.rs",
],
},
d.make_node {
id = "drift-observation",
name = "Passive Drift Observation",
pole = 'Spiral,
level = 'Practice,
description = "Background observer that bridges Yang code artifacts with Yin ontology declarations. Watches crates/, .ontology/, adrs/, reflection/modes/ for changes; after a debounce window runs sync scan + sync diff; if MISSING/STALE/DRIFT/BROKEN items are found emits an ontology_drift notification. Never applies changes automatically — apply remains a deliberate human or agent act.",
artifact_paths = [
"crates/ontoref-daemon/src/ui/drift_watcher.rs",
"reflection/modes/sync-ontology.ncl",
],
},
],
edges = [
{ from = "self-describing", to = "dag-formalized", kind = 'ManifestsIn, weight = 'High },
{ from = "self-describing", to = "adr-lifecycle", kind = 'ManifestsIn, weight = 'High },
{ from = "self-describing", to = "reflection-modes", kind = 'ManifestsIn, weight = 'High },
{ from = "ontology-vs-reflection", to = "dag-formalized", kind = 'Resolves, weight = 'High },
{ from = "ontology-vs-reflection", to = "coder-process-memory", kind = 'Resolves, weight = 'Medium },
{ from = "dag-formalized", to = "ontoref-ontology-crate", kind = 'ManifestsIn, weight = 'High },
{ from = "reflection-modes", to = "ontoref-reflection-crate", kind = 'ManifestsIn, weight = 'High },
{ from = "no-enforcement", to = "formalization-vs-adoption", kind = 'Resolves, weight = 'Medium },
{ from = "protocol-not-runtime", to = "no-enforcement", kind = 'Implies, weight = 'High },
{ from = "adr-lifecycle", to = "reflection-modes", kind = 'Complements, weight = 'Medium },
{ from = "adr-node-linkage", to = "adr-lifecycle", kind = 'ManifestsIn, weight = 'High },
{ from = "adr-node-linkage", to = "describe-query-layer", kind = 'Complements, weight = 'High },
{ from = "describe-query-layer", to = "dag-formalized", kind = 'DependsOn, weight = 'High },
{ from = "coder-process-memory", to = "describe-query-layer", kind = 'Complements, weight = 'Medium },
{ from = "ontoref-daemon", to = "ontoref-ontology-crate", kind = 'Complements, weight = 'High },
{ from = "ontoref-daemon", to = "reflection-modes", kind = 'Complements, weight = 'Medium },
{ from = "protocol-not-runtime", to = "ontoref-daemon", kind = 'Contradicts, weight = 'Low,
note = "Daemon is optional runtime support, not a protocol requirement. Protocol functions without it." },
{ from = "no-enforcement", to = "adopt-ontoref-tooling", kind = 'ManifestsIn, weight = 'High,
note = "Adoption is voluntary — the tooling makes it easy but never mandatory." },
{ from = "adopt-ontoref-tooling", to = "reflection-modes", kind = 'DependsOn, weight = 'High },
{ from = "self-describing", to = "web-presence", kind = 'ManifestsIn, weight = 'Medium },
{ from = "web-presence", to = "adopt-ontoref-tooling", kind = 'Complements, weight = 'Medium },
# Q&A Knowledge Store edges
{ from = "qa-knowledge-store", to = "dag-formalized", kind = 'ManifestsIn, weight = 'High,
note = "Q&A entries are typed NCL records, git-versioned — knowledge as DAG." },
{ from = "qa-knowledge-store", to = "coder-process-memory", kind = 'Complements, weight = 'High,
note = "Q&A is the persistent layer; coder.nu is the session capture layer. Together they form the full memory stack." },
{ from = "ontoref-daemon", to = "qa-knowledge-store", kind = 'Contains, weight = 'High },
{ from = "daemon-config-management", to = "ontoref-daemon", kind = 'DependsOn, weight = 'High },
{ from = "daemon-config-management", to = "adopt-ontoref-tooling", kind = 'Complements, weight = 'Medium,
note = "Config management is part of the adoption surface — new projects get config.ncl and streams.json during install." },
# Quick Actions edges
{ from = "quick-actions", to = "reflection-modes", kind = 'DependsOn, weight = 'High,
note = "Each quick action invokes a reflection mode by id." },
{ from = "quick-actions", to = "ontoref-daemon", kind = 'ManifestsIn, weight = 'Medium },
{ from = "describe-query-layer", to = "quick-actions", kind = 'Complements, weight = 'Medium,
note = "describe capabilities lists available modes; quick-actions makes them executable." },
# Drift Observation edges
{ from = "drift-observation", to = "ontoref-daemon", kind = 'ManifestsIn, weight = 'High },
{ from = "drift-observation", to = "ontology-vs-reflection", kind = 'Resolves, weight = 'Medium,
note = "Drift observer continuously monitors the gap between Yin (ontology) and Yang (code). Passive resolution — it signals drift without forcing resolution." },
{ from = "drift-observation", to = "reflection-modes", kind = 'DependsOn, weight = 'High,
note = "Invokes sync-ontology mode steps (scan, diff) as read-only sub-processes." },
# Personal Ontology Schemas edges
{ from = "personal-ontology-schemas", to = "dag-formalized", kind = 'ManifestsIn, weight = 'High,
note = "Career and personal artifacts are typed NCL records with linked_nodes — DAG connections into the core ontology." },
{ from = "personal-ontology-schemas", to = "self-describing", kind = 'Complements, weight = 'Medium,
note = "Personal/career schemas let projects describe not just what they ARE but who built them and for what trajectory." },
{ from = "content-modes", to = "reflection-modes", kind = 'ManifestsIn, weight = 'High },
{ from = "content-modes", to = "personal-ontology-schemas", kind = 'DependsOn, weight = 'High,
note = "Content and career modes query personal.ncl and core.ncl to ground output in declared artifacts." },
{ from = "search-bookmarks", to = "qa-knowledge-store", kind = 'Complements, weight = 'High,
note = "Both are NCL persistence layers using the same atomic-write surgery pattern. Q&A is for accumulated knowledge; bookmarks are for search navigation state." },
{ from = "search-bookmarks", to = "ontoref-daemon", kind = 'ManifestsIn, weight = 'High },
{ from = "ontoref-daemon", to = "search-bookmarks", kind = 'Contains, weight = 'High },
# Unified Auth Model edges
{ from = "unified-auth-model", to = "ontoref-daemon", kind = 'ManifestsIn, weight = 'High },
{ from = "unified-auth-model", to = "no-enforcement", kind = 'Contradicts, weight = 'Low,
note = "Auth is opt-in per project (no keys = open deployment). When keys are configured enforcement is real, but the protocol itself never mandates it." },
{ from = "ontoref-daemon", to = "unified-auth-model", kind = 'Contains, weight = 'High },
# Project Onboarding edges
{ from = "project-onboarding", to = "adopt-ontoref-tooling", kind = 'Complements, weight = 'High,
note = "adopt-ontoref-tooling is the migration surface for existing projects; project-onboarding is the first-class setup for new projects." },
{ from = "project-onboarding", to = "unified-auth-model", kind = 'DependsOn, weight = 'Medium,
note = "--gen-keys bootstraps the first keys into project.ncl during setup." },
{ from = "project-onboarding", to = "daemon-config-management", kind = 'DependsOn, weight = 'Medium },
],
}