134 lines
5.7 KiB
HTML
Raw Permalink Normal View History

2026-03-13 00:18:14 +00:00
{% extends "base.html" %}
{% import "macros/ui.html" as m %}
{% block title %}Reflection Modes — Ontoref{% endblock title %}
{% block nav_modes %}active{% endblock nav_modes %}
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
{% block nav_group_reflect %}active{% endblock nav_group_reflect %}
2026-03-13 00:18:14 +00:00
{% block content %}
<div class="mb-4 flex items-center justify-between">
<h1 class="text-2xl font-bold">Reflection Modes</h1>
<span class="badge badge-lg badge-neutral">{{ total }}</span>
</div>
{% if showcase %}
<div class="mb-6">
<p class="text-xs font-semibold text-base-content/40 uppercase tracking-wider mb-2">Project Showcase</p>
<div class="flex flex-wrap gap-2">
{% for s in showcase %}
<a href="{{ s.url }}" target="_blank" rel="noopener"
class="btn btn-sm btn-outline gap-2">
{% if s.id == "branding" %}
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01"/>
</svg>
{% elif s.id == "web" %}
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"/>
</svg>
{% elif s.id == "presentation" %}
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M7 12l3-3 3 3 4-4M8 21l4-4 4 4M3 4h18M4 4h16v12a1 1 0 01-1 1H5a1 1 0 01-1-1V4z"/>
</svg>
{% endif %}
{{ s.label }}
<svg class="w-3 h-3 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
</svg>
</a>
{% endfor %}
</div>
</div>
{% endif %}
{% if generated %}
<div class="mb-6">
<p class="text-xs font-semibold text-base-content/40 uppercase tracking-wider mb-2">Generated Artifacts</p>
<div class="flex flex-wrap gap-2">
{% for g in generated %}
<a href="{{ g.url }}" target="_blank" rel="noopener"
class="btn btn-sm btn-ghost gap-2 border border-base-content/10">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
{{ g.label }}
<svg class="w-3 h-3 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
</svg>
</a>
{% endfor %}
</div>
</div>
{% endif %}
{% if modes | length == 0 %}
{{ m::empty_state(message="No reflection modes found in reflection/modes/") }}
{% else %}
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
{% for mode in modes %}
<div class="card bg-base-200 shadow">
<div class="card-body p-4">
<div class="flex items-start justify-between gap-2 mb-2">
<h2 class="card-title text-base font-bold font-mono text-primary">
{{ mode.id | default(value="unknown") }}
</h2>
{% if mode._error %}
<span class="badge badge-error badge-sm shrink-0">error</span>
{% else %}
{% set step_count = mode.steps | default(value=[]) | length %}
<span class="badge badge-neutral badge-sm shrink-0">{{ step_count }} step(s)</span>
{% endif %}
</div>
{% if mode._error %}
<p class="text-xs text-error font-mono bg-base-300 p-2 rounded">{{ mode._error }}</p>
{% else %}
<p class="text-sm text-base-content/70 mb-3">{{ mode.trigger | default(value="") }}</p>
{% set steps = mode.steps | default(value=[]) %}
{% if steps | length > 0 %}
<div class="collapse collapse-arrow bg-base-300 rounded">
<input type="checkbox" class="peer">
<div class="collapse-title text-xs font-semibold py-2 min-h-0">
Steps ({{ steps | length }})
</div>
<div class="collapse-content px-3 pb-3">
<ol class="space-y-2 mt-1">
{% for step in steps %}
<li class="flex gap-2">
<span class="badge badge-outline badge-xs font-mono mt-0.5 shrink-0">{{ step.id | default(value=loop.index) }}</span>
<div class="min-w-0">
<p class="text-xs text-base-content/80">{{ step.action | default(value="") }}</p>
{% if step.cmd %}
<code class="text-xs text-accent block mt-0.5 truncate">{{ step.cmd }}</code>
{% endif %}
</div>
</li>
{% endfor %}
</ol>
</div>
</div>
{% endif %}
{% if mode.preconditions %}
<div class="mt-2 text-xs text-base-content/40 font-mono">
{{ mode.preconditions | length }} precondition(s)
</div>
{% endif %}
{% endif %}
<div class="mt-3 pt-2 border-t border-base-300">
<code class="text-xs text-base-content/30">{{ mode._file | default(value="") }}</code>
</div>
</div>
</div>
{% endfor %}
</div>
{% endif %}
{% endblock content %}