@spec-engine/spec-engine 0.7.1 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/404.html +4 -4
- package/dist/docs/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.BcSo_yiZ.js +1 -0
- package/dist/docs/_astro/Search.astro_astro_type_script_index_0_lang.Djc9ZKGJ.js +1 -0
- package/dist/docs/_astro/TableOfContents.astro_astro_type_script_index_0_lang.Csloo1VZ.js +1 -0
- package/dist/docs/_astro/common.BPl3nku0.css +3 -0
- package/dist/docs/_astro/components.BeLFs6cp.css +1 -0
- package/dist/docs/_astro/page.cNngjUgL.js +1 -0
- package/dist/docs/_astro/print.ehPL0gv-.css +1 -0
- package/dist/docs/_astro/starlight-toc.CTCQXEge.js +1 -0
- package/dist/docs/_astro/ui-core.B94qsovR.js +2 -0
- package/dist/docs/agent-reference/index.html +23 -22
- package/dist/docs/architecture/index.html +422 -421
- package/dist/docs/checks/index.html +247 -246
- package/dist/docs/commands/index.html +125 -124
- package/dist/docs/format/index.html +92 -91
- package/dist/docs/getting-started/index.html +21 -20
- package/dist/docs/guides/adoption/index.html +13 -12
- package/dist/docs/guides/platform-setup/index.html +15 -14
- package/dist/docs/guides/single-repo/index.html +12 -11
- package/dist/docs/index.html +2 -152
- package/dist/docs/overview/index.html +8 -8
- package/dist/docs/pagefind/fragment/en_70e8a6f.pf_fragment +0 -0
- package/dist/docs/pagefind/fragment/en_907a67d.pf_fragment +0 -0
- package/dist/docs/pagefind/fragment/en_b81dc52.pf_fragment +0 -0
- package/dist/docs/pagefind/fragment/en_c8cc99c.pf_fragment +0 -0
- package/dist/docs/pagefind/fragment/en_de9d958.pf_fragment +0 -0
- package/dist/docs/pagefind/fragment/en_e616a50.pf_fragment +0 -0
- package/dist/docs/pagefind/fragment/en_f77a622.pf_fragment +0 -0
- package/dist/docs/pagefind/index/en_19cbfc6.pf_index +0 -0
- package/dist/docs/pagefind/index/en_4be71c4.pf_index +0 -0
- package/dist/docs/pagefind/pagefind-entry.json +1 -1
- package/dist/docs/pagefind/pagefind.en_f697eb692e.pf_meta +0 -0
- package/dist/docs/platform-mapping/index.html +162 -161
- package/dist/docs/tags/index.html +74 -73
- package/dist/impl.js +4 -4
- package/package.json +4 -4
- package/dist/docs/_astro/Code.CAimF0uL.css +0 -1
- package/dist/docs/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.hwBsy0Mo.js +0 -1
- package/dist/docs/_astro/Search.astro_astro_type_script_index_0_lang.lq3t8uE2.js +0 -1
- package/dist/docs/_astro/TableOfContents.astro_astro_type_script_index_0_lang.FuRcXuRY.js +0 -1
- package/dist/docs/_astro/common.DslAiFsT.css +0 -1
- package/dist/docs/_astro/page.B_tncCx8.js +0 -1
- package/dist/docs/_astro/print.DNXP8c50.css +0 -1
- package/dist/docs/_astro/ui-core.C8327L_n.js +0 -2
- package/dist/docs/pagefind/fragment/en_435dca1.pf_fragment +0 -0
- package/dist/docs/pagefind/fragment/en_4bdd17f.pf_fragment +0 -0
- package/dist/docs/pagefind/fragment/en_a3cd8bf.pf_fragment +0 -0
- package/dist/docs/pagefind/fragment/en_aaced0a.pf_fragment +0 -0
- package/dist/docs/pagefind/fragment/en_b44542a.pf_fragment +0 -0
- package/dist/docs/pagefind/fragment/en_d652b3c.pf_fragment +0 -0
- package/dist/docs/pagefind/fragment/en_eb51244.pf_fragment +0 -0
- package/dist/docs/pagefind/index/en_91ab2a1.pf_index +0 -0
- package/dist/docs/pagefind/index/en_b75c632.pf_index +0 -0
- package/dist/docs/pagefind/pagefind.en_dac6a68e28.pf_meta +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!DOCTYPE html><html lang="en" dir="ltr" data-theme="dark" data-has-toc data-has-sidebar class="astro-
|
|
1
|
+
<!DOCTYPE html><html lang="en" dir="ltr" data-theme="dark" data-has-toc data-has-sidebar class="astro-kmpt7d6z"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><title>Architecture | Spec Engine</title><link rel="canonical" href="https://docs.spec-engine.dev/architecture/"/><link rel="sitemap" href="/sitemap-index.xml"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="true"/><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Archivo:wght@600;700;800;900&family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600&display=swap"/><link rel="icon" href="/favicon.ico" sizes="any"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16.png"/><link rel="apple-touch-icon" sizes="180x180" href="/favicon-180.png"/><link rel="manifest" href="/site.webmanifest"/><link rel="shortcut icon" href="/favicon.svg" type="image/svg+xml"/><meta name="generator" content="Astro v7.2.8"/><meta name="generator" content="Starlight v0.40.0"/><meta property="og:title" content="Architecture"/><meta property="og:type" content="article"/><meta property="og:url" content="https://docs.spec-engine.dev/architecture/"/><meta property="og:locale" content="en"/><meta property="og:description" content="What the engine is made of, which seams it has, and what must never change"/><meta property="og:site_name" content="Spec Engine"/><meta name="twitter:card" content="summary_large_image"/><meta name="description" content="What the engine is made of, which seams it has, and what must never change"/><meta name="theme-color" content="#0F1214"/><meta property="og:image" content="https://docs.spec-engine.dev/og-spec-engine-docs.png"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta name="twitter:image" content="https://docs.spec-engine.dev/og-spec-engine-docs.png"/><script>
|
|
2
2
|
window.StarlightThemeProvider = (() => {
|
|
3
3
|
const storedTheme =
|
|
4
4
|
typeof localStorage !== 'undefined' && localStorage.getItem('starlight-theme');
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
};
|
|
26
26
|
})();
|
|
27
|
-
</script><template id="theme-icons"><svg aria-hidden="true" class="light astro-
|
|
27
|
+
</script><template id="theme-icons"><svg aria-hidden="true" class="light astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M5 12a1 1 0 0 0-1-1H3a1 1 0 0 0 0 2h1a1 1 0 0 0 1-1Zm.64 5-.71.71a1 1 0 0 0 0 1.41 1 1 0 0 0 1.41 0l.71-.71A1 1 0 0 0 5.64 17ZM12 5a1 1 0 0 0 1-1V3a1 1 0 0 0-2 0v1a1 1 0 0 0 1 1Zm5.66 2.34a1 1 0 0 0 .7-.29l.71-.71a1 1 0 1 0-1.41-1.41l-.66.71a1 1 0 0 0 0 1.41 1 1 0 0 0 .66.29Zm-12-.29a1 1 0 0 0 1.41 0 1 1 0 0 0 0-1.41l-.71-.71a1.004 1.004 0 1 0-1.43 1.41l.73.71ZM21 11h-1a1 1 0 0 0 0 2h1a1 1 0 0 0 0-2Zm-2.64 6A1 1 0 0 0 17 18.36l.71.71a1 1 0 0 0 1.41 0 1 1 0 0 0 0-1.41l-.76-.66ZM12 6.5a5.5 5.5 0 1 0 5.5 5.5A5.51 5.51 0 0 0 12 6.5Zm0 9a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7Zm0 3.5a1 1 0 0 0-1 1v1a1 1 0 0 0 2 0v-1a1 1 0 0 0-1-1Z"/></svg><svg aria-hidden="true" class="dark astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21.64 13a1 1 0 0 0-1.05-.14 8.049 8.049 0 0 1-3.37.73 8.15 8.15 0 0 1-8.14-8.1 8.59 8.59 0 0 1 .25-2A1 1 0 0 0 8 2.36a10.14 10.14 0 1 0 14 11.69 1 1 0 0 0-.36-1.05Zm-9.5 6.69A8.14 8.14 0 0 1 7.08 5.22v.27a10.15 10.15 0 0 0 10.14 10.14 9.784 9.784 0 0 0 2.1-.22 8.11 8.11 0 0 1-7.18 4.32v-.04Z"/></svg><svg aria-hidden="true" class="auto astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21 14h-1V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7H3a1 1 0 0 0-1 1v2a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-2a1 1 0 0 0-1-1ZM6 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7H6V7Zm14 10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1h16v1Z"/></svg></template><link rel="stylesheet" href="/_astro/print.ehPL0gv-.css" media="print"><link rel="stylesheet" href="/_astro/common.BPl3nku0.css"><link rel="stylesheet" href="/_astro/components.BeLFs6cp.css"><script type="module" src="/_astro/page.cNngjUgL.js"></script></head><body class="astro-kmpt7d6z"><a href="#_top" class="astro-truhxte5">Skip to content</a><div class="page sl-flex astro-qobrlvtk"><header class="header astro-qobrlvtk"><div class="header astro-ppjdlws2"><div class="title-wrapper sl-flex astro-ppjdlws2"><a href="/" class="site-title sl-flex astro-mcf2q6ee"><img class="light:sl-hidden print:hidden astro-mcf2q6ee" alt="Spec Engine" src="/_astro/spec-mark-white.DJBFLLUP.svg" width="512" height="512"><img class="dark:sl-hidden print:block astro-mcf2q6ee" alt="Spec Engine" src="/_astro/spec-mark-black.ZCN22lJi.svg" width="512" height="512"><span class="astro-mcf2q6ee" translate="no">Spec Engine</span></a></div><div class="sl-flex print:hidden astro-ppjdlws2"><site-search class="astro-ppjdlws2 astro-f4jwivv6" data-translations="{"placeholder":"Search"}"><button data-open-modal disabled aria-label="Search" aria-keyshortcuts="Control+K" class="astro-f4jwivv6"><svg aria-hidden="true" class="astro-f4jwivv6 astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21.71 20.29 18 16.61A9 9 0 1 0 16.61 18l3.68 3.68a.999.999 0 0 0 1.42 0 1 1 0 0 0 0-1.39ZM11 18a7 7 0 1 1 0-14 7 7 0 0 1 0 14Z"/></svg><span class="sl-hidden md:sl-block astro-f4jwivv6" aria-hidden="true">Search</span><kbd class="sl-hidden md:sl-flex astro-f4jwivv6" style="display: none;"><kbd class="astro-f4jwivv6">Ctrl</kbd><kbd class="astro-f4jwivv6">K</kbd></kbd></button><dialog style="padding:0" aria-label="Search" class="astro-f4jwivv6"><div class="dialog-frame sl-flex astro-f4jwivv6"><button data-close-modal class="sl-flex md:sl-hidden astro-f4jwivv6">Cancel</button><div class="search-container astro-f4jwivv6"><div id="starlight__search" class="astro-f4jwivv6"></div></div></div></dialog></site-search><script>
|
|
28
28
|
(() => {
|
|
29
29
|
const openBtn = document.querySelector('button[data-open-modal]');
|
|
30
30
|
const shortcut = openBtn?.querySelector('kbd');
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
}
|
|
37
37
|
shortcut.style.display = '';
|
|
38
38
|
})();
|
|
39
|
-
</script
|
|
39
|
+
</script><script type="module" src="/_astro/Search.astro_astro_type_script_index_0_lang.Djc9ZKGJ.js"></script></div><div class="sl-hidden md:sl-flex print:hidden right-group astro-ppjdlws2"><div class="sl-flex social-icons astro-ppjdlws2"><a href="https://github.com/spec-engine/spec-engine" rel="me" class="sl-flex astro-n6yxnlqb"><span class="sr-only astro-n6yxnlqb">GitHub</span><svg aria-hidden="true" class="astro-n6yxnlqb astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M12 .3a12 12 0 0 0-3.8 23.38c.6.12.83-.26.83-.57L9 21.07c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.08-.74.09-.73.09-.73 1.2.09 1.83 1.24 1.83 1.24 1.08 1.83 2.81 1.3 3.5 1 .1-.78.42-1.31.76-1.61-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.64 1.66.24 2.88.12 3.18a4.65 4.65 0 0 1 1.23 3.22c0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.1.81 2.22l-.01 3.29c0 .31.2.69.82.57A12 12 0 0 0 12 .3Z"/></svg></a></div><starlight-theme-select><label style="--sl-select-width: 6.25em" class="astro-bqlrlpix"><span class="sr-only astro-bqlrlpix">Select theme</span><svg aria-hidden="true" class="icon label-icon astro-bqlrlpix astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21 14h-1V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7H3a1 1 0 0 0-1 1v2a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-2a1 1 0 0 0-1-1ZM6 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7H6V7Zm14 10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1h16v1Z"/></svg><select autocomplete="off" class="astro-bqlrlpix"><option value="dark" class="astro-bqlrlpix">Dark</option><option value="light" class="astro-bqlrlpix">Light</option><option value="auto" selected class="astro-bqlrlpix">Auto</option></select><svg aria-hidden="true" class="icon caret astro-bqlrlpix astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M17 9.17a1 1 0 0 0-1.41 0L12 12.71 8.46 9.17a1 1 0 1 0-1.41 1.42l4.24 4.24a1.002 1.002 0 0 0 1.42 0L17 10.59a1.002 1.002 0 0 0 0-1.42Z"/></svg></label></starlight-theme-select><script>
|
|
40
40
|
StarlightThemeProvider.updatePickers();
|
|
41
|
-
</script
|
|
41
|
+
</script><script type="module">var e=`starlight-theme`,t=e=>e===`auto`||e===`dark`||e===`light`?e:`auto`,n=()=>t(typeof localStorage<`u`&&localStorage.getItem(e));function r(t){typeof localStorage<`u`&&localStorage.setItem(e,t===`light`||t===`dark`?t:``)}var i=()=>matchMedia(`(prefers-color-scheme: light)`).matches?`light`:`dark`;function a(e){StarlightThemeProvider.updatePickers(e),document.documentElement.dataset.theme=e===`auto`?i():e,r(e)}matchMedia(`(prefers-color-scheme: light)`).addEventListener(`change`,()=>{n()===`auto`&&a(`auto`)});var o=class extends HTMLElement{constructor(){super(),a(n()),this.querySelector(`select`)?.addEventListener(`change`,e=>{e.currentTarget instanceof HTMLSelectElement&&a(t(e.currentTarget.value))})}};customElements.define(`starlight-theme-select`,o);</script><script type="module">var e=class extends HTMLElement{constructor(){super();let e=this.querySelector(`select`);e&&(e.addEventListener(`change`,e=>{e.currentTarget instanceof HTMLSelectElement&&(window.location.pathname=e.currentTarget.value)}),window.addEventListener(`pageshow`,t=>{if(!t.persisted)return;let n=e.querySelector(`option[selected]`)?.index;n!==e.selectedIndex&&(e.selectedIndex=n??0)}))}};customElements.define(`starlight-lang-select`,e);</script></div></div></header><nav class="sidebar print:hidden astro-qobrlvtk" aria-label="Main"><starlight-menu-button class="print:hidden astro-ehruq3jl"><button aria-expanded="false" aria-label="Menu" aria-controls="starlight__sidebar" class="sl-flex md:sl-hidden astro-ehruq3jl"><svg aria-hidden="true" class="open-menu astro-ehruq3jl astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M3 8h18a1 1 0 1 0 0-2H3a1 1 0 0 0 0 2Zm18 8H3a1 1 0 0 0 0 2h18a1 1 0 0 0 0-2Zm0-5H3a1 1 0 0 0 0 2h18a1 1 0 0 0 0-2Z"/></svg><svg aria-hidden="true" class="close-menu astro-ehruq3jl astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="m13.41 12 6.3-6.29a1.004 1.004 0 1 0-1.42-1.42L12 10.59l-6.29-6.3a1.004 1.004 0 0 0-1.42 1.42l6.3 6.29-6.3 6.29a1 1 0 0 0 0 1.42.998.998 0 0 0 1.42 0l6.29-6.3 6.29 6.3a.999.999 0 0 0 1.42 0 1 1 0 0 0 0-1.42L13.41 12Z"/></svg></button></starlight-menu-button><script type="module">var e=class extends HTMLElement{btn=this.querySelector(`button`);constructor(){super(),this.btn.addEventListener(`click`,()=>this.toggleExpanded());let e=this.closest(`nav`);e&&e.addEventListener(`keyup`,e=>this.closeOnEscape(e))}setExpanded(e){this.setAttribute(`aria-expanded`,String(e)),document.body.toggleAttribute(`data-mobile-menu-expanded`,e)}toggleExpanded(){this.setExpanded(this.getAttribute(`aria-expanded`)!==`true`)}closeOnEscape(e){e.code===`Escape`&&(this.setExpanded(!1),this.btn.focus())}};customElements.define(`starlight-menu-button`,e);</script><div id="starlight__sidebar" class="sidebar-pane astro-qobrlvtk"><div class="sidebar-content sl-flex astro-qobrlvtk"><sl-sidebar-state-persist data-hash="1dxffrg" class="astro-dm3fcvht"><script aria-hidden="true">
|
|
42
42
|
(() => {
|
|
43
43
|
try {
|
|
44
44
|
if (!matchMedia('(min-width: 50em)').matches) return;
|
|
@@ -61,387 +61,387 @@
|
|
|
61
61
|
);
|
|
62
62
|
} catch {}
|
|
63
63
|
})();
|
|
64
|
-
</script
|
|
64
|
+
</script><ul class="top-level astro-3rgm4o2r"><li class="astro-3rgm4o2r"><a href="/overview/" class="large astro-3rgm4o2r"><span class="astro-3rgm4o2r">Overview</span></a></li><li class="astro-3rgm4o2r"><a href="/getting-started/" class="large astro-3rgm4o2r"><span class="astro-3rgm4o2r">Getting Started</span></a></li><li class="astro-3rgm4o2r"><a href="/architecture/" aria-current="page" class="large astro-3rgm4o2r"><span class="astro-3rgm4o2r">Architecture</span></a></li><li class="astro-3rgm4o2r"><a href="/platform-mapping/" class="large astro-3rgm4o2r"><span class="astro-3rgm4o2r">Platform Mapping</span></a></li><li class="astro-3rgm4o2r"><a href="/commands/" class="large astro-3rgm4o2r"><span class="astro-3rgm4o2r">Commands</span></a></li><li class="astro-3rgm4o2r"><a href="/format/" class="large astro-3rgm4o2r"><span class="astro-3rgm4o2r">SPEC.json Format</span></a></li><li class="astro-3rgm4o2r"><a href="/tags/" class="large astro-3rgm4o2r"><span class="astro-3rgm4o2r">Tags</span></a></li><li class="astro-3rgm4o2r"><a href="/checks/" class="large astro-3rgm4o2r"><span class="astro-3rgm4o2r">Integrity Checks</span></a></li><li class="astro-3rgm4o2r"><details open class="astro-3rgm4o2r"><summary class="astro-3rgm4o2r"><span class="group-label astro-3rgm4o2r"><span class="large astro-3rgm4o2r">Guides</span></span><svg aria-hidden="true" class="caret astro-3rgm4o2r astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg></summary><sl-sidebar-restore data-index="0"></sl-sidebar-restore><ul class="astro-3rgm4o2r"><li class="astro-3rgm4o2r"><a href="/guides/adoption/" class="astro-3rgm4o2r"><span class="astro-3rgm4o2r">Adoption Guide</span></a></li><li class="astro-3rgm4o2r"><a href="/guides/platform-setup/" class="astro-3rgm4o2r"><span class="astro-3rgm4o2r">Platform Setup</span></a></li><li class="astro-3rgm4o2r"><a href="/guides/single-repo/" class="astro-3rgm4o2r"><span class="astro-3rgm4o2r">Single Repo (Rung 1)</span></a></li></ul></details></li><li class="astro-3rgm4o2r"><a href="/agent-reference/" class="large astro-3rgm4o2r"><span class="astro-3rgm4o2r">Agent Reference</span></a></li></ul><script aria-hidden="true">
|
|
65
65
|
(() => {
|
|
66
66
|
const scroller = document.getElementById('starlight__sidebar');
|
|
67
67
|
if (!window._starlightScrollRestore || !scroller) return;
|
|
68
68
|
scroller.scrollTop = window._starlightScrollRestore;
|
|
69
69
|
delete window._starlightScrollRestore;
|
|
70
70
|
})();
|
|
71
|
-
</script
|
|
71
|
+
</script></sl-sidebar-state-persist><div class="md:sl-hidden"><div class="mobile-preferences sl-flex astro-hclhd3l6"><div class="social-icons astro-hclhd3l6"><a href="https://github.com/spec-engine/spec-engine" rel="me" class="sl-flex astro-n6yxnlqb"><span class="sr-only astro-n6yxnlqb">GitHub</span><svg aria-hidden="true" class="astro-n6yxnlqb astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M12 .3a12 12 0 0 0-3.8 23.38c.6.12.83-.26.83-.57L9 21.07c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.08-.74.09-.73.09-.73 1.2.09 1.83 1.24 1.83 1.24 1.08 1.83 2.81 1.3 3.5 1 .1-.78.42-1.31.76-1.61-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.64 1.66.24 2.88.12 3.18a4.65 4.65 0 0 1 1.23 3.22c0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.1.81 2.22l-.01 3.29c0 .31.2.69.82.57A12 12 0 0 0 12 .3Z"/></svg></a></div><starlight-theme-select><label style="--sl-select-width: 6.25em" class="astro-bqlrlpix"><span class="sr-only astro-bqlrlpix">Select theme</span><svg aria-hidden="true" class="icon label-icon astro-bqlrlpix astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21 14h-1V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7H3a1 1 0 0 0-1 1v2a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-2a1 1 0 0 0-1-1ZM6 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7H6V7Zm14 10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1h16v1Z"/></svg><select autocomplete="off" class="astro-bqlrlpix"><option value="dark" class="astro-bqlrlpix">Dark</option><option value="light" class="astro-bqlrlpix">Light</option><option value="auto" selected class="astro-bqlrlpix">Auto</option></select><svg aria-hidden="true" class="icon caret astro-bqlrlpix astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M17 9.17a1 1 0 0 0-1.41 0L12 12.71 8.46 9.17a1 1 0 1 0-1.41 1.42l4.24 4.24a1.002 1.002 0 0 0 1.42 0L17 10.59a1.002 1.002 0 0 0 0-1.42Z"/></svg></label></starlight-theme-select><script>
|
|
72
72
|
StarlightThemeProvider.updatePickers();
|
|
73
|
-
</script
|
|
73
|
+
</script></div></div></div></div></nav><div class="main-frame astro-qobrlvtk"><script type="module">var e=document.getElementById(`starlight__sidebar`),t=e?.querySelector(`sl-sidebar-state-persist`),n=`sl-sidebar-state`,r=()=>{let r=[],i=t?.dataset.hash||``;try{let e=sessionStorage.getItem(n),t=JSON.parse(e||`{}`);Array.isArray(t.open)&&t.hash===i&&(r=t.open)}catch{}return{hash:i,open:r,scroll:e?.scrollTop||0}},i=e=>{try{sessionStorage.setItem(n,JSON.stringify(e))}catch{}},a=()=>i(r()),o=(e,t)=>{let n=r();n.open[t]=e,i(n)};t?.addEventListener(`click`,e=>{if(!(e.target instanceof Element))return;let t=e.target.closest(`summary`)?.closest(`details`);if(!t)return;let n=t.querySelector(`sl-sidebar-restore`),r=parseInt(n?.dataset.index||``);isNaN(r)||o(!t.open,r)}),addEventListener(`visibilitychange`,()=>{document.visibilityState===`hidden`&&a()}),addEventListener(`pageHide`,a);</script><div class="lg:sl-flex astro-iv7ihhtf"><aside class="right-sidebar-container print:hidden astro-iv7ihhtf"><div class="right-sidebar astro-iv7ihhtf"><div class="lg:sl-hidden astro-dfaa6j3s"><mobile-starlight-toc data-min-h="2" data-max-h="3" class="astro-hhhdejk6"><nav aria-labelledby="starlight__on-this-page--mobile" class="astro-hhhdejk6"><details id="starlight__mobile-toc" class="astro-hhhdejk6"><summary id="starlight__on-this-page--mobile" class="sl-flex astro-hhhdejk6"><span class="toggle sl-flex astro-hhhdejk6">On this page<svg aria-hidden="true" class="caret astro-hhhdejk6 astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg></span><span class="display-current astro-hhhdejk6"></span></summary><div class="dropdown astro-hhhdejk6"><ul class="isMobile astro-l6rvz6dz" style="--depth: 0;"><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#_top" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Overview</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#components" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Components</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#operations" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Operations</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#the-single-seams" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">The single seams</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#read-path" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Read path</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#write-path" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Write path</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#http-path" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">HTTP path</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#invariants" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Invariants</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#anti-patterns" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Anti-patterns</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#error-handling" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Error handling</span></a></li></ul></div></details></nav></mobile-starlight-toc><script type="module" src="/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.BcSo_yiZ.js"></script></div><div class="right-sidebar-panel sl-hidden lg:sl-block astro-dfaa6j3s"><div class="sl-container astro-dfaa6j3s"><starlight-toc data-min-h="2" data-max-h="3"><nav aria-labelledby="starlight__on-this-page"><h2 id="starlight__on-this-page">On this page</h2><ul class="astro-l6rvz6dz" style="--depth: 0;"><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#_top" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Overview</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#components" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Components</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#operations" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Operations</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#the-single-seams" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">The single seams</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#read-path" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Read path</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#write-path" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Write path</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#http-path" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">HTTP path</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#invariants" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Invariants</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#anti-patterns" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Anti-patterns</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#error-handling" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Error handling</span></a></li></ul></nav></starlight-toc><script type="module" src="/_astro/TableOfContents.astro_astro_type_script_index_0_lang.Csloo1VZ.js"></script></div></div></div></aside><div class="main-pane astro-iv7ihhtf"><main data-pagefind-body class="astro-kmpt7d6z" lang="en" dir="ltr"><div class="content-panel astro-d3w5v5qg"><div class="sl-container astro-d3w5v5qg"><h1 id="_top" class="astro-elp5pbgd">Architecture</h1></div></div><div class="content-panel astro-d3w5v5qg"><div class="sl-container astro-d3w5v5qg"><div class="sl-markdown-content"><p>Spec Engine is a derived-index pipeline. Truth lives in git as <code dir="auto">spec-engine/<KEY>/SPEC.json</code> files plus <code dir="auto">@spec</code> tags in code. Everything else is computed from those two inputs and can be thrown away.</p>
|
|
74
74
|
<div class="expressive-code"><link rel="stylesheet" href="/_astro/ec.v4551.css"><script type="module" src="/_astro/ec.0vx5m.js"></script><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="text"><code><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">CLI (citty) HTTP (Hono) MCP (stdio)</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">engine/src/cli.ts engine/src/server/ engine/src/server/mcp.ts</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">│ │ │</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">▼ ▼ ▼</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">┌──────────────────────────────────────────────────────────┐</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">│ Surfaces: parse input, call an operation, render │</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">│ engine/src/commands/*.ts server/api.ts server/mcp.ts │</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">└───────────────────────────┬──────────────────────────────┘</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">▼</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">┌──────────────────────────────────────────────────────────┐</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">│ Operations: one function per verb, typed input, typed │</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">│ result, no process exit, no console │</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">│ engine/src/operations/*.ts │</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">└───────────────┬──────────────────────────┬───────────────┘</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">│ │</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">write path│ read path│</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">▼ ▼</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">┌────────────────────────┐ ┌──────────────────────────────┐</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">│ authoring/ parser/ │ │ indexer/pipeline.ts runIndex │</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">│ one seam: │ │ discover → parse → scan → │</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">│ validateAndWrite │ │ validate → one write tx │</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">│ (no bun:sqlite) │ │ then check/ guard/ map/ … │</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">└───────────┬────────────┘ └──────────────┬───────────────┘</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">▼ ▼</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">┌────────────────────────┐ ┌──────────────────────────────┐</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">│ CANONICAL TRUTH (git) │──▶│ DERIVED INDEX (disposable) │</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">│ spec-engine/*/SPEC.json│ │ .spec-engine/index.sqlite │</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">│ + @spec tags in code │ │ via storage/sqlite.ts only │</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#d6deeb;--1:#403f53"> </span></span><span style="--0:#d6deeb;--1:#403f53">└────────────────────────┘ └──────────────────────────────┘</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button title="Copy to clipboard" data-copied="Copied!" data-code=" CLI (citty) HTTP (Hono) MCP (stdio) engine/src/cli.ts engine/src/server/ engine/src/server/mcp.ts │ │ │ ▼ ▼ ▼ ┌──────────────────────────────────────────────────────────┐ │ Surfaces: parse input, call an operation, render │ │ engine/src/commands/*.ts server/api.ts server/mcp.ts │ └───────────────────────────┬──────────────────────────────┘ ▼ ┌──────────────────────────────────────────────────────────┐ │ Operations: one function per verb, typed input, typed │ │ result, no process exit, no console │ │ engine/src/operations/*.ts │ └───────────────┬──────────────────────────┬───────────────┘ │ │ write path│ read path│ ▼ ▼ ┌────────────────────────┐ ┌──────────────────────────────┐ │ authoring/ parser/ │ │ indexer/pipeline.ts runIndex │ │ one seam: │ │ discover → parse → scan → │ │ validateAndWrite │ │ validate → one write tx │ │ (no bun:sqlite) │ │ then check/ guard/ map/ … │ └───────────┬────────────┘ └──────────────┬───────────────┘ ▼ ▼ ┌────────────────────────┐ ┌──────────────────────────────┐ │ CANONICAL TRUTH (git) │──▶│ DERIVED INDEX (disposable) │ │ spec-engine/*/SPEC.json│ │ .spec-engine/index.sqlite │ │ + @spec tags in code │ │ via storage/sqlite.ts only │ └────────────────────────┘ └──────────────────────────────┘"><div></div></button></div></figure></div>
|
|
75
|
-
<div class="sl-heading-wrapper level-h2"><h2 id="components">Components</h2><a class="sl-anchor-link" href="#components"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
<div class="sl-heading-wrapper level-h2"><h2 id="operations">Operations</h2><a class="sl-anchor-link" href="#operations"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore
|
|
75
|
+
<div class="sl-heading-wrapper level-h2"><h2 id="components">Components</h2><a class="sl-anchor-link" href="#components"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore>Section titled “Components”</span></a></div>
|
|
76
|
+
<table>
|
|
77
|
+
<thead>
|
|
78
|
+
<tr>
|
|
79
|
+
<th>Component</th>
|
|
80
|
+
<th>Responsibility</th>
|
|
81
|
+
<th>Path</th>
|
|
82
|
+
</tr>
|
|
83
|
+
</thead>
|
|
84
|
+
<tbody>
|
|
85
|
+
<tr>
|
|
86
|
+
<td>CLI root</td>
|
|
87
|
+
<td>Register subcommands with lazy imports so the compiled binary starts fast</td>
|
|
88
|
+
<td><code dir="auto">packages/engine/src/cli.ts</code></td>
|
|
89
|
+
</tr>
|
|
90
|
+
<tr>
|
|
91
|
+
<td>Command layer</td>
|
|
92
|
+
<td>One file per subcommand: flags, platform-dir resolution, exit codes, text or <code dir="auto">--json</code> rendering</td>
|
|
93
|
+
<td><code dir="auto">packages/engine/src/commands/</code></td>
|
|
94
|
+
</tr>
|
|
95
|
+
<tr>
|
|
96
|
+
<td>Operations</td>
|
|
97
|
+
<td>One function per verb. The CLI, the API, and MCP all call these</td>
|
|
98
|
+
<td><code dir="auto">packages/engine/src/operations/</code></td>
|
|
99
|
+
</tr>
|
|
100
|
+
<tr>
|
|
101
|
+
<td>Discovery</td>
|
|
102
|
+
<td>Take membership and shape from platform-map, read each member’s pin, derive the platform version. See <a href="/platform-mapping/">Platform Mapping</a></td>
|
|
103
|
+
<td><code dir="auto">packages/engine/src/indexer/discover.ts</code></td>
|
|
104
|
+
</tr>
|
|
105
|
+
<tr>
|
|
106
|
+
<td>Parser</td>
|
|
107
|
+
<td>Read and validate <code dir="auto">SPEC.json</code> envelopes into typed records</td>
|
|
108
|
+
<td><code dir="auto">packages/engine/src/parser/</code></td>
|
|
109
|
+
</tr>
|
|
110
|
+
<tr>
|
|
111
|
+
<td>Scanner</td>
|
|
112
|
+
<td>Walk member repos, extract <code dir="auto">@spec</code> tags, decide implements vs verifies from the path</td>
|
|
113
|
+
<td><code dir="auto">packages/engine/src/scanner/</code></td>
|
|
114
|
+
</tr>
|
|
115
|
+
<tr>
|
|
116
|
+
<td>Index pipeline</td>
|
|
117
|
+
<td><code dir="auto">runIndex</code>: the one composition of discover, parse, scan, validate, write</td>
|
|
118
|
+
<td><code dir="auto">packages/engine/src/indexer/pipeline.ts</code></td>
|
|
119
|
+
</tr>
|
|
120
|
+
<tr>
|
|
121
|
+
<td>Storage</td>
|
|
122
|
+
<td>The only <code dir="auto">bun:sqlite</code> importer. Open, cold reset, upserts, queries, <code dir="auto">build_id</code></td>
|
|
123
|
+
<td><code dir="auto">packages/engine/src/storage/sqlite.ts</code></td>
|
|
124
|
+
</tr>
|
|
125
|
+
<tr>
|
|
126
|
+
<td>Schema</td>
|
|
127
|
+
<td>Tables, the FTS5 table, and the <code dir="auto">coverage</code>, <code dir="auto">drift</code>, <code dir="auto">term_drift</code>, <code dir="auto">provenance_matrix</code> views</td>
|
|
128
|
+
<td><code dir="auto">packages/shared/src/schema.ts</code></td>
|
|
129
|
+
</tr>
|
|
130
|
+
<tr>
|
|
131
|
+
<td>Storage contract</td>
|
|
132
|
+
<td>The <code dir="auto">Storage</code> interface and row types every surface reads through</td>
|
|
133
|
+
<td><code dir="auto">packages/shared/src/storage.ts</code></td>
|
|
134
|
+
</tr>
|
|
135
|
+
<tr>
|
|
136
|
+
<td>Checks</td>
|
|
137
|
+
<td>Diagnostic producers, SQL and non-SQL: grammar, file refs, removal, status flips, proofs, CODEOWNERS</td>
|
|
138
|
+
<td><code dir="auto">packages/engine/src/check/</code></td>
|
|
139
|
+
</tr>
|
|
140
|
+
<tr>
|
|
141
|
+
<td>Loss guard</td>
|
|
142
|
+
<td>Diff the requirement derivation at a git ref against the worktree</td>
|
|
143
|
+
<td><code dir="auto">packages/engine/src/guard/</code></td>
|
|
144
|
+
</tr>
|
|
145
|
+
<tr>
|
|
146
|
+
<td>Authoring</td>
|
|
147
|
+
<td>Domain scaffolds, next-id allocation, <code dir="auto">@</code> file refs, statement grammar at write time</td>
|
|
148
|
+
<td><code dir="auto">packages/engine/src/authoring/</code></td>
|
|
149
|
+
</tr>
|
|
150
|
+
<tr>
|
|
151
|
+
<td>Projections</td>
|
|
152
|
+
<td>One directory per computed answer, each with a <code dir="auto">format.ts</code> for text mode</td>
|
|
153
|
+
<td><code dir="auto">map/</code>, <code dir="auto">query/</code>, <code dir="auto">resolve/</code>, <code dir="auto">relations/</code>, <code dir="auto">propagation/</code>, <code dir="auto">provenance/</code>, <code dir="auto">gate/</code>, <code dir="auto">results/</code></td>
|
|
154
|
+
</tr>
|
|
155
|
+
<tr>
|
|
156
|
+
<td>HTTP API</td>
|
|
157
|
+
<td>Hono routes over <code dir="auto">Storage</code>, read routes always on, write routes flag-gated</td>
|
|
158
|
+
<td><code dir="auto">packages/engine/src/server/api.ts</code></td>
|
|
159
|
+
</tr>
|
|
160
|
+
<tr>
|
|
161
|
+
<td>MCP server</td>
|
|
162
|
+
<td>Eleven tools and one prompt, same JSON as the CLI’s <code dir="auto">--json</code></td>
|
|
163
|
+
<td><code dir="auto">packages/engine/src/server/mcp.ts</code></td>
|
|
164
|
+
</tr>
|
|
165
|
+
<tr>
|
|
166
|
+
<td>Webapp</td>
|
|
167
|
+
<td>Server-rendered pages. No filesystem, no sqlite, no engine import</td>
|
|
168
|
+
<td><code dir="auto">packages/webapp/src/</code></td>
|
|
169
|
+
</tr>
|
|
170
|
+
<tr>
|
|
171
|
+
<td>Tracker</td>
|
|
172
|
+
<td>Optional read-only Linear adapter with a cache sidecar</td>
|
|
173
|
+
<td><code dir="auto">packages/tracker/src/</code></td>
|
|
174
|
+
</tr>
|
|
175
|
+
<tr>
|
|
176
|
+
<td>Docs site</td>
|
|
177
|
+
<td>This site, served offline by <code dir="auto">spec docs</code></td>
|
|
178
|
+
<td><code dir="auto">packages/site/</code></td>
|
|
179
|
+
</tr>
|
|
180
|
+
</tbody>
|
|
181
|
+
</table>
|
|
182
|
+
<div class="sl-heading-wrapper level-h2"><h2 id="operations">Operations</h2><a class="sl-anchor-link" href="#operations"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore>Section titled “Operations”</span></a></div>
|
|
183
183
|
<p>An operation takes typed input and returns typed data or a typed refusal. It never exits the process and never prints. Each surface maps a refusal to its own vocabulary: the CLI to exit 2, the API to a status, MCP to an error result.</p>
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
184
|
+
<table>
|
|
185
|
+
<thead>
|
|
186
|
+
<tr>
|
|
187
|
+
<th>Operation</th>
|
|
188
|
+
<th>Input</th>
|
|
189
|
+
<th>Result</th>
|
|
190
|
+
<th>CLI</th>
|
|
191
|
+
<th>HTTP</th>
|
|
192
|
+
<th>MCP</th>
|
|
193
|
+
</tr>
|
|
194
|
+
</thead>
|
|
195
|
+
<tbody>
|
|
196
|
+
<tr>
|
|
197
|
+
<td><code dir="auto">query</code></td>
|
|
198
|
+
<td>storage, text, limit</td>
|
|
199
|
+
<td>ranked hits, or <code dir="auto">usage</code> on an FTS5 grammar error</td>
|
|
200
|
+
<td><code dir="auto">spec query</code></td>
|
|
201
|
+
<td><code dir="auto">GET /api/query</code></td>
|
|
202
|
+
<td><code dir="auto">spec_query</code></td>
|
|
203
|
+
</tr>
|
|
204
|
+
<tr>
|
|
205
|
+
<td><code dir="auto">resolveFiles</code></td>
|
|
206
|
+
<td>storage, platform-relative files</td>
|
|
207
|
+
<td>the requirements tagged in them</td>
|
|
208
|
+
<td><code dir="auto">spec resolve</code></td>
|
|
209
|
+
<td><code dir="auto">GET /api/resolve?files=</code></td>
|
|
210
|
+
<td><code dir="auto">spec_resolve</code></td>
|
|
211
|
+
</tr>
|
|
212
|
+
<tr>
|
|
213
|
+
<td><code dir="auto">reqTags</code></td>
|
|
214
|
+
<td>storage, requirement id</td>
|
|
215
|
+
<td>every tag site, and whether the id is known</td>
|
|
216
|
+
<td><code dir="auto">spec resolve --req</code></td>
|
|
217
|
+
<td><code dir="auto">GET /api/resolve?req=</code></td>
|
|
218
|
+
<td><code dir="auto">spec_req_tags</code></td>
|
|
219
|
+
</tr>
|
|
220
|
+
<tr>
|
|
221
|
+
<td><code dir="auto">propagation</code></td>
|
|
222
|
+
<td>storage, requirement id</td>
|
|
223
|
+
<td>per-member migration state</td>
|
|
224
|
+
<td><code dir="auto">spec propagation</code></td>
|
|
225
|
+
<td><code dir="auto">GET /api/propagation/:id</code></td>
|
|
226
|
+
<td><code dir="auto">spec_propagation</code></td>
|
|
227
|
+
</tr>
|
|
228
|
+
<tr>
|
|
229
|
+
<td><code dir="auto">coverageReport</code></td>
|
|
230
|
+
<td>storage</td>
|
|
231
|
+
<td>per-domain rollup</td>
|
|
232
|
+
<td></td>
|
|
233
|
+
<td><code dir="auto">GET /api/report</code></td>
|
|
234
|
+
<td><code dir="auto">spec_coverage_report</code></td>
|
|
235
|
+
</tr>
|
|
236
|
+
<tr>
|
|
237
|
+
<td><code dir="auto">check</code></td>
|
|
238
|
+
<td>storage, platform dir, results file, base ref, flags</td>
|
|
239
|
+
<td>diagnostics, <code dir="auto">build_id</code>, red or green</td>
|
|
240
|
+
<td><code dir="auto">spec check</code></td>
|
|
241
|
+
<td></td>
|
|
242
|
+
<td><code dir="auto">spec_check</code></td>
|
|
243
|
+
</tr>
|
|
244
|
+
<tr>
|
|
245
|
+
<td><code dir="auto">nextId</code></td>
|
|
246
|
+
<td>platform dir, domain key or prefix</td>
|
|
247
|
+
<td>the resolved key and next unused id, or <code dir="auto">usage</code></td>
|
|
248
|
+
<td><code dir="auto">spec req</code></td>
|
|
249
|
+
<td></td>
|
|
250
|
+
<td><code dir="auto">spec_next_id</code></td>
|
|
251
|
+
</tr>
|
|
252
|
+
<tr>
|
|
253
|
+
<td><code dir="auto">mint</code></td>
|
|
254
|
+
<td>platform dir, key, statement, why, lives-in, relates, issue, status</td>
|
|
255
|
+
<td>the new id and file, or <code dir="auto">not_found</code> / <code dir="auto">usage</code> / <code dir="auto">invalid_domain_file</code></td>
|
|
256
|
+
<td><code dir="auto">spec req --text</code></td>
|
|
257
|
+
<td><code dir="auto">POST /api/requirements</code></td>
|
|
258
|
+
<td><code dir="auto">spec_req</code></td>
|
|
259
|
+
</tr>
|
|
260
|
+
<tr>
|
|
261
|
+
<td><code dir="auto">amend</code></td>
|
|
262
|
+
<td>platform dir, id, fields</td>
|
|
263
|
+
<td>the changed fields, or <code dir="auto">not_found</code> / <code dir="auto">conflict</code> / <code dir="auto">invalid_domain_file</code></td>
|
|
264
|
+
<td><code dir="auto">spec amend</code></td>
|
|
265
|
+
<td><code dir="auto">PUT /api/requirements/:id</code></td>
|
|
266
|
+
<td><code dir="auto">spec_amend</code></td>
|
|
267
|
+
</tr>
|
|
268
|
+
<tr>
|
|
269
|
+
<td><code dir="auto">supersede</code></td>
|
|
270
|
+
<td>platform dir, id, successor statement and fields, a fresh-tags callback</td>
|
|
271
|
+
<td>the successor id, the domain version, the retag worklist, or <code dir="auto">not_found</code> / <code dir="auto">conflict</code> / <code dir="auto">usage</code> / <code dir="auto">invalid_domain_file</code></td>
|
|
272
|
+
<td><code dir="auto">spec supersede</code></td>
|
|
273
|
+
<td><code dir="auto">POST /api/requirements/:id/supersede</code></td>
|
|
274
|
+
<td><code dir="auto">spec_supersede</code></td>
|
|
275
|
+
</tr>
|
|
276
|
+
<tr>
|
|
277
|
+
<td><code dir="auto">move</code></td>
|
|
278
|
+
<td>platform dir, id, target domain key, optional successor fields, a fresh-tags callback</td>
|
|
279
|
+
<td>both files, both versions, the retag worklist, or <code dir="auto">usage</code> / <code dir="auto">not_found</code> / <code dir="auto">conflict</code> / <code dir="auto">invalid_domain_file</code></td>
|
|
280
|
+
<td><code dir="auto">spec move</code></td>
|
|
281
|
+
<td><code dir="auto">POST /api/requirements/:id/move</code></td>
|
|
282
|
+
<td><code dir="auto">spec_move</code></td>
|
|
283
|
+
</tr>
|
|
284
|
+
<tr>
|
|
285
|
+
<td><code dir="auto">deprecate</code></td>
|
|
286
|
+
<td>platform dir, id, reason, a fresh-tags callback</td>
|
|
287
|
+
<td>the file and the tags still bound, or <code dir="auto">not_found</code> / <code dir="auto">conflict</code> / <code dir="auto">invalid_domain_file</code></td>
|
|
288
|
+
<td><code dir="auto">spec deprecate</code></td>
|
|
289
|
+
<td><code dir="auto">POST /api/requirements/:id/deprecate</code></td>
|
|
290
|
+
<td><code dir="auto">spec_deprecate</code></td>
|
|
291
|
+
</tr>
|
|
292
|
+
<tr>
|
|
293
|
+
<td><code dir="auto">accept</code></td>
|
|
294
|
+
<td>platform dir, id</td>
|
|
295
|
+
<td>the file, or <code dir="auto">not_found</code> / <code dir="auto">conflict</code> / <code dir="auto">invalid_domain_file</code></td>
|
|
296
|
+
<td><code dir="auto">spec accept</code></td>
|
|
297
|
+
<td><code dir="auto">POST /api/requirements/:id/accept</code></td>
|
|
298
|
+
<td><code dir="auto">spec_accept</code></td>
|
|
299
|
+
</tr>
|
|
300
|
+
<tr>
|
|
301
|
+
<td><code dir="auto">mintTerm</code>, <code dir="auto">listTerms</code>, <code dir="auto">reviseTerm</code>, <code dir="auto">confirmTerm</code></td>
|
|
302
|
+
<td>platform dir, term fields or ids</td>
|
|
303
|
+
<td>the term id, the store rows, the bumped version, or the re-pinned citation; <code dir="auto">not_found</code> / <code dir="auto">conflict</code> / <code dir="auto">invalid_domain_file</code></td>
|
|
304
|
+
<td><code dir="auto">spec term</code></td>
|
|
305
|
+
<td></td>
|
|
306
|
+
<td></td>
|
|
307
|
+
</tr>
|
|
308
|
+
<tr>
|
|
309
|
+
<td><code dir="auto">coverageMatrix</code></td>
|
|
310
|
+
<td>storage</td>
|
|
311
|
+
<td>requirement × repo rows</td>
|
|
312
|
+
<td><code dir="auto">spec map</code></td>
|
|
313
|
+
<td><code dir="auto">GET /api/coverage</code></td>
|
|
314
|
+
<td></td>
|
|
315
|
+
</tr>
|
|
316
|
+
<tr>
|
|
317
|
+
<td><code dir="auto">getRecord</code></td>
|
|
318
|
+
<td>storage, requirement id</td>
|
|
319
|
+
<td>one full <code dir="auto">Requirement</code> row, or null</td>
|
|
320
|
+
<td><code dir="auto">spec get</code></td>
|
|
321
|
+
<td><code dir="auto">GET /api/requirements/:id</code></td>
|
|
322
|
+
<td><code dir="auto">spec_get</code></td>
|
|
323
|
+
</tr>
|
|
324
|
+
<tr>
|
|
325
|
+
<td><code dir="auto">listRecords</code></td>
|
|
326
|
+
<td>storage, optional key and status</td>
|
|
327
|
+
<td>every <code dir="auto">Requirement</code> row in (key, seq) order</td>
|
|
328
|
+
<td><code dir="auto">spec list</code></td>
|
|
329
|
+
<td><code dir="auto">GET /api/requirements</code></td>
|
|
330
|
+
<td><code dir="auto">spec_list</code></td>
|
|
331
|
+
</tr>
|
|
332
|
+
<tr>
|
|
333
|
+
<td><code dir="auto">relations</code></td>
|
|
334
|
+
<td>storage</td>
|
|
335
|
+
<td><code dir="auto">relates</code> links</td>
|
|
336
|
+
<td><code dir="auto">spec relations</code></td>
|
|
337
|
+
<td><code dir="auto">GET /api/relations</code></td>
|
|
338
|
+
<td></td>
|
|
339
|
+
</tr>
|
|
340
|
+
<tr>
|
|
341
|
+
<td><code dir="auto">provenance</code></td>
|
|
342
|
+
<td>storage, optional issue id</td>
|
|
343
|
+
<td>provenance matrix rows</td>
|
|
344
|
+
<td><code dir="auto">spec provenance</code></td>
|
|
345
|
+
<td><code dir="auto">GET /api/provenance</code></td>
|
|
346
|
+
<td></td>
|
|
347
|
+
</tr>
|
|
348
|
+
<tr>
|
|
349
|
+
<td><code dir="auto">guard</code></td>
|
|
350
|
+
<td>storage, platform dir, git ref</td>
|
|
351
|
+
<td>the losses a change is about to cause</td>
|
|
352
|
+
<td><code dir="auto">spec guard</code></td>
|
|
353
|
+
<td></td>
|
|
354
|
+
<td></td>
|
|
355
|
+
</tr>
|
|
356
|
+
<tr>
|
|
357
|
+
<td><code dir="auto">gate</code></td>
|
|
358
|
+
<td>storage, platform dir, repo, requirement id</td>
|
|
359
|
+
<td>the gate outcome and <code dir="auto">build_id</code>, or <code dir="auto">usage</code> for an unknown repo</td>
|
|
360
|
+
<td><code dir="auto">spec gate</code></td>
|
|
361
|
+
<td></td>
|
|
362
|
+
<td></td>
|
|
363
|
+
</tr>
|
|
364
|
+
<tr>
|
|
365
|
+
<td><code dir="auto">resolveMemberPin</code>, <code dir="auto">writeMemberConfig</code></td>
|
|
366
|
+
<td>repo dir, pin override, force</td>
|
|
367
|
+
<td>the pin and its source; wrote or already configured, or <code dir="auto">usage</code> / <code dir="auto">conflict</code></td>
|
|
368
|
+
<td><code dir="auto">spec init</code></td>
|
|
369
|
+
<td></td>
|
|
370
|
+
<td></td>
|
|
371
|
+
</tr>
|
|
372
|
+
<tr>
|
|
373
|
+
<td><code dir="auto">newDomain</code>, <code dir="auto">listDomains</code>, <code dir="auto">setDomainGrammar</code></td>
|
|
374
|
+
<td>platform dir, key</td>
|
|
375
|
+
<td>the scaffolded file, or <code dir="auto">usage</code> / <code dir="auto">conflict</code> / <code dir="auto">invalid_domain_file</code>; the <code dir="auto">{ key, scope }</code> rows; the written <code dir="auto">grammar</code> / <code dir="auto">grammarSeverity</code>, or <code dir="auto">usage</code> / <code dir="auto">not_found</code> / <code dir="auto">invalid_domain_file</code></td>
|
|
376
|
+
<td><code dir="auto">spec domain</code></td>
|
|
377
|
+
<td></td>
|
|
378
|
+
<td></td>
|
|
379
|
+
</tr>
|
|
380
|
+
<tr>
|
|
381
|
+
<td><code dir="auto">writeGlossary</code>, <code dir="auto">migrateGlossary</code>, <code dir="auto">checkGlossary</code></td>
|
|
382
|
+
<td>platform dir</td>
|
|
383
|
+
<td>the generated count, the migrated count or a skip, clean or drift</td>
|
|
384
|
+
<td><code dir="auto">spec glossary</code></td>
|
|
385
|
+
<td></td>
|
|
386
|
+
<td></td>
|
|
387
|
+
</tr>
|
|
388
|
+
</tbody>
|
|
389
|
+
</table>
|
|
390
390
|
<p>Reads take an open <code dir="auto">Storage</code> handle because the surface owns the handle’s lifetime: the CLI and MCP open one per call through <code dir="auto">withIndex</code>, the API keeps one for the life of the server. Writes take the platform directory because they edit <code dir="auto">SPEC.json</code> files. A lifecycle write takes a fresh-tags callback for its worklist, so a one-shot surface cold-rebuilds a throwaway index while the API re-indexes into the handle it keeps. Every guard runs before the first byte is written (REQ-038 <!-- @spec REQ-038 -->), and <code dir="auto">operations/parity.test.ts</code> proves each surface writes the same envelope.</p>
|
|
391
|
-
<div class="sl-heading-wrapper level-h2"><h2 id="the-single-seams">The single seams</h2><a class="sl-anchor-link" href="#the-single-seams"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore
|
|
391
|
+
<div class="sl-heading-wrapper level-h2"><h2 id="the-single-seams">The single seams</h2><a class="sl-anchor-link" href="#the-single-seams"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore>Section titled “The single seams”</span></a></div>
|
|
392
392
|
<p>Each of these exists exactly once, and a grep fence in <code dir="auto">scripts/arch-fences.sh</code> fails CI if a second copy appears. Every fence label starts with the id of the requirement the fence enforces, and the fence function carries that id as its <code dir="auto">@spec</code> tag.</p>
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
<div class="sl-heading-wrapper level-h2"><h2 id="read-path">Read path</h2><a class="sl-anchor-link" href="#read-path"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore
|
|
393
|
+
<table>
|
|
394
|
+
<thead>
|
|
395
|
+
<tr>
|
|
396
|
+
<th>Seam</th>
|
|
397
|
+
<th>What goes through it</th>
|
|
398
|
+
<th>Fence</th>
|
|
399
|
+
</tr>
|
|
400
|
+
</thead>
|
|
401
|
+
<tbody>
|
|
402
|
+
<tr>
|
|
403
|
+
<td><code dir="auto">runIndex</code></td>
|
|
404
|
+
<td>Every index build. One transaction, one <code dir="auto">build_id</code></td>
|
|
405
|
+
<td>reviewed, not fenced</td>
|
|
406
|
+
</tr>
|
|
407
|
+
<tr>
|
|
408
|
+
<td><code dir="auto">validateAndWrite</code></td>
|
|
409
|
+
<td>Every write of a <code dir="auto">SPEC.json</code> file, a test’s fixture included; a planted defect under <code dir="auto">src/testing/fixtures/</code> is the only file written by hand</td>
|
|
410
|
+
<td><code dir="auto">SCHM-035 every SPEC.json write goes through validateAndWrite</code></td>
|
|
411
|
+
</tr>
|
|
412
|
+
<tr>
|
|
413
|
+
<td><code dir="auto">bun:sqlite</code> import</td>
|
|
414
|
+
<td>Only <code dir="auto">storage/sqlite.ts</code> may import it</td>
|
|
415
|
+
<td><code dir="auto">SCHM-025 bun:sqlite outside storage/sqlite.ts</code>, <code dir="auto">SCHM-025 bun:sqlite outside the engine</code></td>
|
|
416
|
+
</tr>
|
|
417
|
+
<tr>
|
|
418
|
+
<td><code dir="auto">Storage</code> interface</td>
|
|
419
|
+
<td>Every read the CLI, API, and MCP make</td>
|
|
420
|
+
<td>the webapp import fence in <code dir="auto">packages/webapp/test/import-fence.test.ts</code></td>
|
|
421
|
+
</tr>
|
|
422
|
+
<tr>
|
|
423
|
+
<td>Operations</td>
|
|
424
|
+
<td>The write seam and the id allocator are reached only through <code dir="auto">operations/</code>; no command, route, or tool imports them. A test’s fixture builder (<code dir="auto">src/testing/platform.ts</code>) is one more caller of the same operations</td>
|
|
425
|
+
<td><code dir="auto">SCHM-027 write seam under operations</code></td>
|
|
426
|
+
</tr>
|
|
427
|
+
<tr>
|
|
428
|
+
<td>No model calls</td>
|
|
429
|
+
<td>The engine never runs an LLM. The MCP authoring prompt is a text template</td>
|
|
430
|
+
<td><code dir="auto">AUTHOR-008 llm-free engine</code></td>
|
|
431
|
+
</tr>
|
|
432
|
+
<tr>
|
|
433
|
+
<td>Derived versions</td>
|
|
434
|
+
<td>No authored <code dir="auto">specVersion</code> on requirement domains</td>
|
|
435
|
+
<td><code dir="auto">SCHM-020 no authored specVersion</code></td>
|
|
436
|
+
</tr>
|
|
437
|
+
<tr>
|
|
438
|
+
<td>Generated docs</td>
|
|
439
|
+
<td><code dir="auto">GLOSSARY.md</code> and the TAXONOMY charters are regenerated, never hand-edited</td>
|
|
440
|
+
<td><code dir="auto">CHCK-020 glossary round-trip</code>, <code dir="auto">CHRT-007 charters generated from the envelopes</code></td>
|
|
441
|
+
</tr>
|
|
442
|
+
</tbody>
|
|
443
|
+
</table>
|
|
444
|
+
<div class="sl-heading-wrapper level-h2"><h2 id="read-path">Read path</h2><a class="sl-anchor-link" href="#read-path"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore>Section titled “Read path”</span></a></div>
|
|
445
445
|
<p><code dir="auto">spec map</code>, <code dir="auto">spec check</code>, <code dir="auto">spec query</code>, and the other read commands:</p>
|
|
446
446
|
<ol>
|
|
447
447
|
<li>Resolve <code dir="auto">platformDir</code> and assert it contains <code dir="auto">spec-engine/</code>. A non-platform directory exits 2 and leaves no <code dir="auto">.spec-engine/</code> behind.</li>
|
|
@@ -450,7 +450,7 @@
|
|
|
450
450
|
<li>Query the views.</li>
|
|
451
451
|
<li>Render text to stdout, or the sorted <code dir="auto">--json</code> array. Warnings and guidance go to stderr.</li>
|
|
452
452
|
</ol>
|
|
453
|
-
<div class="sl-heading-wrapper level-h2"><h2 id="write-path">Write path</h2><a class="sl-anchor-link" href="#write-path"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore
|
|
453
|
+
<div class="sl-heading-wrapper level-h2"><h2 id="write-path">Write path</h2><a class="sl-anchor-link" href="#write-path"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore>Section titled “Write path”</span></a></div>
|
|
454
454
|
<p><code dir="auto">spec req</code>, <code dir="auto">spec amend</code>, <code dir="auto">spec accept</code>, <code dir="auto">spec supersede</code>, <code dir="auto">spec move</code>, <code dir="auto">spec deprecate</code>, <code dir="auto">spec term</code>:</p>
|
|
455
455
|
<ol>
|
|
456
456
|
<li>Resolve the target domain and run every guard before writing a byte.</li>
|
|
@@ -459,60 +459,61 @@
|
|
|
459
459
|
<li>Write the whole envelope through <code dir="auto">validateAndWrite</code>.</li>
|
|
460
460
|
<li>Lifecycle commands then reindex fresh and print the retag worklist.</li>
|
|
461
461
|
</ol>
|
|
462
|
-
<div class="sl-heading-wrapper level-h2"><h2 id="http-path">HTTP path</h2><a class="sl-anchor-link" href="#http-path"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore
|
|
462
|
+
<div class="sl-heading-wrapper level-h2"><h2 id="http-path">HTTP path</h2><a class="sl-anchor-link" href="#http-path"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore>Section titled “HTTP path”</span></a></div>
|
|
463
463
|
<ol>
|
|
464
464
|
<li><code dir="auto">spec serve</code> composes the engine’s API routes and the webapp’s pages onto one Hono app, bound to <code dir="auto">127.0.0.1</code> or one private <code dir="auto">--host</code> address.</li>
|
|
465
465
|
<li>Pages call <code dir="auto">/api/*</code> in-process. There is no loopback fetch.</li>
|
|
466
466
|
<li>A feature whose flag is off answers 404 on its endpoints and renders a placeholder page.</li>
|
|
467
467
|
</ol>
|
|
468
|
-
<div class="sl-heading-wrapper level-h2"><h2 id="invariants">Invariants</h2><a class="sl-anchor-link" href="#invariants"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore
|
|
468
|
+
<div class="sl-heading-wrapper level-h2"><h2 id="invariants">Invariants</h2><a class="sl-anchor-link" href="#invariants"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore>Section titled “Invariants”</span></a></div>
|
|
469
469
|
<p>The six headline invariants (cold-rebuild identity, <code dir="auto">check --ci</code> builds fresh, one shared schema, spec defects become diagnostics, one model one seam, drift is a view) are catalogued in <code dir="auto">spec-engine/TAXONOMY.md</code> with the requirement id that records each.</p>
|
|
470
|
-
<div class="sl-heading-wrapper level-h2"><h2 id="anti-patterns">Anti-patterns</h2><a class="sl-anchor-link" href="#anti-patterns"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
<div class="sl-heading-wrapper level-h2"><h2 id="error-handling">Error handling</h2><a class="sl-anchor-link" href="#error-handling"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore
|
|
470
|
+
<div class="sl-heading-wrapper level-h2"><h2 id="anti-patterns">Anti-patterns</h2><a class="sl-anchor-link" href="#anti-patterns"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore>Section titled “Anti-patterns”</span></a></div>
|
|
471
|
+
<table>
|
|
472
|
+
<thead>
|
|
473
|
+
<tr>
|
|
474
|
+
<th>Don’t</th>
|
|
475
|
+
<th>Why</th>
|
|
476
|
+
<th>Do instead</th>
|
|
477
|
+
</tr>
|
|
478
|
+
</thead>
|
|
479
|
+
<tbody>
|
|
480
|
+
<tr>
|
|
481
|
+
<td>Write a value into the index that cannot be re-derived</td>
|
|
482
|
+
<td>A cold rebuild must give an identical result</td>
|
|
483
|
+
<td>Put truth in <code dir="auto">SPEC.json</code> or a tag; express the report as a view</td>
|
|
484
|
+
</tr>
|
|
485
|
+
<tr>
|
|
486
|
+
<td>Import <code dir="auto">bun:sqlite</code> in a second file</td>
|
|
487
|
+
<td>Forks the storage contract and reds the SCHM-025 fence</td>
|
|
488
|
+
<td>Extend <code dir="auto">Storage</code> and implement it in <code dir="auto">storage/sqlite.ts</code></td>
|
|
489
|
+
</tr>
|
|
490
|
+
<tr>
|
|
491
|
+
<td><code dir="auto">Bun.write</code> a spec file directly</td>
|
|
492
|
+
<td>Skips schema validation</td>
|
|
493
|
+
<td>Mutate the envelope and call <code dir="auto">validateAndWrite</code></td>
|
|
494
|
+
</tr>
|
|
495
|
+
<tr>
|
|
496
|
+
<td>Use a ticket number as a requirement id or in a tag</td>
|
|
497
|
+
<td>Tickets are temporary; requirements outlive them</td>
|
|
498
|
+
<td>Mint with <code dir="auto">spec req</code>, record the ticket with <code dir="auto">--issue</code></td>
|
|
499
|
+
</tr>
|
|
500
|
+
<tr>
|
|
501
|
+
<td>“Fix” a defect under <code dir="auto">fixtures/</code></td>
|
|
502
|
+
<td>Those defects are what <code dir="auto">spec check</code> exists to catch</td>
|
|
503
|
+
<td>Leave them. Tags under <code dir="auto">fixtures/</code> never index</td>
|
|
504
|
+
</tr>
|
|
505
|
+
<tr>
|
|
506
|
+
<td>Trust a warm index after editing specs or tags</td>
|
|
507
|
+
<td>Read commands only build when the index is missing</td>
|
|
508
|
+
<td>Pass <code dir="auto">--fresh</code>, or use <code dir="auto">check --ci</code> / <code dir="auto">gate</code></td>
|
|
509
|
+
</tr>
|
|
510
|
+
</tbody>
|
|
511
|
+
</table>
|
|
512
|
+
<div class="sl-heading-wrapper level-h2"><h2 id="error-handling">Error handling</h2><a class="sl-anchor-link" href="#error-handling"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore>Section titled “Error handling”</span></a></div>
|
|
513
513
|
<ul>
|
|
514
514
|
<li>Exit codes are the contract: 0 success (including empty results), 1 data failure, 2 usage or environment error.</li>
|
|
515
515
|
<li>Storage failures map to a named hint. A sandboxed process without file locks gets <code dir="auto">SQLITE_IOERR_VNODE</code>; the CLI says so and <code dir="auto">/api/*</code> returns a structured 503.</li>
|
|
516
516
|
<li>Every guard runs before the first write, so a rejected <code dir="auto">move</code> or <code dir="auto">supersede</code> never half-applies.</li>
|
|
517
517
|
<li>Outside git, <code dir="auto">check</code> deletion detection and <code dir="auto">spec guard</code> warn and exit 0.</li>
|
|
518
|
-
</ul>
|
|
518
|
+
</ul>
|
|
519
|
+
</div><footer class="sl-flex astro-yaxnhex4"><div class="meta sl-flex astro-yaxnhex4"><a href="https://github.com/spec-engine/spec-engine/edit/main/packages/site/src/content/docs/architecture.md" class="sl-flex print:hidden astro-uulcuzsf"><svg aria-hidden="true" class="astro-uulcuzsf astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.2em;"><path d="M22 7.24a1 1 0 0 0-.29-.71l-4.24-4.24a1 1 0 0 0-1.1-.22 1 1 0 0 0-.32.22l-2.83 2.83L2.29 16.05a1 1 0 0 0-.29.71V21a1 1 0 0 0 1 1h4.24a1 1 0 0 0 .76-.29l10.87-10.93L21.71 8c.1-.1.17-.2.22-.33a1 1 0 0 0 0-.24v-.14l.07-.05ZM6.83 20H4v-2.83l9.93-9.93 2.83 2.83L6.83 20ZM18.17 8.66l-2.83-2.83 1.42-1.41 2.82 2.82-1.41 1.42Z"/></svg>Edit page</a></div><div class="pagination-links print:hidden astro-kestnrba" dir="ltr"><a href="/getting-started/" rel="prev" class="astro-kestnrba"><svg aria-hidden="true" class="astro-kestnrba astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M17 11H9.41l3.3-3.29a1.004 1.004 0 1 0-1.42-1.42l-5 5a1 1 0 0 0-.21.33 1 1 0 0 0 0 .76 1 1 0 0 0 .21.33l5 5a1.002 1.002 0 0 0 1.639-.325 1 1 0 0 0-.219-1.095L9.41 13H17a1 1 0 0 0 0-2Z"/></svg><span class="astro-kestnrba">Previous<br class="astro-kestnrba"><span class="link-title astro-kestnrba">Getting Started</span></span></a><a href="/platform-mapping/" rel="next" class="astro-kestnrba"><svg aria-hidden="true" class="astro-kestnrba astro-ica5m7eu" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M17.92 11.62a1.001 1.001 0 0 0-.21-.33l-5-5a1.003 1.003 0 1 0-1.42 1.42l3.3 3.29H7a1 1 0 0 0 0 2h7.59l-3.3 3.29a1.002 1.002 0 0 0 .325 1.639 1 1 0 0 0 1.095-.219l5-5a1 1 0 0 0 .21-.33 1 1 0 0 0 0-.76Z"/></svg><span class="astro-kestnrba">Next<br class="astro-kestnrba"><span class="link-title astro-kestnrba">Platform Mapping</span></span></a></div></footer></div></div></main></div></div></div></div></body></html>
|