92 lines
4.3 KiB
HTML
Raw Normal View History

2026-03-13 00:18:14 +00:00
{% extends "base.html" %}
{% import "macros/ui.html" as m %}
{% block title %}Actions — Ontoref{% endblock title %}
{% block nav_actions %}active{% endblock nav_actions %}
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 mob_nav_actions %}active{% endblock mob_nav_actions %}
{% block content %}
<div class="mb-6 flex items-center justify-between">
<h1 class="text-xl font-bold">Quick Actions</h1>
<span class="text-xs text-base-content/40 font-mono">Runnable tasks and workflows</span>
</div>
{% if not actions or actions | length == 0 %}
{{ m::empty_state(message="No quick actions configured — add quick_actions to .ontoref/config.ncl") }}
{% else %}
{% set grouped = actions | group_by(attribute="category") %}
{% for cat, cat_actions in grouped %}
<section class="mb-8">
<h2 class="text-sm font-semibold uppercase tracking-wider text-base-content/50 mb-3">
{% if cat == "docs" %}Documentation
{% elif cat == "sync" %}Synchronization
{% elif cat == "analysis" %}Analysis
{% elif cat == "test" %}Testing
{% else %}{{ cat | title }}{% endif %}
</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{% for action in cat_actions %}
<div class="card bg-base-200 border border-base-content/10 hover:border-base-content/20 transition-colors">
<div class="card-body p-4 gap-3">
<div class="flex items-start gap-3">
<div class="flex-shrink-0 w-9 h-9 rounded-lg bg-base-300 flex items-center justify-center text-primary">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
{% if action.icon == "book-open" %}
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"/>
{% elif action.icon == "refresh" %}
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
{% elif action.icon == "code" %}
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"/>
{% else %}
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M13 10V3L4 14h7v7l9-11h-7z"/>
{% endif %}
</svg>
</div>
<div class="flex-1 min-w-0">
<h3 class="font-semibold text-sm leading-tight">{{ action.label }}</h3>
<p class="text-xs text-base-content/50 font-mono mt-0.5">mode: {{ action.mode }}</p>
</div>
</div>
<div class="flex flex-wrap gap-1">
{% for actor in action.actors %}
<span class="badge badge-xs
{% if actor == "developer" %}badge-primary
{% elif actor == "agent" %}badge-secondary
{% elif actor == "ci" %}badge-accent
{% else %}badge-ghost{% endif %}">{{ actor }}</span>
{% endfor %}
</div>
{% if not current_role or current_role == "admin" %}
<div class="card-actions justify-end pt-1">
<form method="post" action="{{ base_url }}/actions/run">
<input type="hidden" name="action_id" value="{{ action.id }}">
<button type="submit" class="btn btn-xs btn-primary gap-1">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
Run
</button>
</form>
</div>
{% endif %}
</div>
</div>
{% endfor %}
</div>
</section>
{% endfor %}
{% endif %}
{% endblock content %}