ontoref/reflection/backlog.ncl

497 lines
26 KiB
Text
Raw Normal View History

let s = import "schemas/backlog.ncl" in
{
items = [
{
id = "bl-001",
title = "Publish ontoref.dev landing page",
kind = 'Todo,
priority = 'High,
status = 'Open,
detail = "Deploy assets/web/ to ontoref.dev. Prerequisite for protocol-stable state transition (ADR-001 condition).",
related_adrs = ["adr-001-protocol-as-standalone-project"],
related_dim = "protocol-maturity",
graduates_to = 'PrItem,
created = "2026-03-13",
},
{
id = "bl-002",
title = "First external project consuming the protocol",
kind = 'Todo,
priority = 'High,
status = 'Open,
detail = "Onboard at least one project outside the stratumiops ecosystem (vapora, kogral, or syntaxis) with .ontoref/config.ncl and ontoref setup. Prerequisite for protocol-stable state transition.",
related_adrs = ["adr-001-protocol-as-standalone-project"],
related_dim = "ecosystem-integration",
graduates_to = 'StateTransition,
created = "2026-03-13",
},
{
id = "bl-003",
title = "ontoref keys CLI group",
kind = 'Todo,
priority = 'Medium,
status = 'Open,
detail = "Add `ontoref keys list`, `keys add <label> <role>`, `keys remove <label>`, `keys rotate <label>` subcommands. list is viewer+, mutations require admin Bearer. Complements setup --gen-keys (bootstrap only) with runtime key management.",
related_adrs = ["adr-005-unified-auth-session-model"],
created = "2026-03-13",
},
{
id = "bl-004",
title = "Session management UI views",
kind = 'Todo,
priority = 'Medium,
status = 'Open,
detail = "Per-project sessions tab in /ui/{slug}/: read-only table of active sessions (id, role, key_label, expires_at). Manage page sessions table: all sessions across all projects with revoke button. Daemon admin only for the global view.",
related_adrs = ["adr-005-unified-auth-session-model"],
created = "2026-03-13",
},
{
id = "bl-005",
title = "Fix Syntaxis ES→EN ontology migration errors",
kind = 'Bug,
priority = 'Medium,
status = 'Open,
detail = "syntaxis-ontology crate has migration errors blocking ecosystem-integration → multi-project transition. Blocker from state.ncl ecosystem-integration dimension.",
related_dim = "ecosystem-integration",
created = "2026-03-13",
},
{
id = "bl-006",
title = "Accept ADR-001 (protocol as standalone project)",
kind = 'Todo,
priority = 'High,
status = 'Open,
detail = "ADR-001 is currently Proposed. Acceptance condition: ontoref.dev published and at least one external project consuming the protocol. Triggers protocol-stable state transition.",
related_adrs = ["adr-001-protocol-as-standalone-project"],
related_dim = "protocol-maturity",
graduates_to = 'Adr,
created = "2026-03-13",
},
feat: #[onto_mcp_tool] catalog, OCI credential vault layer, validate ADR-018 mode hierarchy ontoref-derive: #[onto_mcp_tool] attribute macro registers MCP tool unit-structs in the catalog at link time via inventory::submit!; annotated item is emitted unchanged, ToolBase/AsyncTool impls stay on the struct. All 34 tools migrated from manual wiring (net +5: ontoref_list_projects, ontoref_search, ontoref_describe, ontoref_list_ontology_extensions, ontoref_get_ontology_extension). validate modes (ADR-018): reads level_hierarchy from workflow.ncl and checks every .ncl mode for level declared, strategy declared, delegate chain coherent, compose extends valid. mode resolve <id> shows which hierarchy level handles a mode and why. --self-test generates synthetic fixtures in a temp dir for CI smoke-testing. validate run-cargo: two-step Cargo.toml resolution — workspace layout first (crates/<check.crate>/Cargo.toml), single-crate fallback by package name or repo basename. Lets the same ADR constraint shape apply to workspace and single-crate repos. ontology/schemas/manifest.ncl: registry_topology_type contract — multi-registry coordination, push targets, participant scopes, per-namespace capability. reflection/requirements/base.ncl: oras ≥1.2.0, cosign ≥2.0.0, sops ≥3.9.0, age ≥1.1.0, restic declared as Hard/Soft requirements with version_min, check_cmd, and install_hint (ADR-017 toolchain surface). ADR-019: per-file recipient routing for tenant isolation without multi-vault. Schema additions: sops.recipient_groups + sops.recipient_rules in ontoref-project.ncl. secrets-bootstrap generates .sops.yaml from project.ncl in declarative mode. Three new secrets-audit checks: recipient-routing-coherent, recipient-routing-coverage, no-multi-vault. Adoption templates: single-team/, multi-tenant/, agent-first/. Integration templates: domain-producer/, mode-producer/, mode-consumer/. UI: project_picker surfaces registry badge (⟳ participant) and vault badge (⛁ vault_id · N, green=declarative / amber=legacy) per project card. Expanded panel adds collapsible Registry section with namespace, endpoint, and push/pull capability. manage.html gains Runtime Services card — MCP and GraphQL toggleable without restart via HTMX POST /ui/manage/services/{service}/toggle. describe.nu: capabilities JSON includes registry_topology and vault_state per project. sync.nu: drift check extended to detect //! absence on newly registered crates. qa.ncl: six entries — credential-vault-best-practice (layered data-flow diagram), credential-vault-templates (paths A/B/C), credential-vault-troubleshooting (15 named errors), integration-what-and-why (ADR-042 OCI federation), integration-how-to-implement, integration-troubleshooting. on+re: core.ncl + manifest.ncl updated to reflect OCI, MCP, and mode-hierarchy nodes. Deleted stale presentation assets (2026-02 slides + voice notes).
2026-05-12 04:46:15 +01:00
{
id = "bl-007",
title = "ADR `'Grep` constraint check needs path-exclusion expressivity",
kind = 'Wish,
priority = 'Low,
status = 'Open,
detail = "Surfaced by an adopting project (lian-build) writing adr-003 (`nickel-via-subprocess`). The ADR wants to enforce: 'no Rust file in src/ may call Command::new(\"nickel\") EXCEPT src/directives.rs which is the canonical dispatch site.' The current `'Grep` check shape (pattern, paths, must_be_empty) cannot express 'paths_exclude'. Workaround in lian-build: must_be_empty=false (positive presence) plus check_hint explaining the rule socially. Auditable but does not catch a second copy of the dispatch in another module. Alternatives: (A) add `paths_exclude: Array String` to `'Grep`; (B) new `'GrepFiltered` tag with include/exclude lists; (C) recommend `'NuCmd` for these cases (works today, opaque to static review). Friction site: lian-build/adrs/adr-003-nickel-via-subprocess.ncl::nickel-export-centralized. Mirror lives at lian-build/reflection/backlog.ncl::bl-002.",
related_adrs = [],
graduates_to = 'PrItem,
created = "2026-05-03",
},
{
id = "bl-010",
title = "Canonicalize ontoref-instance directory layout (manifest path + federated-peer catalog path)",
kind = 'Debt,
priority = 'Medium,
status = 'Open,
detail = m%"
SURFACED BY adr-020 layer-2-biconditional check applied across the
three ontoref-onboarded projects (2026-05-03 audit).
DRIFT OBSERVED — three projects, three conventions
ontoref domains/, modes/ (TOP-LEVEL — no catalog/)
.ontology/manifest.ncl (under .ontology/)
registry_provides declared
lian-build catalog/domains/, catalog/modes/ (under catalog/)
manifest.ncl (at root)
.ontology/manifest.ncl (pointer to root)
registry_provides declared
provisioning catalog/domains/, catalog/components/, catalog/providers/
.ontology/manifest.ncl (under .ontology/)
registry_provides ABSENT despite federated-peer
catalog/domains/
THREE INDEPENDENT QUESTIONS
Q1 — federated-peer catalog path
Options:
(a) `catalog/domains/` and `catalog/modes/` (lian-build / provisioning)
(b) `domains/` and `modes/` at top-level (ontoref)
(c) Allow either, normalize at check time
Trade-off: (a) groups all federation artifacts under one prefix;
(b) gives them top-level visibility; (c) avoids migration but
makes the layer-2-biconditional check more elaborate.
Q2 — manifest.ncl canonical location
Options:
(a) Project root: `manifest.ncl` (lian-build)
(b) Self-ontology: `.ontology/manifest.ncl` (ontoref, provisioning)
(c) Both, with the non-canonical one as a pointer (lian-build does
this — root is canonical, .ontology/manifest.ncl imports it)
Trade-off: (a) joins the top-level doc surface; (b) groups all
self-ontology files under one directory; (c) accommodates both
but adds one indirection.
Q3 — provisioning's missing registry_provides
Independent of Q1 / Q2: provisioning has catalog/domains/ but no
registry_provides declaration. Either it should add one (as a
federated peer publishing the protocol's shared domains under
its participant namespace), OR the protocol's shared domains
should move to a participant-scoped location somewhere else.
See bl-007 for related schema work.
WHEN THIS GRADUATES
Decision yields an ADR (or amendment to adr-020) committing the
canonical paths. Migration follows in three coordinated changes:
one per project. After migration, adr-020 promotes from 'Proposed
to 'Accepted and the layer-2-biconditional check passes ecosystem-
wide.
REFERENCES
- adrs/adr-020-three-layer-ontoref-instance-model.ncl
- reflection/backlog.ncl::bl-009 graduation parent
- reflection/qa.ncl::ontoref-three-layer-model protocol-level
explanation
"%,
related_adrs = ["adr-020"],
graduates_to = 'Adr,
created = "2026-05-03",
},
{
id = "bl-012",
title = "ontoref runner + template bugs surfaced during dao-discipline rollout",
kind = 'Bug,
priority = 'High,
status = 'Done,
updated = "2026-05-03",
detail = m%"
SURFACED BY adr-020 + lian-build adr-002/adr-003 smoke tests + the
full update_ontoref end-to-end run during dao-discipline
rollout (2026-05-03). What started as 3 validate.nu
dispatcher bugs grew into 5 root-cause fixes when each
fix exposed the next failure layer. All 5 fixed in this
session; 4 of 5 propagated via just install + 1 via
direct template edit.
FINAL BUG INVENTORY (all closed)
BUG #1 — port drift: client default 7891, daemon 7890
File: reflection/modules/store.nu (daemon-url)
Cosmetic fix attempted first: changed literal 7891→7890 in 10 sites.
Real fix applied: single source of truth — daemon-url in store.nu
reads ~/.config/ontoref/config.ncl::daemon.port. The 9 consumer
sites import daemon-url from store.nu and call (daemon-url)
instead of duplicating the env-or-default pattern. Future port
changes are 1 edit in config.ncl, not 10.
BUG #2a — run-nucmd doesn't substitute placeholders
File: reflection/nulib/modes.nu (exec-step-cmd)
Symptom: cmd "test -f {project_dir}/.ontology/manifest.ncl || ..."
ran with literal {project_dir}, hitting filesystem paths that
don't exist. Every mode step using placeholders silently failed.
Fix: build-cmd-context resolves {project_dir} / {ontoref_dir} /
{project_name} from env + .ontoref/project.ncl::slug; substitution
happens before bash/nu dispatch.
BUG #2b — paths with spaces break --import-path A:B:C
File: reflection/modes/update_ontoref.ncl (validate-* steps)
Surfaced after Bug #2a fix exposed the second-order failure on
macOS where ontoref installs to ~/Library/Application Support/.
Fix: rewrote 4 cmds (add-manifest, add-connections, validate-
manifest, validate-connections) to quote {ontoref_dir} placeholder
and use --import-path repeated per directory instead of colon-
separated. Also future-proofs for any project path containing
spaces.
BUG #3 — template connections.ncl uses bare import "connections"
File: templates/ontology/connections.ncl
Symptom: template generated files that didn't typecheck because
NICKEL_IMPORT_PATH didn't include a directory where bare
"connections" resolves. Existing onboarded projects worked
because they used import "reflection/schemas/connections.ncl"
(path-qualified) from older onboarding flows.
Fix: template aligned with convention.
BUG #4 — template manifest.ncl missing required consumption_modes
File: templates/ontology/manifest.ncl
Symptom: generated manifest.ncl failed contract validation because
ProjectManifest schema requires consumption_modes (no default).
Surfaced after Bug #2b fix unblocked validate-manifest step.
Fix: template adds default 'Developer consumer scaffold with
comment marking it for replacement.
BUG #1 (original report; now superseded by inventory above) — run-nucmd doesn't cd to project root
File: reflection/modules/validate.nu line ~89
Symptom: NuCmd checks with relative paths silently mis-resolve.
The cmd executes from validate.nu's invocation cwd, not
from (adr-root). Concrete case: adr-020's
layer-2-biconditional check evaluates to FALSE for both
sides (no catalog/, no manifest.ncl) when invoked from
reflection/modules/, producing a spurious 'biconditional
holds' PASS even though the project violates it.
Fix: cd (adr-root) before nu -c $check.cmd in run-nucmd.
One-line patch.
Validates: re-run validate check-adr adr-020 from arbitrary cwd
and confirm result matches direct-from-root invocation.
BUG #2 — run-cargo assumes workspace layout (crates/<name>/Cargo.toml)
File: reflection/modules/validate.nu (run-cargo)
Symptom: For single-crate projects (lian-build), the dispatcher
looks at crates/lian-build/Cargo.toml which doesn't
exist; the check fails with 'Cargo.toml not found'.
Concrete case: adr-003's no-nickel-rust-deps fails on lian-build
despite Cargo.toml at project root containing no
nickel-lang dep.
Fix: Try Cargo.toml at root first; fall back to crates/<crate>/
only if root Cargo.toml doesn't declare the named crate.
Or: make the check accept an explicit `manifest_path`
field instead of inferring from `crate` name.
Validates: re-run validate check-adr adr-003 from lian-build root;
no-nickel-rust-deps should PASS.
BUG #3 — daemon-export-safe failure on some ADRs
File: reflection/modules/store.nu line 200
Symptom: `validate check-adr adr-001` against lian-build returns
eval_block_with_input error from store.nu:200 ($result.stdout
| from json with empty stdout because nickel export
failed silently).
Hypothesis: daemon-export-safe doesn't pass the four
nickel_import_paths from .ontoref/project.ncl, so ADRs
that import from those paths fail to export. This was
the root cause when I drafted lian-build adrs/ — they
all import ../../../Development/ontoref/adrs/defaults.ncl.
Fix: Read .ontoref/project.ncl::nickel_import_paths and pass
them to nickel export as --import-path. Already partially
done in some sites; needs auditing across daemon-export-safe.
Validates: re-run validate check-adr adr-001 from lian-build root;
should not error from store.nu.
WHY HIGH PRIORITY
Without these fixes, the constraint discipline doesn't deliver its
value: false PASSes (Bug #1) silently mask real violations; false
FAILs (Bugs #2, #3) train readers to ignore the runner. Either
failure mode erodes trust in the validation surface.
REFERENCES
- reflection/modules/validate.nu (file with all three bugs)
- reflection/modules/store.nu:200 (Bug #3 site)
- adrs/adr-020-three-layer-ontoref-instance-model.ncl
(Bug #1 surfaced here)
- lian-build/adrs/adr-002-cli-subcommand-discipline.ncl
(independent: my own NuCmd
used bash `2>&1` instead of
nu `out+err>`; fixed in
same audit)
- lian-build/adrs/adr-003-nickel-via-subprocess.ncl
(Bug #2 surfaced here)
"%,
related_adrs = ["adr-020"],
graduates_to = 'PrItem,
created = "2026-05-03",
},
{
id = "bl-011",
title = "Cross-project constraint application — protocol ADRs need a way to validate consumer projects",
kind = 'Idea,
priority = 'Medium,
status = 'Open,
detail = m%"
SURFACED BY adr-020 drafting (2026-05-03). The constraint runner in
reflection/modules/validate.nu globs `adrs/adr-*.ncl`
from the target project's root only. Protocol-level
ADRs (currently adr-020, future adr-021+) live in
<ontoref>/adrs/, so they do NOT apply when validating
a consumer project (lian-build, provisioning).
EFFECT
adr-020's six constraints are runnable against ontoref itself, but
a consumer project's CI cannot use the same constraints to verify
its own Layer 1 / Layer 2 compliance. Each consumer would have to
either:
(a) copy adr-020 into its own adrs/ (cargo-cult, drift hazard)
(b) write its own adr-NNN that references the model (ceremony)
(c) wait for a protocol-aware validate runner
ALTERNATIVES (no decision committed)
A. Inherit by reference — `.ontoref/project.ncl` declares
`protocol_adrs = ["adr-020"]`, and validate.nu's adr-files
helper unions the project's own adrs/ with the named
protocol adrs from <ontoref-root>/adrs/. Uses the existing
ADR-018 level hierarchy machinery (parent-traversal).
B. Separate validate command — `validate check-protocol`
explicitly runs a fixed set of protocol-level ADRs against
the current target. Makes the protocol-vs-self distinction
explicit at the CLI; less magic than (A).
C. Cargo-cult copy on setup — `ontoref setup` writes a sentinel
file at `adrs/_protocol/adr-020.ncl` that pulls
`<ontoref>/adrs/adr-020-*.ncl` via NCL import. Lighter than
a full copy; brittle if the protocol path changes.
D. Status quo — protocol ADRs apply only to ontoref itself;
consumer projects implement their own self-mirror.
TRADE-OFF SUMMARY
- (A) extends the existing level-hierarchy plumbing; couples
validate.nu to the level resolution logic. Cleanest model.
- (B) is the smallest CLI change but requires every consumer
to remember to run it.
- (C) is the smallest setup change but creates phantom files.
- (D) is the least work and the least value.
WHEN THIS GRADUATES
When a second consumer project (beyond lian-build) onboards and
asks "how do I know my project conforms to adr-020?" Today
lian-build can be checked manually (and was, in 2026-05-03's
audit). At >=2 consumers the manual approach doesn't scale.
REFERENCES
- reflection/modules/validate.nu::adr-files current root-only globbing
- reflection/modules/validate.nu::run-fileexists / run-nucmd constraint runners (already exist)
- adr-018-level-hierarchy-mode-resolution-strategy parent-traversal precedent
- adr-020-three-layer-ontoref-instance-model the ADR whose effectiveness this gates
- bl-010 directory drift (independent of this gap)
"%,
related_adrs = ["adr-020", "adr-018-level-hierarchy-mode-resolution-strategy"],
graduates_to = 'Adr,
created = "2026-05-03",
},
{
id = "bl-008",
title = "lian-build is a candidate satisfier of bl-002 (first external consuming project)",
kind = 'Idea,
priority = 'Medium,
status = 'Open,
detail = "bl-002 ('First external project consuming the protocol') gates the protocol-maturity dimension's transition to 'protocol-stable'. lian-build now has its own ontoref instance (.ontology, reflection/{qa,backlog,modes}, adrs, manifest.ncl, catalog/{domains,modes}) and adopts the schema fully. Open question: does lian-build count as 'external' given that it's authored by the same maintainer set, or does the criterion require organizationally-distinct adoption? If it counts, this graduates bl-002. If not, lian-build is at minimum strong evidence the protocol is consumable. Decision should be recorded as an explicit acceptance criterion update on bl-002, not buried in a chat. Cross-references: lian-build's reflection/qa.ncl exemplifies a project's qa instance; reflection/backlog.ncl exemplifies project-level backlog; adrs/adr-001..003 exemplify project ADRs with constraint-bearing checks.",
related_dim = "protocol-maturity",
graduates_to = 'StateTransition,
created = "2026-05-03",
},
{
id = "bl-009",
title = "Codify the three-layer ontoref model as a protocol-level concept",
kind = 'Idea,
priority = 'Medium,
status = 'InProgress,
updated = "2026-05-03",
detail = m%"
SURFACED BY lian-build adoption (.coder/2026-05-03 conversation,
reflection/qa.ncl::lian-build-what-and-why).
WHY HERE when an adopting project sees the protocol, the layering
of its ontoref instance must be discoverable from protocol
documentation, not re-derived per project. Today the model
is implicit — projects accidentally mix layers, and the
'don't mix' rule lives in chat threads.
THE THREE LAYERS as observed across ontoref + lian-build + provisioning
LAYER 1 — Self-management ontoref (about the project itself)
paths: .ontology/ reflection/ adrs/
audience: this project's developers and maintainers
purpose: describe the project to itself — axioms, FSM dimensions,
binding decisions, open questions
present: EVERY ontoref-onboarded project
LAYER 2 — Specialized domain/mode ontoref (the integration surface)
paths: schemas/ catalog/{domains,modes}/ manifest.ncl::registry_provides
audience: OTHER projects that want to integrate this project
purpose: the contract surface other projects bind to —
domain artifacts (typed contracts), mode artifacts
(orchestration shapes), schemas, registry-namespace
claim
present: projects that publish federated artifacts (lian-build
yes; some projects no — Layer 2 is OPTIONAL)
LAYER 3 — Caller-side implementations (NOT in this project)
paths: <caller>/extensions/<this-project>/
<workspace>/infra/<ws>/integrations/
<caller>/catalog/components/<...>/ (when consuming)
audience: operators and CI of caller projects
purpose: wiring this project into a specific workspace or pipeline
present: PER CALLER, NEVER in this project's repo
WHY THE LAYERING MATTERS
The three layers collapse if mixed. Symptoms when mixing happens:
- Layer 3 content in Layer 1 → project FAQ becomes a how-to-deploy
guide for one specific caller; other callers get nothing.
- Layer 2 content in Layer 1 → schemas drift from the binary
because they're treated as 'project notes' instead of contracts.
- Layer 1 content in Layer 2 → caller pulls a contract artifact
and gets architectural rationale instead of a typed shape.
- Cross-project Layer 1 sharing → ontoref's qa.ncl would carry
project-specific entries that adopters can't filter out.
Each layer has a different lifecycle, audience, and validation
rule. Treating them as one violates the no-mixing convention
repeatedly observed in practice.
WHAT AN ADR WOULD COMMIT (constraint candidates — pick a subset)
(a) Layer 1 mandatory: every ontoref-onboarded project has
.ontology/core.ncl AND reflection/qa.ncl AND reflection/backlog.ncl
AND adrs/.
Check: 'FileExists per path.
(b) Layer 2 optional but well-formed when present: a project with
catalog/ MUST also have manifest.ncl::registry_provides
(and vice versa).
Check: 'NuCmd that asserts the biconditional.
(c) Layer 3 isolation: a project's src/ + Cargo.toml + .ontology/
+ reflection/ MUST NOT contain caller-side cabling files
(cabling lives in callers).
Check: 'Grep with paths_exclude (depends on bl-007).
(d) Cross-layer reference convention: a project's qa entry that
touches another layer must be tagged accordingly
("layer-1", "layer-2", "layer-3-boundary").
Check: 'NuCmd validating tag presence on cross-layer entries.
CANDIDATES TO ADD TO `ontoref setup`
- Generate reflection/qa.ncl scaffold (currently only backlog.ncl
and qa.ncl appear after manual setup).
- Generate manifest.ncl with registry_provides commented out (Layer 2
opt-in cue).
- Generate adrs/_template.ncl pre-filled with constraint-bearing
example shape (already done in ontoref itself — propagate).
OPEN QUESTIONS
- Naming: 'self-management' / 'integration-surface' / 'caller-side'
vs. 'Layer 1/2/3' vs. some other vocabulary. Numbered is precise
but flat; named is descriptive but verbose.
- Should Layer 2's `manifest.ncl::registry_provides` be in
`.ontology/` instead of project root? Today it lives at root in
both lian-build and ontoref; the alternative is .ontology/manifest.ncl
(which exists as a pointer in lian-build).
- How does this layering interact with ADR-018 (level-hierarchy:
Base / Domain / Instance)? Are the three layers orthogonal to
the three levels (a 3x3 matrix), or do they collapse onto each
other in some way?
REFERENCES
- lian-build/reflection/qa.ncl::lian-build-what-and-why worked example
- lian-build/manifest.ncl Layer 2 example
- adr-018-level-hierarchy-mode-resolution-strategy open interaction
- bl-002 / bl-008 protocol-maturity
transition gate
"%,
related_adrs = ["adr-018-level-hierarchy-mode-resolution-strategy"],
related_dim = "protocol-maturity",
graduates_to = 'Adr,
created = "2026-05-03",
},
],
} | s.BacklogConfig