commit 77373f5859d48ecbb29c223e361ab68902e600ce Author: Jesús Pérez Date: Thu Mar 12 23:59:21 2026 +0000 init repo diff --git a/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc new file mode 100644 index 0000000..0488308 --- /dev/null +++ b/.markdownlint-cli2.jsonc @@ -0,0 +1,119 @@ +// Markdownlint-cli2 Configuration +// Documentation quality enforcement for technical projects +// See: https://github.com/DavidAnson/markdownlint-cli2 +// Generated by dev-system/ci + +{ + "config": { + "default": true, + + // Headings - enforce proper hierarchy + "MD001": false, // heading-increment (relaxed - allow flexibility) + "MD026": { "punctuation": ".,;:!?" }, // heading-punctuation + + // Lists - enforce consistency + "MD004": { "style": "consistent" }, // ul-style (consistent list markers) + "MD005": false, // inconsistent-indentation (relaxed) + "MD007": { "indent": 2 }, // ul-indent + "MD029": false, // ol-prefix (allow flexible list numbering) + "MD030": { "ul_single": 1, "ol_single": 1, "ul_multi": 1, "ol_multi": 1 }, + + // Code blocks - fenced only + "MD046": { "style": "fenced" }, // code-block-style + + // CRITICAL: MD040 only checks opening fences, NOT closing fences + // It does NOT catch malformed closing fences with language specifiers (e.g., ```plaintext) + // CommonMark spec requires closing fences to be ``` only (no language) + // Use separate validation script to check closing fences + "MD040": true, // fenced-code-language (relaxed - flexible language specifiers) + + // Formatting - strict whitespace + "MD009": true, // no-hard-tabs + "MD010": true, // hard-tabs + "MD011": true, // reversed-link-syntax + "MD018": true, // no-missing-space-atx + "MD019": true, // no-multiple-space-atx + "MD020": true, // no-missing-space-closed-atx + "MD021": true, // no-multiple-space-closed-atx + "MD023": true, // heading-starts-line + "MD027": true, // no-multiple-spaces-blockquote + "MD031": false, // blanks-around-fences (relaxed - flexible spacing around code blocks) + "MD037": true, // no-space-in-emphasis + "MD039": true, // no-space-in-links + + // Trailing content + "MD012": false, // no-multiple-blanks (relaxed - allow formatting space) + "MD024": false, // no-duplicate-heading (too strict for docs) + "MD028": false, // no-blanks-blockquote (relaxed) + "MD047": true, // single-trailing-newline + + // Links and references + "MD034": true, // no-bare-urls (links must be formatted) + "MD042": true, // no-empty-links + + // HTML - allow for documentation formatting and images + "MD033": { "allowed_elements": ["br", "hr", "details", "summary", "p", "img", "div"] }, + + // Line length - relaxed for technical documentation + "MD013": { + "line_length": 150, + "heading_line_length": 150, + "code_block_line_length": 150, + "code_blocks": true, + "tables": false, + "headers": true, + "headers_line_length": 150, + "strict": false, + "stern": false + }, + + // Images + "MD045": true, // image-alt-text + + // Tables - enforce proper formatting + "MD060": false, // table-column-style (relaxed - flexible table spacing) + + // Disable rules that conflict with relaxed style + "MD003": false, // consistent-indentation + "MD041": false, // first-line-heading + "MD025": false, // single-h1 / multiple-top-level-headings + "MD022": false, // blanks-around-headings (flexible spacing) + "MD032": false, // blanks-around-lists (flexible spacing) + "MD035": false, // hr-style (consistent) + "MD036": false, // no-emphasis-as-heading + "MD044": false // proper-names + }, + + // Documentation patterns + "globs": [ + "**/*.md", + "!node_modules/**", + "!target/**", + "!.git/**", + "!build/**", + "!dist/**", + "!.typedialog/**", + "!.woodpecker/**", + "!assets/branding/**", + "!assets/logo_prompt.md" + ], + + // Ignore build artifacts, external content, and operational directories + "ignores": [ + "assets/presentation/**", + ".typedialog/**", + ".woodpecker/**", + "assets/branding/**", + "assets/logo_prompt.md", + "node_modules/**", + "target/**", + ".git/**", + "build/**", + "dist/**", + ".coder/**", + ".claude/**", + ".wrks/**", + ".vale/**", + "vendor/**" + ] +} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..1d93a6b --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,132 @@ +# Pre-commit Framework Configuration +# Generated by dev-system/ci +# Configures git pre-commit hooks for Rust projects + +repos: + # ============================================================================ + # Rust Hooks + # ============================================================================ + - repo: local + hooks: + - id: rust-fmt + name: Rust formatting (cargo +nightly fmt) + entry: bash -c 'cargo +nightly fmt --all -- --check' + language: system + types: [rust] + pass_filenames: false + stages: [pre-commit] + + - id: rust-clippy + name: Rust linting (cargo clippy) + entry: bash -c 'cargo clippy --all-targets -- -D warnings' + language: system + types: [rust] + pass_filenames: false + stages: [pre-commit] + + - id: rust-test + name: Rust tests + entry: bash -c 'cargo test --workspace' + language: system + types: [rust] + pass_filenames: false + stages: [pre-push] + + - id: cargo-deny + name: Cargo deny (licenses & advisories) + entry: bash -c 'cargo deny check licenses advisories' + language: system + pass_filenames: false + stages: [pre-push] + + # ============================================================================ + # Nushell Hooks (optional - enable if using Nushell) + # ============================================================================ + # - repo: local + # hooks: + # - id: nushell-check + # name: Nushell validation (nu --ide-check) + # entry: >- + # bash -c 'for f in $(git diff --cached --name-only --diff-filter=ACM | grep "\.nu$"); do + # echo "Checking: $f"; nu --ide-check 100 "$f" || exit 1; done' + # language: system + # types: [file] + # files: \.nu$ + # pass_filenames: false + # stages: [pre-commit] + + # ============================================================================ + # Nickel Hooks (optional - enable if using Nickel) + # ============================================================================ + # - repo: local + # hooks: + # - id: nickel-typecheck + # name: Nickel type checking + # entry: >- + # bash -c 'export NICKEL_IMPORT_PATH="../:."; for f in $(git diff --cached --name-only --diff-filter=ACM | grep "\.ncl$"); do + # echo "Checking: $f"; nickel typecheck "$f" || exit 1; done' + # language: system + # types: [file] + # files: \.ncl$ + # pass_filenames: false + # stages: [pre-commit] + + # ============================================================================ + # Bash Hooks (optional - enable if using Bash) + # ============================================================================ + # - repo: local + # hooks: + # - id: shellcheck + # name: Shellcheck (bash linting) + # entry: shellcheck + # language: system + # types: [shell] + # stages: [pre-commit] + # + # - id: shfmt + # name: Shell script formatting + # entry: bash -c 'shfmt -i 2 -d' + # language: system + # types: [shell] + # stages: [pre-commit] + + # ============================================================================ + # Markdown Hooks (RECOMMENDED - enable for documentation quality) + # ============================================================================ + - repo: local + hooks: + - id: markdownlint + name: Markdown linting (markdownlint-cli2) + entry: markdownlint-cli2 + language: system + pass_filenames: false + stages: [pre-commit] + + # ============================================================================ + # General Pre-commit Hooks + # ============================================================================ + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-added-large-files + args: ['--maxkb=1000'] + exclude: ^assets/presentation/ + + - id: check-case-conflict + + - id: check-merge-conflict + + - id: check-toml + exclude: ^assets/presentation/ + + - id: check-yaml + exclude: ^(\.woodpecker/|assets/presentation/) + + - id: end-of-file-fixer + exclude: ^assets/presentation/ + + - id: trailing-whitespace + exclude: (\.md$|^assets/presentation/) + + - id: mixed-line-ending + exclude: ^assets/presentation/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..fade058 --- /dev/null +++ b/README.md @@ -0,0 +1,123 @@ +

