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).
70 lines
4.3 KiB
XML
70 lines
4.3 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="85 19 56 100" preserveAspectRatio="xMidYMid meet" role="img" aria-label="Lian Build">
|
|
<title>Lian Build</title>
|
|
<defs>
|
|
<linearGradient id="lv-fg" x1="0" y1="1" x2="0" y2="0">
|
|
<stop offset="0" stop-color="#e86c2f"/>
|
|
<stop offset="1" stop-color="#f5a623"/>
|
|
</linearGradient>
|
|
<linearGradient id="lv-cg" x1="0" y1="1" x2="0" y2="0">
|
|
<stop offset="0" stop-color="#f5a623"/>
|
|
<stop offset="1" stop-color="#fcd99e"/>
|
|
</linearGradient>
|
|
<style><![CDATA[
|
|
@import url('https://fonts.googleapis.com/css2?family=Jost:wght@400;500&display=swap');
|
|
.lv-flame{fill:url(#lv-fg);opacity:0;transform-origin:50% 100%;transform-box:fill-box;animation:lv-flame 23s cubic-bezier(.4,0,.2,1) infinite}
|
|
.lv-core{fill:url(#lv-cg);opacity:0;transform-origin:50% 100%;transform-box:fill-box;animation:lv-core 23s cubic-bezier(.4,0,.2,1) infinite}
|
|
.lv-cruc{fill:none;stroke:#a8a8a0;stroke-width:1.5;stroke-linecap:round;stroke-dasharray:36;stroke-dashoffset:36;animation:lv-cruc 23s cubic-bezier(.4,0,.2,1) infinite}
|
|
.lv-word{fill:#bd9156;font-family:"Jost","Avenir Next",Futura,"Century Gothic","Helvetica Neue",system-ui,sans-serif;font-weight:500;letter-spacing:.22em;font-size:22px;opacity:0;animation:lv-word 23s cubic-bezier(.4,0,.2,1) infinite}
|
|
.lv-sub{fill:#f29a3d;font-family:"Jost","Avenir Next",Futura,"Century Gothic","Helvetica Neue",system-ui,sans-serif;font-weight:500;letter-spacing:.22em;font-size:14px;opacity:0;animation:lv-sub 23s cubic-bezier(.4,0,.2,1) infinite}
|
|
.lv-fbord{fill:none;stroke:#e86c2f;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;opacity:0;animation:lv-fbord 23s cubic-bezier(.4,0,.2,1) infinite}
|
|
.lv-code{opacity:0;animation:lv-code 23s cubic-bezier(.4,0,.2,1) infinite}
|
|
@keyframes lv-core{
|
|
0%{opacity:0;transform:scale(.5)} 1.3%{opacity:.75;transform:scale(1.05)}
|
|
3.5%{opacity:.55;transform:scale(.95)} 5.2%{opacity:.35;transform:scale(.92)}
|
|
22%{opacity:.55;transform:scale(1)} 37%{opacity:.24;transform:scale(.88)}
|
|
53%{opacity:.55;transform:scale(1)} 68%{opacity:.24;transform:scale(.88)}
|
|
83%{opacity:.55;transform:scale(1)} 99%{opacity:.35;transform:scale(.92)} 100%{opacity:0}
|
|
}
|
|
@keyframes lv-flame{
|
|
0%,6.5%{opacity:0;transform:scale(.4)} 8.7%{opacity:.9;transform:scale(1)}
|
|
10.4%{opacity:1;transform:scale(1.05)} 12%{opacity:1;transform:scale(1)}
|
|
99%{opacity:1;transform:scale(1)} 100%{opacity:0;transform:scale(.4)}
|
|
}
|
|
@keyframes lv-fbord{
|
|
0%,11.7%{opacity:0} 14.3%{opacity:1} 99%{opacity:1} 100%{opacity:0}
|
|
}
|
|
@keyframes lv-code{
|
|
0%,15.2%{opacity:0} 17.4%{opacity:1} 99%{opacity:1} 100%{opacity:0}
|
|
}
|
|
@keyframes lv-cruc{
|
|
0%,18.3%{stroke-dashoffset:36;opacity:0} 18.8%{opacity:.8}
|
|
22.6%{stroke-dashoffset:0;opacity:.8} 99%{stroke-dashoffset:0;opacity:.8}
|
|
100%{stroke-dashoffset:36;opacity:0}
|
|
}
|
|
@keyframes lv-sub{
|
|
0%,19.6%{opacity:0} 23.9%{opacity:.85} 99%{opacity:.85} 100%{opacity:0}
|
|
}
|
|
@keyframes lv-word{
|
|
0%,20.4%{opacity:0} 25.2%{opacity:1} 99%{opacity:1} 100%{opacity:0}
|
|
}
|
|
@media (prefers-reduced-motion:reduce){
|
|
.lv-flame,.lv-fbord,.lv-core,.lv-cruc,.lv-word,.lv-sub,.lv-code{animation:none}
|
|
.lv-flame{opacity:1} .lv-fbord{opacity:1} .lv-code{opacity:1}
|
|
.lv-core{opacity:.35;transform:scale(.95);transform-origin:50% 100%;transform-box:fill-box}
|
|
.lv-cruc{opacity:.8;stroke-dashoffset:0} .lv-word{opacity:1} .lv-sub{opacity:.85}
|
|
}
|
|
]]></style>
|
|
</defs>
|
|
<path class="lv-cruc" d="M 92 66 L 128 66"/>
|
|
<path class="lv-flame" d="M 110 64 C 92 57 92 36 110 22 C 128 36 128 57 110 64 Z"/>
|
|
<path class="lv-fbord" d="M 110 64 C 92 57 92 36 110 22 C 128 36 128 57 110 64 Z"/>
|
|
<path class="lv-core" d="M 110 58 C 100 52 100 40 110 32 C 120 40 120 52 110 58 Z"/>
|
|
<g class="lv-code" fill="none" stroke="#c25a1a" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
|
|
<polyline points="106,42 103,46 106,50"/>
|
|
<line x1="112" y1="43" x2="109" y2="49"/>
|
|
<polyline points="115,42 118,46 115,50"/>
|
|
</g>
|
|
<text class="lv-word" x="113" y="93" text-anchor="middle">lian</text>
|
|
<text class="lv-sub" x="112" y="110" text-anchor="middle">build</text>
|
|
</svg>
|