+ ontoref +

+ +
+ +**ontoref** is a protocol specification and tooling layer for structured self-knowledge in +software projects. It provides schemas, Nushell automation, and Rust crates so that projects +can describe what they are, record architectural decisions, track operational state, and +execute formalized procedures — all as typed, queryable artifacts. + +--- + +## Axioms + +| Axiom | Meaning | +| --- | --- | +| **Protocol, Not Runtime** | Never a runtime dependency. Projects adopt the protocol; ontoref provides the schemas and modules to do so. | +| **Self-Describing** | Consumes its own protocol: `.ontology/`, `adrs/`, `reflection/` in this repo ARE ontoref running against itself. | +| **No Enforcement** | ontoref defines contracts. There is no enforcement mechanism. Coherence is voluntary and emerges from justified adoption. | +| **DAG-Formalized Knowledge** | Concepts, tensions, decisions, state — encoded as DAGs. Enables transversal queries and impact analysis. | + +## Layers + +```text +ontology/ Protocol specification — Nickel schemas for nodes, edges, ADRs, state, gates +adrs/ Architecture Decision Records — typed NCL with constraints and ontology checks +reflection/ Operational tooling — Nushell modules, DAG modes, forms, and schemas +crates/ Rust implementation — typed struct loaders and mode executors +.ontology/ Self-description — ontoref's own ontology, state, gate, and manifest +``` + +## Crates + +| Crate | Purpose | +| --- | --- | +| `ontoref-ontology` | Load `.ontology/*.ncl` as typed Rust structs. Zero stratumiops deps — minimal adoption surface. | +| `ontoref-reflection` | Load, validate, and execute Reflection modes as NCL DAG contracts against project state. | +| `ontoref-daemon` | NCL export cache, file watcher, actor registry, HTTP API, MCP server, Q&A store, quick-actions, passive drift observation. | + +`ontoref-daemon` caches `nickel export` results (keyed by path + mtime), reducing full sync +scans from ~2m42s to <30s. The daemon is always optional — every module falls back to direct +subprocess when unavailable. + +### Daemon Capabilities + +**Q&A Knowledge Store** — accumulated Q&A entries persist to `reflection/qa.ncl` (typed NCL, +git-versioned). Not localStorage. Any actor — developer, agent, CI — reads the same store. + +**MCP Server** — exposes 8+ tools over stdio and streamable-HTTP for AI agent integration: + +| Tool | What it does | +| --- | --- | +| `ontoref_qa_list` | List Q&A entries with optional filter | +| `ontoref_qa_add` | Append a new Q&A entry to `reflection/qa.ncl` | +| `ontoref_action_list` | List all quick actions from `.ontoref/config.ncl` | +| `ontoref_action_add` | Create a reflection mode + register it as a quick action | +| `ontoref_backlog_list` | List backlog items | +| `ontoref_backlog_add` | Add a backlog item | +| `ontoref_describe` | Describe project ontology and constraints | +| `ontoref_sync_scan` | Scan for ontology drift | + +**Passive Drift Observation** — background file watcher that detects divergence between Yang +code artifacts and Yin ontology. Watches `crates/`, `.ontology/`, `adrs/`, `reflection/modes/`. +After a 15s debounce runs `sync scan + sync diff`; emits an `ontology_drift` notification when +MISSING/STALE/DRIFT/BROKEN items are found. Never applies changes — `apply` is always deliberate. + +**Quick Actions** — runnable shortcuts over reflection modes, configured as `quick_actions` in +`.ontoref/config.ncl`. Accessible from HTTP (`/actions`), CLI (`./ontoref`), and MCP +(`ontoref_action_list/add`). + +## Adopting ontoref + +A consumer project needs exactly two artifacts: + +```sh +# 1. Copy the entry point wrapper +cp templates/scripts-ontoref scripts/ontoref +chmod +x scripts/ontoref + +# 2. Initialize config +mkdir -p .ontoref +cp templates/ontoref-config.ncl .ontoref/config.ncl +``` + +Or run the adoption mode interactively: + +```sh +./ontoref --actor developer adopt_ontoref +``` + +`ONTOREF_PROJECT_ROOT` is set by the consumer wrapper — one ontoref checkout serves multiple projects. + +## Prerequisites + +- [Nushell](https://www.nushell.sh/) >= 0.110.0 +- [Nickel](https://nickel-lang.org/) (for schema evaluation) +- Rust toolchain (for building crates) +- [Just](https://just.systems/) (for CI recipes) + +To build `ontoref-daemon` and `ontoref-reflection` with NATS/SurrealDB support, the +stratumiops repo must be checked out at `../../../stratumiops`. Without it, build without +default features: + +```sh +cargo build -p ontoref-daemon --no-default-features +cargo build -p ontoref-ontology # always standalone +``` + +## Development + +```sh +cargo check-all # check all targets + features +cargo test-all # run full test suite +just ci-lint # clippy + TOML + Nickel + Markdown +just ci-full # all CI checks +nu --ide-check 50 reflection/modules/.nu # validate a Nushell module +./ontoref --actor developer # run a reflection mode +``` + +## License + +MIT OR Apache-2.0