@spec-engine/spec-engine 0.7.0 → 0.7.2

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.
Files changed (54) hide show
  1. package/dist/docs/404.html +4 -4
  2. package/dist/docs/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.BcSo_yiZ.js +1 -0
  3. package/dist/docs/_astro/Search.astro_astro_type_script_index_0_lang.Djc9ZKGJ.js +1 -0
  4. package/dist/docs/_astro/TableOfContents.astro_astro_type_script_index_0_lang.Csloo1VZ.js +1 -0
  5. package/dist/docs/_astro/common.BPl3nku0.css +3 -0
  6. package/dist/docs/_astro/components.BeLFs6cp.css +1 -0
  7. package/dist/docs/_astro/page.cNngjUgL.js +1 -0
  8. package/dist/docs/_astro/print.ehPL0gv-.css +1 -0
  9. package/dist/docs/_astro/starlight-toc.CTCQXEge.js +1 -0
  10. package/dist/docs/_astro/ui-core.B94qsovR.js +2 -0
  11. package/dist/docs/agent-reference/index.html +23 -22
  12. package/dist/docs/architecture/index.html +423 -422
  13. package/dist/docs/checks/index.html +247 -246
  14. package/dist/docs/commands/index.html +127 -123
  15. package/dist/docs/format/index.html +92 -91
  16. package/dist/docs/getting-started/index.html +21 -20
  17. package/dist/docs/guides/adoption/index.html +13 -12
  18. package/dist/docs/guides/platform-setup/index.html +15 -14
  19. package/dist/docs/guides/single-repo/index.html +12 -11
  20. package/dist/docs/index.html +2 -152
  21. package/dist/docs/overview/index.html +8 -8
  22. package/dist/docs/pagefind/fragment/en_70e8a6f.pf_fragment +0 -0
  23. package/dist/docs/pagefind/fragment/en_907a67d.pf_fragment +0 -0
  24. package/dist/docs/pagefind/fragment/en_b81dc52.pf_fragment +0 -0
  25. package/dist/docs/pagefind/fragment/en_c8cc99c.pf_fragment +0 -0
  26. package/dist/docs/pagefind/fragment/en_de9d958.pf_fragment +0 -0
  27. package/dist/docs/pagefind/fragment/en_e616a50.pf_fragment +0 -0
  28. package/dist/docs/pagefind/fragment/en_f77a622.pf_fragment +0 -0
  29. package/dist/docs/pagefind/index/en_19cbfc6.pf_index +0 -0
  30. package/dist/docs/pagefind/index/en_4be71c4.pf_index +0 -0
  31. package/dist/docs/pagefind/pagefind-entry.json +1 -1
  32. package/dist/docs/pagefind/pagefind.en_f697eb692e.pf_meta +0 -0
  33. package/dist/docs/platform-mapping/index.html +162 -161
  34. package/dist/docs/tags/index.html +74 -73
  35. package/dist/impl.js +283 -32
  36. package/package.json +2 -2
  37. package/dist/docs/_astro/Code.CAimF0uL.css +0 -1
  38. package/dist/docs/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.hwBsy0Mo.js +0 -1
  39. package/dist/docs/_astro/Search.astro_astro_type_script_index_0_lang.lq3t8uE2.js +0 -1
  40. package/dist/docs/_astro/TableOfContents.astro_astro_type_script_index_0_lang.FuRcXuRY.js +0 -1
  41. package/dist/docs/_astro/common.DslAiFsT.css +0 -1
  42. package/dist/docs/_astro/page.B_tncCx8.js +0 -1
  43. package/dist/docs/_astro/print.DNXP8c50.css +0 -1
  44. package/dist/docs/_astro/ui-core.C8327L_n.js +0 -2
  45. package/dist/docs/pagefind/fragment/en_435dca1.pf_fragment +0 -0
  46. package/dist/docs/pagefind/fragment/en_4bdd17f.pf_fragment +0 -0
  47. package/dist/docs/pagefind/fragment/en_6ce6fae.pf_fragment +0 -0
  48. package/dist/docs/pagefind/fragment/en_775cc8c.pf_fragment +0 -0
  49. package/dist/docs/pagefind/fragment/en_a3cd8bf.pf_fragment +0 -0
  50. package/dist/docs/pagefind/fragment/en_b44542a.pf_fragment +0 -0
  51. package/dist/docs/pagefind/fragment/en_d652b3c.pf_fragment +0 -0
  52. package/dist/docs/pagefind/index/en_6b9dc89.pf_index +0 -0
  53. package/dist/docs/pagefind/index/en_c5bf3e1.pf_index +0 -0
  54. package/dist/docs/pagefind/pagefind.en_c6c8e941d5.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-ioexmpvj"> <head><meta charset="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><title>Platform Mapping | Spec Engine</title><link rel="canonical" href="https://docs.spec-engine.dev/platform-mapping/"/><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&amp;family=IBM+Plex+Mono:wght@400;500;600&amp;family=IBM+Plex+Sans:wght@400;500;600&amp;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 v6.4.8"/><meta name="generator" content="Starlight v0.40.0"/><meta property="og:title" content="Platform Mapping"/><meta property="og:type" content="article"/><meta property="og:url" content="https://docs.spec-engine.dev/platform-mapping/"/><meta property="og:locale" content="en"/><meta property="og:description" content="How Spec Engine decides what a platform is, which repositories belong to it, and what each coverage column is named"/><meta property="og:site_name" content="Spec Engine"/><meta name="twitter:card" content="summary_large_image"/><meta name="description" content="How Spec Engine decides what a platform is, which repositories belong to it, and what each coverage column is named"/><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>
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>Platform Mapping | Spec Engine</title><link rel="canonical" href="https://docs.spec-engine.dev/platform-mapping/"/><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&amp;family=IBM+Plex+Mono:wght@400;500;600&amp;family=IBM+Plex+Sans:wght@400;500;600&amp;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="Platform Mapping"/><meta property="og:type" content="article"/><meta property="og:url" content="https://docs.spec-engine.dev/platform-mapping/"/><meta property="og:locale" content="en"/><meta property="og:description" content="How Spec Engine decides what a platform is, which repositories belong to it, and what each coverage column is named"/><meta property="og:site_name" content="Spec Engine"/><meta name="twitter:card" content="summary_large_image"/><meta name="description" content="How Spec Engine decides what a platform is, which repositories belong to it, and what each coverage column is named"/><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-lm5mbbcm" 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-lm5mbbcm" 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-lm5mbbcm" 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.DNXP8c50.css" media="print"><link rel="stylesheet" href="/_astro/common.DslAiFsT.css"><link rel="stylesheet" href="/_astro/Code.CAimF0uL.css"><script type="module" src="/_astro/page.B_tncCx8.js"></script></head> <body class="astro-ioexmpvj"> <a href="#_top" class="astro-exkej44h">Skip to content</a> <div class="page sl-flex astro-to3xypmc"> <header class="header astro-to3xypmc"><div class="header astro-shhymrmb"> <div class="title-wrapper sl-flex astro-shhymrmb"> <a href="/" class="site-title sl-flex astro-6qdjqr3f"> <img class="light:sl-hidden print:hidden astro-6qdjqr3f" alt="Spec Engine" src="/_astro/spec-mark-white.DJBFLLUP.svg" width="512" height="512"> <img class="dark:sl-hidden print:block astro-6qdjqr3f" alt="Spec Engine" src="/_astro/spec-mark-black.ZCN22lJi.svg" width="512" height="512"> <span class="astro-6qdjqr3f" translate="no"> Spec Engine </span> </a> </div> <div class="sl-flex print:hidden astro-shhymrmb"> <site-search class="astro-shhymrmb astro-7vagb36t" data-translations="{&quot;placeholder&quot;:&quot;Search&quot;}"> <button data-open-modal disabled aria-label="Search" aria-keyshortcuts="Control+K" class="astro-7vagb36t"> <svg aria-hidden="true" class="astro-7vagb36t astro-lm5mbbcm" 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-7vagb36t" aria-hidden="true">Search</span> <kbd class="sl-hidden md:sl-flex astro-7vagb36t" style="display: none;"> <kbd class="astro-7vagb36t">Ctrl</kbd><kbd class="astro-7vagb36t">K</kbd> </kbd> </button> <dialog style="padding:0" aria-label="Search" class="astro-7vagb36t"> <div class="dialog-frame sl-flex astro-7vagb36t"> <button data-close-modal class="sl-flex md:sl-hidden astro-7vagb36t"> Cancel </button> <div class="search-container astro-7vagb36t"> <div id="starlight__search" class="astro-7vagb36t"></div> </div> </div> </dialog> </site-search> <script>
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="{&quot;placeholder&quot;:&quot;Search&quot;}"><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> <script type="module" src="/_astro/Search.astro_astro_type_script_index_0_lang.lq3t8uE2.js"></script> </div> <div class="sl-hidden md:sl-flex print:hidden right-group astro-shhymrmb"> <div class="sl-flex social-icons astro-shhymrmb"> <a href="https://github.com/spec-engine/spec-engine" rel="me" class="sl-flex astro-opyhioab"><span class="sr-only astro-opyhioab">GitHub</span><svg aria-hidden="true" class="astro-opyhioab astro-lm5mbbcm" 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-oxpvutiw"> <span class="sr-only astro-oxpvutiw">Select theme</span> <svg aria-hidden="true" class="icon label-icon astro-oxpvutiw astro-lm5mbbcm" 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-oxpvutiw"> <option value="dark" class="astro-oxpvutiw">Dark</option><option value="light" class="astro-oxpvutiw">Light</option><option value="auto" selected class="astro-oxpvutiw">Auto</option> </select> <svg aria-hidden="true" class="icon caret astro-oxpvutiw astro-lm5mbbcm" 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>
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> <script type="module">const r="starlight-theme",o=e=>e==="auto"||e==="dark"||e==="light"?e:"auto",c=()=>o(typeof localStorage<"u"&&localStorage.getItem(r));function n(e){typeof localStorage<"u"&&localStorage.setItem(r,e==="light"||e==="dark"?e:"")}const l=()=>matchMedia("(prefers-color-scheme: light)").matches?"light":"dark";function t(e){StarlightThemeProvider.updatePickers(e),document.documentElement.dataset.theme=e==="auto"?l():e,n(e)}matchMedia("(prefers-color-scheme: light)").addEventListener("change",()=>{c()==="auto"&&t("auto")});class s extends HTMLElement{constructor(){super(),t(c()),this.querySelector("select")?.addEventListener("change",a=>{a.currentTarget instanceof HTMLSelectElement&&t(o(a.currentTarget.value))})}}customElements.define("starlight-theme-select",s);</script> <script type="module">class s extends HTMLElement{constructor(){super();const e=this.querySelector("select");e&&(e.addEventListener("change",t=>{t.currentTarget instanceof HTMLSelectElement&&(window.location.pathname=t.currentTarget.value)}),window.addEventListener("pageshow",t=>{if(!t.persisted)return;const n=e.querySelector("option[selected]")?.index;n!==e.selectedIndex&&(e.selectedIndex=n??0)}))}}customElements.define("starlight-lang-select",s);</script> </div> </div></header> <nav class="sidebar print:hidden astro-to3xypmc" aria-label="Main"> <starlight-menu-button class="print:hidden astro-l43anhaf"> <button aria-expanded="false" aria-label="Menu" aria-controls="starlight__sidebar" class="sl-flex md:sl-hidden astro-l43anhaf"> <svg aria-hidden="true" class="open-menu astro-l43anhaf astro-lm5mbbcm" 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-l43anhaf astro-lm5mbbcm" 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">class s extends HTMLElement{constructor(){super(),this.btn=this.querySelector("button"),this.btn.addEventListener("click",()=>this.toggleExpanded());const t=this.closest("nav");t&&t.addEventListener("keyup",e=>this.closeOnEscape(e))}setExpanded(t){this.setAttribute("aria-expanded",String(t)),document.body.toggleAttribute("data-mobile-menu-expanded",t)}toggleExpanded(){this.setExpanded(this.getAttribute("aria-expanded")!=="true")}closeOnEscape(t){t.code==="Escape"&&(this.setExpanded(!1),this.btn.focus())}}customElements.define("starlight-menu-button",s);</script> <div id="starlight__sidebar" class="sidebar-pane astro-to3xypmc"> <div class="sidebar-content sl-flex astro-to3xypmc"> <sl-sidebar-state-persist data-hash="1dxffrg" class="astro-znqwvy6e"> <script aria-hidden="true">
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,202 +61,203 @@
61
61
  );
62
62
  } catch {}
63
63
  })();
64
- </script> <ul class="top-level astro-ux7joveq"> <li class="astro-ux7joveq"> <a href="/overview/" class="large astro-ux7joveq"> <span class="astro-ux7joveq">Overview</span> </a> </li><li class="astro-ux7joveq"> <a href="/getting-started/" class="large astro-ux7joveq"> <span class="astro-ux7joveq">Getting Started</span> </a> </li><li class="astro-ux7joveq"> <a href="/architecture/" class="large astro-ux7joveq"> <span class="astro-ux7joveq">Architecture</span> </a> </li><li class="astro-ux7joveq"> <a href="/platform-mapping/" aria-current="page" class="large astro-ux7joveq"> <span class="astro-ux7joveq">Platform Mapping</span> </a> </li><li class="astro-ux7joveq"> <a href="/commands/" class="large astro-ux7joveq"> <span class="astro-ux7joveq">Commands</span> </a> </li><li class="astro-ux7joveq"> <a href="/format/" class="large astro-ux7joveq"> <span class="astro-ux7joveq">SPEC.json Format</span> </a> </li><li class="astro-ux7joveq"> <a href="/tags/" class="large astro-ux7joveq"> <span class="astro-ux7joveq">Tags</span> </a> </li><li class="astro-ux7joveq"> <a href="/checks/" class="large astro-ux7joveq"> <span class="astro-ux7joveq">Integrity Checks</span> </a> </li><li class="astro-ux7joveq"> <details open class="astro-ux7joveq"> <summary class="astro-ux7joveq"> <span class="group-label astro-ux7joveq"> <span class="large astro-ux7joveq">Guides</span> </span> <svg aria-hidden="true" class="caret astro-ux7joveq astro-lm5mbbcm" 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-ux7joveq"> <li class="astro-ux7joveq"> <a href="/guides/adoption/" class="astro-ux7joveq"> <span class="astro-ux7joveq">Adoption Guide</span> </a> </li><li class="astro-ux7joveq"> <a href="/guides/platform-setup/" class="astro-ux7joveq"> <span class="astro-ux7joveq">Platform Setup</span> </a> </li><li class="astro-ux7joveq"> <a href="/guides/single-repo/" class="astro-ux7joveq"> <span class="astro-ux7joveq">Single Repo (Rung 1)</span> </a> </li> </ul> </details> </li><li class="astro-ux7joveq"> <a href="/agent-reference/" class="large astro-ux7joveq"> <span class="astro-ux7joveq">Agent Reference</span> </a> </li> </ul> <script aria-hidden="true">
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/" class="large astro-3rgm4o2r"><span class="astro-3rgm4o2r">Architecture</span></a></li><li class="astro-3rgm4o2r"><a href="/platform-mapping/" aria-current="page" 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> </sl-sidebar-state-persist> <div class="md:sl-hidden"> <div class="mobile-preferences sl-flex astro-2lx56rho"> <div class="social-icons astro-2lx56rho"> <a href="https://github.com/spec-engine/spec-engine" rel="me" class="sl-flex astro-opyhioab"><span class="sr-only astro-opyhioab">GitHub</span><svg aria-hidden="true" class="astro-opyhioab astro-lm5mbbcm" 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-oxpvutiw"> <span class="sr-only astro-oxpvutiw">Select theme</span> <svg aria-hidden="true" class="icon label-icon astro-oxpvutiw astro-lm5mbbcm" 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-oxpvutiw"> <option value="dark" class="astro-oxpvutiw">Dark</option><option value="light" class="astro-oxpvutiw">Light</option><option value="auto" selected class="astro-oxpvutiw">Auto</option> </select> <svg aria-hidden="true" class="icon caret astro-oxpvutiw astro-lm5mbbcm" 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>
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> </div> </div> </div> </div> </nav> <div class="main-frame astro-to3xypmc"> <script type="module">const a=document.getElementById("starlight__sidebar"),n=a?.querySelector("sl-sidebar-state-persist"),o="sl-sidebar-state",i=()=>{let t=[];const e=n?.dataset.hash||"";try{const s=sessionStorage.getItem(o),r=JSON.parse(s||"{}");Array.isArray(r.open)&&r.hash===e&&(t=r.open)}catch{}return{hash:e,open:t,scroll:a?.scrollTop||0}},c=t=>{try{sessionStorage.setItem(o,JSON.stringify(t))}catch{}},d=()=>c(i()),l=(t,e)=>{const s=i();s.open[e]=t,c(s)};n?.addEventListener("click",t=>{if(!(t.target instanceof Element))return;const e=t.target.closest("summary")?.closest("details");if(!e)return;const s=e.querySelector("sl-sidebar-restore"),r=parseInt(s?.dataset.index||"");isNaN(r)||l(!e.open,r)});addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&d()});addEventListener("pageHide",d);</script> <div class="lg:sl-flex astro-blhl7r6q"> <aside class="right-sidebar-container print:hidden astro-blhl7r6q"> <div class="right-sidebar astro-blhl7r6q"> <div class="lg:sl-hidden astro-l5m3cfel"><mobile-starlight-toc data-min-h="2" data-max-h="3" class="astro-goxitxj7"><nav aria-labelledby="starlight__on-this-page--mobile" class="astro-goxitxj7"><details id="starlight__mobile-toc" class="astro-goxitxj7"><summary id="starlight__on-this-page--mobile" class="sl-flex astro-goxitxj7"><span class="toggle sl-flex astro-goxitxj7">On this page<svg aria-hidden="true" class="caret astro-goxitxj7 astro-lm5mbbcm" 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-goxitxj7"></span></summary><div class="dropdown astro-goxitxj7"><ul class="isMobile astro-xz67lhkg" style="--depth: 0;"> <li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#_top" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Overview</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#two-files-one-convention" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Two files, one convention</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#the-platform-root" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">The platform root</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#members" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Members</span> </a> <ul class="isMobile astro-xz67lhkg" style="--depth: 1;"> <li class="astro-xz67lhkg" style="--depth: 1;"> <a href="#two-ignore-lists" class="astro-xz67lhkg" style="--depth: 1;"> <span class="astro-xz67lhkg" style="--depth: 1;">Two ignore lists</span> </a> </li> </ul> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#monorepo-members-and-their-packages" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Monorepo members and their packages</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#a-lone-repository" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">A lone repository</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#names" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Names</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#diagnostics" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Diagnostics</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#where-spec-init-may-write" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Where spec init may write</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#the-webapps-scan-mode-tile" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">The webapp’s scan-mode tile</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#determinism" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Determinism</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#declaring-a-platform" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Declaring a platform</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#propagation-order-dependson" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Propagation order: dependsOn</span> </a> </li> </ul></div></details></nav></mobile-starlight-toc><script type="module" src="/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.hwBsy0Mo.js"></script></div><div class="right-sidebar-panel sl-hidden lg:sl-block astro-l5m3cfel"><div class="sl-container astro-l5m3cfel"><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-xz67lhkg" style="--depth: 0;"> <li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#_top" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Overview</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#two-files-one-convention" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Two files, one convention</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#the-platform-root" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">The platform root</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#members" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Members</span> </a> <ul class="astro-xz67lhkg" style="--depth: 1;"> <li class="astro-xz67lhkg" style="--depth: 1;"> <a href="#two-ignore-lists" class="astro-xz67lhkg" style="--depth: 1;"> <span class="astro-xz67lhkg" style="--depth: 1;">Two ignore lists</span> </a> </li> </ul> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#monorepo-members-and-their-packages" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Monorepo members and their packages</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#a-lone-repository" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">A lone repository</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#names" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Names</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#diagnostics" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Diagnostics</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#where-spec-init-may-write" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Where spec init may write</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#the-webapps-scan-mode-tile" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">The webapp’s scan-mode tile</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#determinism" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Determinism</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#declaring-a-platform" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Declaring a platform</span> </a> </li><li class="astro-xz67lhkg" style="--depth: 0;"> <a href="#propagation-order-dependson" class="astro-xz67lhkg" style="--depth: 0;"> <span class="astro-xz67lhkg" style="--depth: 0;">Propagation order: dependsOn</span> </a> </li> </ul></nav></starlight-toc><script type="module" src="/_astro/TableOfContents.astro_astro_type_script_index_0_lang.FuRcXuRY.js"></script></div></div> </div> </aside> <div class="main-pane astro-blhl7r6q"> <main data-pagefind-body class="astro-ioexmpvj" lang="en" dir="ltr"> <div class="content-panel astro-sfndtt72"> <div class="sl-container astro-sfndtt72"> <h1 id="_top" class="astro-4b4mtvou">Platform Mapping</h1> </div> </div> <div class="content-panel astro-sfndtt72"> <div class="sl-container astro-sfndtt72"> <div class="sl-markdown-content"> <p>Spec Engine does not have its own idea of what a platform is. It takes membership and shape from <a href="https://www.npmjs.com/package/@spec-engine/platform-map"><code dir="auto">@spec-engine/platform-map</code></a>, the same package every tool built on Spec Engine uses, and adds exactly one fact of its own per member: the version pin. <!-- @spec INIT-037 --> platform-map is a dependency of the engine and is called as a library: <code dir="auto">spec init</code> declares members through it, <code dir="auto">spec check</code> runs its checks underneath, and no <code dir="auto">spec</code> workflow asks you to run a platform-map command yourself. This page states the model in platform-map’s vocabulary and names the requirement each rule carries.</p>
74
- <div class="sl-heading-wrapper level-h2"><h2 id="two-files-one-convention">Two files, one convention</h2><a class="sl-anchor-link" href="#two-files-one-convention"><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 “Two files, one convention”</span></a></div>
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="#two-files-one-convention" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Two files, one convention</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#the-platform-root" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">The platform root</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#members" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Members</span></a><ul class="isMobile astro-l6rvz6dz" style="--depth: 1;"><li style="--depth: 1;" class="astro-l6rvz6dz"><a href="#two-ignore-lists" style="--depth: 1;" class="astro-l6rvz6dz"><span style="--depth: 1;" class="astro-l6rvz6dz">Two ignore lists</span></a></li></ul></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#monorepo-members-and-their-packages" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Monorepo members and their packages</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#a-lone-repository" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">A lone repository</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#names" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Names</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#diagnostics" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Diagnostics</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#where-spec-init-may-write" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Where spec init may write</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#the-webapps-scan-mode-tile" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">The webapp’s scan-mode tile</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#determinism" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Determinism</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#declaring-a-platform" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Declaring a platform</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#propagation-order-dependson" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Propagation order: dependsOn</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="#two-files-one-convention" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Two files, one convention</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#the-platform-root" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">The platform root</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#members" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Members</span></a><ul class="astro-l6rvz6dz" style="--depth: 1;"><li style="--depth: 1;" class="astro-l6rvz6dz"><a href="#two-ignore-lists" style="--depth: 1;" class="astro-l6rvz6dz"><span style="--depth: 1;" class="astro-l6rvz6dz">Two ignore lists</span></a></li></ul></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#monorepo-members-and-their-packages" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Monorepo members and their packages</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#a-lone-repository" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">A lone repository</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#names" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Names</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#diagnostics" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Diagnostics</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#where-spec-init-may-write" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Where spec init may write</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#the-webapps-scan-mode-tile" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">The webapp’s scan-mode tile</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#determinism" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Determinism</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#declaring-a-platform" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Declaring a platform</span></a></li><li style="--depth: 0;" class="astro-l6rvz6dz"><a href="#propagation-order-dependson" style="--depth: 0;" class="astro-l6rvz6dz"><span style="--depth: 0;" class="astro-l6rvz6dz">Propagation order: dependsOn</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">Platform Mapping</h1></div></div><div class="content-panel astro-d3w5v5qg"><div class="sl-container astro-d3w5v5qg"><div class="sl-markdown-content"><p>Spec Engine does not have its own idea of what a platform is. It takes membership and shape from <a href="https://www.npmjs.com/package/@spec-engine/platform-map"><code dir="auto">@spec-engine/platform-map</code></a>, the same package every tool built on Spec Engine uses, and adds exactly one fact of its own per member: the version pin. <!-- @spec INIT-037 --> platform-map is a dependency of the engine and is called as a library: <code dir="auto">spec init</code> declares members through it, <code dir="auto">spec check</code> runs its checks underneath, and no <code dir="auto">spec</code> workflow asks you to run a platform-map command yourself. This page states the model in platform-map’s vocabulary and names the requirement each rule carries.</p>
74
+ <div class="sl-heading-wrapper level-h2"><h2 id="two-files-one-convention">Two files, one convention</h2><a class="sl-anchor-link" href="#two-files-one-convention"><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 “Two files, one convention”</span></a></div>
75
75
  <p>platform-map works from two small committed files that share one name, <code dir="auto">platform-map.json</code>. Which one a file is depends on its keys.</p>
76
76
  <p><strong>The platform file</strong> lives at the platform root and declares the members:</p>
77
- <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="json"><code><div class="ec-line"><div class="code"><span style="--0:#D6DEEB;--1:#403F53">{ </span><span style="--0:#7FDBCA;--1:#096E72">"name"</span><span style="--0:#D6DEEB;--1:#403F53">: </span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">acme</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#D6DEEB;--1:#403F53">, </span><span style="--0:#7FDBCA;--1:#096E72">"members"</span><span style="--0:#D6DEEB;--1:#403F53">: [</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">api</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#D6DEEB;--1:#403F53">, </span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">webapp</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#D6DEEB;--1:#403F53">, </span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">mobile</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#D6DEEB;--1:#403F53">, </span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">shared</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#D6DEEB;--1:#403F53">], </span><span style="--0:#7FDBCA;--1:#096E72">"ignore"</span><span style="--0:#D6DEEB;--1:#403F53">: [</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">scratch</span><span style="--0:#D9F5DD;--1:#111111">"</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="{ &#x22;name&#x22;: &#x22;acme&#x22;, &#x22;members&#x22;: [&#x22;api&#x22;, &#x22;webapp&#x22;, &#x22;mobile&#x22;, &#x22;shared&#x22;], &#x22;ignore&#x22;: [&#x22;scratch&#x22;] }"><div></div></button></div></figure></div>
77
+ <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="json"><code><div class="ec-line"><div class="code"><span style="--0:#D6DEEB;--1:#403F53">{ </span><span style="--0:#7FDBCA;--1:#096E72">"name"</span><span style="--0:#D6DEEB;--1:#403F53">: </span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">acme</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#D6DEEB;--1:#403F53">, </span><span style="--0:#7FDBCA;--1:#096E72">"members"</span><span style="--0:#D6DEEB;--1:#403F53">: [</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">api</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#D6DEEB;--1:#403F53">, </span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">webapp</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#D6DEEB;--1:#403F53">, </span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">mobile</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#D6DEEB;--1:#403F53">, </span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">shared</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#D6DEEB;--1:#403F53">], </span><span style="--0:#7FDBCA;--1:#096E72">"ignore"</span><span style="--0:#D6DEEB;--1:#403F53">: [</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">scratch</span><span style="--0:#D9F5DD;--1:#111111">"</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="{ &quot;name&quot;: &quot;acme&quot;, &quot;members&quot;: [&quot;api&quot;, &quot;webapp&quot;, &quot;mobile&quot;, &quot;shared&quot;], &quot;ignore&quot;: [&quot;scratch&quot;] }"><div></div></button></div></figure></div>
78
78
  <p><strong>The leaf marker</strong> lives inside each member and points back at the platform:</p>
79
- <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="json"><code><div class="ec-line"><div class="code"><span style="--0:#D6DEEB;--1:#403F53">{ </span><span style="--0:#7FDBCA;--1:#096E72">"platform"</span><span style="--0:#D6DEEB;--1:#403F53">: </span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">acme</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#D6DEEB;--1:#403F53">, </span><span style="--0:#7FDBCA;--1:#096E72">"member"</span><span style="--0:#D6DEEB;--1:#403F53">: </span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">api</span><span style="--0:#D9F5DD;--1:#111111">"</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="{ &#x22;platform&#x22;: &#x22;acme&#x22;, &#x22;member&#x22;: &#x22;api&#x22; }"><div></div></button></div></figure></div>
80
- <p>Neither file contains a path. Members are child directories of the platform root, named after their member name. A checkout that lives somewhere else is recorded in the per-user file <code dir="auto">~/.config/platform-map/platforms.json</code>, which <code dir="auto">spec init --platform &#x3C;dir></code> writes through platform-map’s <code dir="auto">link</code> and which is never committed or edited by hand. <!-- @spec INIT-039 --></p>
79
+ <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="json"><code><div class="ec-line"><div class="code"><span style="--0:#D6DEEB;--1:#403F53">{ </span><span style="--0:#7FDBCA;--1:#096E72">"platform"</span><span style="--0:#D6DEEB;--1:#403F53">: </span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">acme</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#D6DEEB;--1:#403F53">, </span><span style="--0:#7FDBCA;--1:#096E72">"member"</span><span style="--0:#D6DEEB;--1:#403F53">: </span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">api</span><span style="--0:#D9F5DD;--1:#111111">"</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="{ &quot;platform&quot;: &quot;acme&quot;, &quot;member&quot;: &quot;api&quot; }"><div></div></button></div></figure></div>
80
+ <p>Neither file contains a path. Members are child directories of the platform root, named after their member name. A checkout that lives somewhere else is recorded in the per-user file <code dir="auto">~/.config/platform-map/platforms.json</code>, which <code dir="auto">spec init --platform &lt;dir&gt;</code> writes through platform-map’s <code dir="auto">link</code> and which is never committed or edited by hand. <!-- @spec INIT-039 --></p>
81
81
  <p>Spec Engine adds one more committed file per member, <code dir="auto">spec-engine.member.json</code>. It carries the member’s pin and its scan ignore list, and it says nothing about membership:</p>
82
- <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="json"><code><div class="ec-line"><div class="code"><span style="--0:#D6DEEB;--1:#403F53">{ </span><span style="--0:#7FDBCA;--1:#096E72">"specs"</span><span style="--0:#D6DEEB;--1:#403F53">: </span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">spec-engine@17</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#D6DEEB;--1:#403F53">, </span><span style="--0:#7FDBCA;--1:#096E72">"ignore"</span><span style="--0:#D6DEEB;--1:#403F53">: [</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">generated</span><span style="--0:#D9F5DD;--1:#111111">"</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="{ &#x22;specs&#x22;: &#x22;spec-engine@17&#x22;, &#x22;ignore&#x22;: [&#x22;generated&#x22;] }"><div></div></button></div></figure></div>
83
- <div class="sl-heading-wrapper level-h2"><h2 id="the-platform-root">The platform root</h2><a class="sl-anchor-link" href="#the-platform-root"><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 platform root”</span></a></div>
82
+ <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="json"><code><div class="ec-line"><div class="code"><span style="--0:#D6DEEB;--1:#403F53">{ </span><span style="--0:#7FDBCA;--1:#096E72">"specs"</span><span style="--0:#D6DEEB;--1:#403F53">: </span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">spec-engine@17</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#D6DEEB;--1:#403F53">, </span><span style="--0:#7FDBCA;--1:#096E72">"ignore"</span><span style="--0:#D6DEEB;--1:#403F53">: [</span><span style="--0:#D9F5DD;--1:#111111">"</span><span style="--0:#C789D6;--1:#7C5686">generated</span><span style="--0:#D9F5DD;--1:#111111">"</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="{ &quot;specs&quot;: &quot;spec-engine@17&quot;, &quot;ignore&quot;: [&quot;generated&quot;] }"><div></div></button></div></figure></div>
83
+ <div class="sl-heading-wrapper level-h2"><h2 id="the-platform-root">The platform root</h2><a class="sl-anchor-link" href="#the-platform-root"><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 platform root”</span></a></div>
84
84
  <p>The platform root is the directory that holds the canonical <code dir="auto">spec-engine/</code> tree. When the platform is declared, the same directory holds the platform file. Every <code dir="auto">spec</code> command resolves its root through platform-map’s <code dir="auto">locate()</code>: from wherever the command ran, walk upward to the nearest directory holding a <code dir="auto">platform-map.json</code> or a <code dir="auto">.git</code> entry, stopping at the home directory or the filesystem root, then resolve a marker to its platform through the parent directory or the per-user file. A root that <code dir="auto">locate()</code> finds but that holds no <code dir="auto">spec-engine/</code> directory is not a Spec Engine platform, and the command exits 2. <!-- @spec INIT-034 --></p>
85
85
  <p>The index-building commands take the platform directory as an argument and ask platform-map to describe that directory. A directory that platform-map does not recognize as a starting point, one with neither a <code dir="auto">.git</code> entry nor a <code dir="auto">platform-map.json</code> inside a larger repository (a spec tree kept in a subfolder, such as a committed fixture), is mapped as a lone single repository: one coverage column named by the directory, and no platform-map diagnostics.</p>
86
86
  <p>The platform version is derived, never authored. It is the maximum of the domain versions under <code dir="auto">spec-engine/</code>. A domain file that fails to parse contributes nothing to that number, and the index build then refuses: the command prints only that file’s <code dir="auto">INVALID_DOMAIN_FILE</code> rows and exits 1, leaving the index on disk as it was. <!-- @spec INIT-029 --></p>
87
- <div class="sl-heading-wrapper level-h2"><h2 id="members">Members</h2><a class="sl-anchor-link" href="#members"><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 “Members”</span></a></div>
87
+ <div class="sl-heading-wrapper level-h2"><h2 id="members">Members</h2><a class="sl-anchor-link" href="#members"><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 “Members”</span></a></div>
88
88
  <p>A member is a name in the platform file’s <code dir="auto">members</code> list. Nothing else makes a directory a member: not a <code dir="auto">.git</code> entry, not a <code dir="auto">package.json</code>, not a <code dir="auto">spec-engine.member.json</code>. A repository sitting in the platform folder that nobody declared is platform-map’s <code dir="auto">UNLISTED_REPO</code>, and <code dir="auto">spec check</code> reports it so the repository’s <code dir="auto">@spec</code> tags never go unscanned in silence.</p>
89
- <p><code dir="auto">spec init &#x3C;name></code> is the one command that makes a repository a member. It declares the repository through platform-map’s <code dir="auto">init</code> (an entry in the platform file and a marker in the repository), then writes the repository’s <code dir="auto">spec-engine.member.json</code>. Run on a repository that is already declared, it only writes the pin, and puts back a missing marker. <!-- @spec INIT-038 --></p>
90
- <p>A declared member that has no <code dir="auto">spec-engine.member.json</code> is a member without a pin. The index reports it as <code dir="auto">NO_SPEC_CONFIG</code>, one warning per member, and suggests <code dir="auto">spec init &#x3C;name></code>. <!-- @spec INIT-032 --> When stdin is a terminal and <code dir="auto">--no-prompt</code> is absent, an index-building command offers to run <code dir="auto">spec init &#x3C;name></code> before it proceeds, for each declared member without a pin and for each undeclared repository in the platform folder. <!-- @spec INIT-033 --></p>
89
+ <p><code dir="auto">spec init &lt;name&gt;</code> is the one command that makes a repository a member. It declares the repository through platform-map’s <code dir="auto">init</code> (an entry in the platform file and a marker in the repository), then writes the repository’s <code dir="auto">spec-engine.member.json</code>. Run on a repository that is already declared, it only writes the pin, and puts back a missing marker. <!-- @spec INIT-038 --></p>
90
+ <p>A declared member that has no <code dir="auto">spec-engine.member.json</code> is a member without a pin. The index reports it as <code dir="auto">NO_SPEC_CONFIG</code>, one warning per member, and suggests <code dir="auto">spec init &lt;name&gt;</code>. <!-- @spec INIT-032 --> When stdin is a terminal and <code dir="auto">--no-prompt</code> is absent, an index-building command offers to run <code dir="auto">spec init &lt;name&gt;</code> before it proceeds, for each declared member without a pin and for each undeclared repository in the platform folder. <!-- @spec INIT-033 --></p>
91
91
  <p>A member’s pin is the <code dir="auto">specs</code> string in its <code dir="auto">spec-engine.member.json</code>, one platform-wide scalar <code dir="auto">spec-engine@N</code>.</p>
92
- <div class="sl-heading-wrapper level-h3"><h3 id="two-ignore-lists">Two <code dir="auto">ignore</code> lists</h3><a class="sl-anchor-link" href="#two-ignore-lists"><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 “Two ignore lists”</span></a></div>
92
+ <div class="sl-heading-wrapper level-h3"><h3 id="two-ignore-lists">Two <code dir="auto">ignore</code> lists</h3><a class="sl-anchor-link" href="#two-ignore-lists"><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 “Two ignore lists”</span></a></div>
93
93
  <p>Two files carry a field named <code dir="auto">ignore</code>, and they mean different things.</p>
94
-
95
-
96
-
97
-
98
-
99
-
100
-
101
-
102
-
103
-
104
-
105
-
106
-
107
-
108
-
109
-
110
-
111
-
112
-
113
-
114
-
115
-
116
-
117
- <table><thead><tr><th>File</th><th>Field</th><th>What it skips</th><th>Example</th></tr></thead><tbody><tr><td><code dir="auto">platform-map.json</code> at the platform root</td><td><code dir="auto">ignore</code></td><td>Directories platform-map never considers a repository, so they are never candidates and never <code dir="auto">UNLISTED_REPO</code></td><td><code dir="auto">"ignore": ["scratch"]</code> keeps a scratch folder out of the platform</td></tr><tr><td><code dir="auto">spec-engine.member.json</code> in a member</td><td><code dir="auto">ignore</code></td><td>Repo-relative directory prefixes the tag scanner skips inside that one member</td><td><code dir="auto">"ignore": ["generated"]</code> stops tags in generated code from counting</td></tr></tbody></table>
94
+ <table>
95
+ <thead>
96
+ <tr>
97
+ <th>File</th>
98
+ <th>Field</th>
99
+ <th>What it skips</th>
100
+ <th>Example</th>
101
+ </tr>
102
+ </thead>
103
+ <tbody>
104
+ <tr>
105
+ <td><code dir="auto">platform-map.json</code> at the platform root</td>
106
+ <td><code dir="auto">ignore</code></td>
107
+ <td>Directories platform-map never considers a repository, so they are never candidates and never <code dir="auto">UNLISTED_REPO</code></td>
108
+ <td><code dir="auto">"ignore": ["scratch"]</code> keeps a scratch folder out of the platform</td>
109
+ </tr>
110
+ <tr>
111
+ <td><code dir="auto">spec-engine.member.json</code> in a member</td>
112
+ <td><code dir="auto">ignore</code></td>
113
+ <td>Repo-relative directory prefixes the tag scanner skips inside that one member</td>
114
+ <td><code dir="auto">"ignore": ["generated"]</code> stops tags in generated code from counting</td>
115
+ </tr>
116
+ </tbody>
117
+ </table>
118
118
  <p>Neither list removes a member from the platform. To stop scanning a member entirely, remove it from the platform file.</p>
119
- <div class="sl-heading-wrapper level-h2"><h2 id="monorepo-members-and-their-packages">Monorepo members and their packages</h2><a class="sl-anchor-link" href="#monorepo-members-and-their-packages"><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 “Monorepo members and their packages”</span></a></div>
119
+ <div class="sl-heading-wrapper level-h2"><h2 id="monorepo-members-and-their-packages">Monorepo members and their packages</h2><a class="sl-anchor-link" href="#monorepo-members-and-their-packages"><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 “Monorepo members and their packages”</span></a></div>
120
120
  <p>platform-map classifies every member as <code dir="auto">single-repo</code> or <code dir="auto">monorepo</code> from its ecosystem’s workspace manifest: <code dir="auto">pnpm-workspace.yaml</code>, <code dir="auto">package.json</code> <code dir="auto">workspaces</code>, <code dir="auto">lerna.json</code>, a <code dir="auto">uv</code> workspace, a Cargo workspace, or <code dir="auto">go.work</code>. A monorepo member’s packages are the directories its workspace manifest lists.</p>
121
121
  <p>Each package is its own coverage column, named by the package’s path relative to the member (<code dir="auto">packages/ui</code>), prefixed by the member name when the member belongs to a declared platform (<code dir="auto">shared/packages/ui</code>). A package inherits its member’s pin unless it carries a nested <code dir="auto">spec-engine.member.json</code>, whose pin and <code dir="auto">ignore</code> then apply to that package alone. That is how one package can sit on <code dir="auto">spec-engine@2</code> while a sibling lags on <code dir="auto">@1</code>.</p>
122
122
  <p>A monorepo’s files outside every workspace package (CI scripts, infrastructure, migrations at the repository root) are one more column: named by the member for a declared member, and by the directory for a lone monorepo. That column skips every package path, so no file is scanned twice, and it inherits the member’s <code dir="auto">ignore</code> list. When a workspace lists the repository root itself as a package, the root is already a column and no extra one is added. <!-- @spec INIT-040 --></p>
123
123
  <p>There is no <code dir="auto">members</code> glob in <code dir="auto">spec-engine.member.json</code>. The workspace manifest is the one place a monorepo names its packages.</p>
124
- <div class="sl-heading-wrapper level-h2"><h2 id="a-lone-repository">A lone repository</h2><a class="sl-anchor-link" href="#a-lone-repository"><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 “A lone repository”</span></a></div>
124
+ <div class="sl-heading-wrapper level-h2"><h2 id="a-lone-repository">A lone repository</h2><a class="sl-anchor-link" href="#a-lone-repository"><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 “A lone repository”</span></a></div>
125
125
  <p>A repository that holds its own <code dir="auto">spec-engine/</code> tree and is not a declared platform is a lone repository. platform-map maps it as <code dir="auto">single-repo</code> or <code dir="auto">monorepo</code> with one repo entry, and Spec Engine scans that repo without any member config or CI gate. <!-- @spec INIT-035 --></p>
126
126
  <p>A lone <code dir="auto">single-repo</code> is one coverage column named by the directory name. A lone <code dir="auto">monorepo</code> has one coverage column per workspace package, named by the package’s repo-relative path (<code dir="auto">packages/engine</code>), with no member prefix, plus one column named by the directory for its files outside every package. Every lone-repository column, and the canonical <code dir="auto">spec-engine</code> row itself, is pinned to the derived platform version, so a repository is never reported drifted against its own working-tree domains. A nested <code dir="auto">spec-engine.member.json</code> inside a package still overrides that package’s pin. <!-- @spec INIT-028 --></p>
127
127
  <p>This repository is a lone <code dir="auto">monorepo</code>. Its coverage columns are <code dir="auto">packages/engine</code>, <code dir="auto">packages/shared</code>, <code dir="auto">packages/site</code>, <code dir="auto">packages/tracker</code>, <code dir="auto">packages/webapp</code>, and <code dir="auto">scripts</code>, each a workspace package of the root <code dir="auto">package.json</code>. It has no root column: a checkout directory named <code dir="auto">spec-engine</code> would collide with the canonical <code dir="auto">spec-engine</code> row, the same limitation a lone single repository of that name has.</p>
128
- <div class="sl-heading-wrapper level-h2"><h2 id="names">Names</h2><a class="sl-anchor-link" href="#names"><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 “Names”</span></a></div>
128
+ <div class="sl-heading-wrapper level-h2"><h2 id="names">Names</h2><a class="sl-anchor-link" href="#names"><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 “Names”</span></a></div>
129
129
  <p>One name serves everywhere. For a declared member it is the member name from the platform file. For a package it is the member name and the package path joined by <code dir="auto">/</code>, or the bare package path in a lone monorepo. That same string is:</p>
130
130
  <ul>
131
131
  <li>the coverage column in <code dir="auto">spec map</code>,</li>
132
- <li>the prefix of every <code dir="auto">tags.file</code> value, so <code dir="auto">spec resolve &#x3C;name>/&#x3C;path></code> finds the tag,</li>
133
- <li>the <code dir="auto">repo</code> argument of <code dir="auto">spec gate &#x3C;repo> &#x3C;KEY-NNN></code>,</li>
132
+ <li>the prefix of every <code dir="auto">tags.file</code> value, so <code dir="auto">spec resolve &lt;name&gt;/&lt;path&gt;</code> finds the tag,</li>
133
+ <li>the <code dir="auto">repo</code> argument of <code dir="auto">spec gate &lt;repo&gt; &lt;KEY-NNN&gt;</code>,</li>
134
134
  <li>the <code dir="auto">repo</code> field of every <code dir="auto">spec propagation</code> row.</li>
135
135
  </ul>
136
136
  <p>The canonical <code dir="auto">spec-engine/</code> tree is one more row named <code dir="auto">spec-engine</code>. It holds requirement text, never code, and the webapp excludes it from every member count.</p>
137
- <div class="sl-heading-wrapper level-h2"><h2 id="diagnostics">Diagnostics</h2><a class="sl-anchor-link" href="#diagnostics"><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 “Diagnostics”</span></a></div>
137
+ <div class="sl-heading-wrapper level-h2"><h2 id="diagnostics">Diagnostics</h2><a class="sl-anchor-link" href="#diagnostics"><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 “Diagnostics”</span></a></div>
138
138
  <p>platform-map reports what it finds as diagnostics on the map. <code dir="auto">spec check</code> surfaces the ones that describe a broken or incomplete platform as rows of its own, with the platform-map code, so a broken platform declaration fails the same gate a broken requirement does.</p>
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
-
183
-
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
- <table><thead><tr><th>platform-map code</th><th>platform-map severity</th><th><code dir="auto">spec check</code> severity</th><th>Meaning</th></tr></thead><tbody><tr><td><code dir="auto">MALFORMED_FILE</code></td><td>error, or warning for a manifest</td><td>same</td><td>A <code dir="auto">platform-map.json</code>, a manifest, or the per-user file failed to parse or validate</td></tr><tr><td><code dir="auto">MARKER_MISMATCH</code></td><td>error</td><td>error</td><td>A member’s marker names a different platform</td></tr><tr><td><code dir="auto">MEMBER_MISSING</code></td><td>warning</td><td>warning</td><td>A declared member is not on this machine; it is not scanned</td></tr><tr><td><code dir="auto">MARKER_MISSING</code></td><td>warning</td><td>warning</td><td>A declared member has no marker</td></tr><tr><td><code dir="auto">PLATFORM_NOT_LOCATED</code></td><td>warning</td><td>warning</td><td>A marker names a platform this machine cannot find</td></tr><tr><td><code dir="auto">SCAN_TRUNCATED</code></td><td>warning</td><td>warning</td><td>A directory walk hit its depth or entry cap</td></tr><tr><td><code dir="auto">UNLISTED_REPO</code></td><td>info</td><td>warning</td><td>A repository in the platform folder is not a member; its tags are not scanned until <code dir="auto">spec init &#x3C;name></code> declares it</td></tr><tr><td><code dir="auto">UNDECLARED_PLATFORM</code></td><td>info</td><td>warning</td><td>A folder of repositories with no platform file; nothing in it is a member until <code dir="auto">spec init &#x3C;name></code> declares the first one</td></tr><tr><td><code dir="auto">UNMATCHED_PATTERN</code></td><td>info</td><td>not surfaced</td><td>A workspace glob matched no package</td></tr><tr><td><code dir="auto">AMBIGUOUS_ECOSYSTEM</code></td><td>info</td><td>not surfaced</td><td>A repo has manifests from more than one ecosystem</td></tr></tbody></table>
139
+ <table>
140
+ <thead>
141
+ <tr>
142
+ <th>platform-map code</th>
143
+ <th>platform-map severity</th>
144
+ <th><code dir="auto">spec check</code> severity</th>
145
+ <th>Meaning</th>
146
+ </tr>
147
+ </thead>
148
+ <tbody>
149
+ <tr>
150
+ <td><code dir="auto">MALFORMED_FILE</code></td>
151
+ <td>error, or warning for a manifest</td>
152
+ <td>same</td>
153
+ <td>A <code dir="auto">platform-map.json</code>, a manifest, or the per-user file failed to parse or validate</td>
154
+ </tr>
155
+ <tr>
156
+ <td><code dir="auto">MARKER_MISMATCH</code></td>
157
+ <td>error</td>
158
+ <td>error</td>
159
+ <td>A member’s marker names a different platform</td>
160
+ </tr>
161
+ <tr>
162
+ <td><code dir="auto">MEMBER_MISSING</code></td>
163
+ <td>warning</td>
164
+ <td>warning</td>
165
+ <td>A declared member is not on this machine; it is not scanned</td>
166
+ </tr>
167
+ <tr>
168
+ <td><code dir="auto">MARKER_MISSING</code></td>
169
+ <td>warning</td>
170
+ <td>warning</td>
171
+ <td>A declared member has no marker</td>
172
+ </tr>
173
+ <tr>
174
+ <td><code dir="auto">PLATFORM_NOT_LOCATED</code></td>
175
+ <td>warning</td>
176
+ <td>warning</td>
177
+ <td>A marker names a platform this machine cannot find</td>
178
+ </tr>
179
+ <tr>
180
+ <td><code dir="auto">SCAN_TRUNCATED</code></td>
181
+ <td>warning</td>
182
+ <td>warning</td>
183
+ <td>A directory walk hit its depth or entry cap</td>
184
+ </tr>
185
+ <tr>
186
+ <td><code dir="auto">UNLISTED_REPO</code></td>
187
+ <td>info</td>
188
+ <td>warning</td>
189
+ <td>A repository in the platform folder is not a member; its tags are not scanned until <code dir="auto">spec init &lt;name&gt;</code> declares it</td>
190
+ </tr>
191
+ <tr>
192
+ <td><code dir="auto">UNDECLARED_PLATFORM</code></td>
193
+ <td>info</td>
194
+ <td>warning</td>
195
+ <td>A folder of repositories with no platform file; nothing in it is a member until <code dir="auto">spec init &lt;name&gt;</code> declares the first one</td>
196
+ </tr>
197
+ <tr>
198
+ <td><code dir="auto">UNMATCHED_PATTERN</code></td>
199
+ <td>info</td>
200
+ <td>not surfaced</td>
201
+ <td>A workspace glob matched no package</td>
202
+ </tr>
203
+ <tr>
204
+ <td><code dir="auto">AMBIGUOUS_ECOSYSTEM</code></td>
205
+ <td>info</td>
206
+ <td>not surfaced</td>
207
+ <td>A repo has manifests from more than one ecosystem</td>
208
+ </tr>
209
+ </tbody>
210
+ </table>
211
211
  <p>The rule behind the table: every platform-map error and warning keeps its severity, and an info diagnostic is promoted to a warning only when it means a repository’s tags are silently not being scanned. <!-- @spec CHCK-031 --> A row’s <code dir="auto">source_file</code> is the diagnostic’s subject; <code dir="auto">repo</code> is the subject when it names a member of the platform. A message that would tell you to run a platform-map command is reworded to the <code dir="auto">spec init</code> form that does the same. <code dir="auto">NO_SPEC_CONFIG</code> stays Spec Engine’s own code, because the pin is Spec Engine’s own file.</p>
212
- <div class="sl-heading-wrapper level-h2"><h2 id="where-spec-init-may-write">Where <code dir="auto">spec init</code> may write</h2><a class="sl-anchor-link" href="#where-spec-init-may-write"><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 “Where spec init may write”</span></a></div>
213
- <p><code dir="auto">spec init &#x3C;dir></code> declares a member and writes its <code dir="auto">spec-engine.member.json</code>. Where the target sits decides what is written:</p>
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
- <table><thead><tr><th>The target</th><th>What <code dir="auto">spec init</code> writes</th></tr></thead><tbody><tr><td>A repository directly under a platform folder (a directory holding <code dir="auto">spec-engine/</code>) that the platform file does not list</td><td>The platform file entry (the file is created when absent), the marker, and the pin</td></tr><tr><td>A declared member</td><td>The pin; a missing marker is written back</td></tr><tr><td>A workspace package of a monorepo, lone or member</td><td>A nested pin, no declaration</td></tr><tr><td>A plain folder platform-map cannot declare (no <code dir="auto">.git</code> entry, no <code dir="auto">package.json</code>), or a repository inside a lone monorepo that is not a workspace package</td><td>Nothing: exit 2, because a pin there would index nothing</td></tr><tr><td>A directory under no platform</td><td>The <code dir="auto">spec-engine@1</code> fallback pin</td></tr><tr><td>A declared member’s checkout outside the platform folder, with <code dir="auto">--platform &#x3C;dir></code></td><td>The per-user location file, then the pin</td></tr></tbody></table>
212
+ <div class="sl-heading-wrapper level-h2"><h2 id="where-spec-init-may-write">Where <code dir="auto">spec init</code> may write</h2><a class="sl-anchor-link" href="#where-spec-init-may-write"><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 “Where spec init may write”</span></a></div>
213
+ <p><code dir="auto">spec init &lt;dir&gt;</code> declares a member and writes its <code dir="auto">spec-engine.member.json</code>. Where the target sits decides what is written:</p>
214
+ <table>
215
+ <thead>
216
+ <tr>
217
+ <th>The target</th>
218
+ <th>What <code dir="auto">spec init</code> writes</th>
219
+ </tr>
220
+ </thead>
221
+ <tbody>
222
+ <tr>
223
+ <td>A repository directly under a platform folder (a directory holding <code dir="auto">spec-engine/</code>) that the platform file does not list</td>
224
+ <td>The platform file entry (the file is created when absent), the marker, and the pin</td>
225
+ </tr>
226
+ <tr>
227
+ <td>A declared member</td>
228
+ <td>The pin; a missing marker is written back</td>
229
+ </tr>
230
+ <tr>
231
+ <td>A workspace package of a monorepo, lone or member</td>
232
+ <td>A nested pin, no declaration</td>
233
+ </tr>
234
+ <tr>
235
+ <td>A plain folder platform-map cannot declare (no <code dir="auto">.git</code> entry, no <code dir="auto">package.json</code>), or a repository inside a lone monorepo that is not a workspace package</td>
236
+ <td>Nothing: exit 2, because a pin there would index nothing</td>
237
+ </tr>
238
+ <tr>
239
+ <td>A directory under no platform</td>
240
+ <td>The <code dir="auto">spec-engine@1</code> fallback pin</td>
241
+ </tr>
242
+ <tr>
243
+ <td>A declared member’s checkout outside the platform folder, with <code dir="auto">--platform &lt;dir&gt;</code></td>
244
+ <td>The per-user location file, then the pin</td>
245
+ </tr>
246
+ </tbody>
247
+ </table>
248
248
  <p>It resolves symlinks, locates the platform root, and refuses two targets with exit 2: a directory inside a <code dir="auto">spec-engine/</code> tree, because a pin there registers the requirement source as a member of itself, and the platform root itself, because the root is not a member. <!-- @spec INIT-018 --></p>
249
249
  <p>The refusal reads every path segment for the name <code dir="auto">spec-engine</code>. On the engine’s own checkout, whose root package is named <code dir="auto">@spec-engine/spec-engine</code>, only the path below the platform root is judged, so a checkout named <code dir="auto">spec-engine</code> can still scaffold its own packages. <!-- @spec INIT-030 --></p>
250
250
  <p>The default pin is the derived platform version. With no located platform, <code dir="auto">spec init</code> writes <code dir="auto">spec-engine@1</code> and says so.</p>
251
- <div class="sl-heading-wrapper level-h2"><h2 id="the-webapps-scan-mode-tile">The webapp’s scan-mode tile</h2><a class="sl-anchor-link" href="#the-webapps-scan-mode-tile"><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 webapp’s scan-mode tile”</span></a></div>
251
+ <div class="sl-heading-wrapper level-h2"><h2 id="the-webapps-scan-mode-tile">The webapp’s scan-mode tile</h2><a class="sl-anchor-link" href="#the-webapps-scan-mode-tile"><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 webapp’s scan-mode tile”</span></a></div>
252
252
  <p>The Setup page’s scan-mode tile is <code dir="auto">map().mode</code> rendered in words: <code dir="auto">monorepo</code> renders Monorepo, <code dir="auto">multi-repo</code> renders Platform, and <code dir="auto">single-repo</code> renders Single repo. <!-- @spec SERV-018 --></p>
253
- <div class="sl-heading-wrapper level-h2"><h2 id="determinism">Determinism</h2><a class="sl-anchor-link" href="#determinism"><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 “Determinism”</span></a></div>
253
+ <div class="sl-heading-wrapper level-h2"><h2 id="determinism">Determinism</h2><a class="sl-anchor-link" href="#determinism"><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 “Determinism”</span></a></div>
254
254
  <p><code dir="auto">map()</code> contains no absolute path and sorts every array with plain string comparison, so the same files and the same disk produce the same map from any directory. Spec Engine reads paths from <code dir="auto">locate()</code>, which is never part of the map, and hashes none of them into <code dir="auto">build_id</code>. Deleting <code dir="auto">.spec-engine/</code> and rebuilding produces the identical index and the identical <code dir="auto">build_id</code>. <!-- @spec INDX-007 --> <code dir="auto">spec index</code> walks the spec directory and every present member and package, and reports the <code dir="auto">build_id</code> and the row counts. <!-- @spec INDX-009 --></p>
255
- <div class="sl-heading-wrapper level-h2"><h2 id="declaring-a-platform">Declaring a platform</h2><a class="sl-anchor-link" href="#declaring-a-platform"><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 “Declaring a platform”</span></a></div>
256
- <div class="expressive-code"><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="bash"><code><div class="ec-line"><div class="code"><span style="--0:#C5E478;--1:#3B61B0">cd</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">~/clients/acme</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#919F9F;--1:#5F636F"># the folder holding the repos</span></div></div><div class="ec-line"><div class="code"><span style="--0:#82AAFF;--1:#3B61B0">spec</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">domain</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">new</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">BILLING</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#919F9F;--1:#5F636F"># the canonical tree makes it a Spec Engine platform</span></div></div><div class="ec-line"><div class="code"><span style="--0:#82AAFF;--1:#3B61B0">spec</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">init</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">api</span><span style="--0:#D6DEEB;--1:#403F53"> &#x26;&#x26; </span><span style="--0:#82AAFF;--1:#3B61B0">spec</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">init</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">webapp</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#919F9F;--1:#5F636F"># each: platform file entry, marker, pin</span></div></div><div class="ec-line"><div class="code"><span style="--0:#82AAFF;--1:#3B61B0">spec</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">index</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">.</span><span style="--0:#D6DEEB;--1:#403F53"> &#x26;&#x26; </span><span style="--0:#82AAFF;--1:#3B61B0">spec</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">check</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">.</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#82AAFF;--1:#3B61B0">--ci</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#919F9F;--1:#5F636F"># membership and pins are now one gate</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button title="Copy to clipboard" data-copied="Copied!" data-code="cd ~/clients/acme # the folder holding the reposspec domain new BILLING # the canonical tree makes it a Spec Engine platformspec init api &#x26;&#x26; spec init webapp # each: platform file entry, marker, pinspec index . &#x26;&#x26; spec check . --ci # membership and pins are now one gate"><div></div></button></div></figure></div>
255
+ <div class="sl-heading-wrapper level-h2"><h2 id="declaring-a-platform">Declaring a platform</h2><a class="sl-anchor-link" href="#declaring-a-platform"><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 “Declaring a platform”</span></a></div>
256
+ <div class="expressive-code"><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="bash"><code><div class="ec-line"><div class="code"><span style="--0:#C5E478;--1:#3B61B0">cd</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">~/clients/acme</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#919F9F;--1:#5F636F"># the folder holding the repos</span></div></div><div class="ec-line"><div class="code"><span style="--0:#82AAFF;--1:#3B61B0">spec</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">domain</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">new</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">BILLING</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#919F9F;--1:#5F636F"># the canonical tree makes it a Spec Engine platform</span></div></div><div class="ec-line"><div class="code"><span style="--0:#82AAFF;--1:#3B61B0">spec</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">init</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">api</span><span style="--0:#D6DEEB;--1:#403F53"> &amp;&amp; </span><span style="--0:#82AAFF;--1:#3B61B0">spec</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">init</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">webapp</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#919F9F;--1:#5F636F"># each: platform file entry, marker, pin</span></div></div><div class="ec-line"><div class="code"><span style="--0:#82AAFF;--1:#3B61B0">spec</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">index</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">.</span><span style="--0:#D6DEEB;--1:#403F53"> &amp;&amp; </span><span style="--0:#82AAFF;--1:#3B61B0">spec</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">check</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#ECC48D;--1:#3B61B0">.</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#82AAFF;--1:#3B61B0">--ci</span><span style="--0:#D6DEEB;--1:#403F53"> </span><span style="--0:#919F9F;--1:#5F636F"># membership and pins are now one gate</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button title="Copy to clipboard" data-copied="Copied!" data-code="cd ~/clients/acme # the folder holding the reposspec domain new BILLING # the canonical tree makes it a Spec Engine platformspec init api &amp;&amp; spec init webapp # each: platform file entry, marker, pinspec index . &amp;&amp; spec check . --ci # membership and pins are now one gate"><div></div></button></div></figure></div>
257
257
  <p><code dir="auto">spec check . --ci</code> runs platform-map’s own check underneath, so one gate fails when a requirement, a tag, a pin, or the platform declaration is broken.</p>
258
- <div class="sl-heading-wrapper level-h2"><h2 id="propagation-order-dependson">Propagation order: <code dir="auto">dependsOn</code></h2><a class="sl-anchor-link" href="#propagation-order-dependson"><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 “Propagation order: dependsOn”</span></a></div>
258
+ <div class="sl-heading-wrapper level-h2"><h2 id="propagation-order-dependson">Propagation order: <code dir="auto">dependsOn</code></h2><a class="sl-anchor-link" href="#propagation-order-dependson"><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 “Propagation order: dependsOn”</span></a></div>
259
259
  <p>Every repo and package in the map carries <code dir="auto">dependsOn</code>, the platform’s own package names its manifest depends on, matched within one ecosystem. Spec Engine reads it as the order in which a superseded requirement propagates: a consumer can only move to the successor after the packages it depends on ship it. <code dir="auto">spec propagation</code>, <code dir="auto">/api/propagation/:id</code>, <code dir="auto">spec_propagation</code>, and the webapp’s propagation page list members in dependency order, a member after every member it depends on, and members at the same depth by name. <!-- @spec PROP-006 --></p>
260
260
  <p>The depth is a coverage-column fact, computed at discovery and stored in the derived index. A single-repo member’s node is its map repo; a monorepo member’s package column, and a lone monorepo’s package column, is its map <code dir="auto">Package</code>. A column depends on another column when the other’s <code dir="auto">packageName</code> appears in its <code dir="auto">dependsOn</code>; a name that is no column (an absent member or package) is no edge; a monorepo’s root column carries its root manifest’s name and dependencies. A column with no dependency is depth 0; every other column is one deeper than its deepest dependency. A dependency cycle, and every column downstream of it, sits at one depth after every column outside it, by name.</p>
261
261
  <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="plaintext"><code><div class="ec-line"><div class="code"><span style="--0:#d6deeb;--1:#403f53">$ spec propagation BILLING-002 .</span></div></div><div class="ec-line"><div class="code"><span style="--0:#d6deeb;--1:#403f53">REPO STATE VIA DRIFT?</span></div></div><div class="ec-line"><div class="code"><span style="--0:#d6deeb;--1:#403f53">shared MIGRATED_VERIFIED — no</span></div></div><div class="ec-line"><div class="code"><span style="--0:#d6deeb;--1:#403f53">zed NO_DOMAIN_REFERENCE — no</span></div></div><div class="ec-line"><div class="code"><span style="--0:#d6deeb;--1:#403f53">api ON_PREDECESSOR BILLING-001 no</span></div></div><div class="ec-line"><div class="code"><span style="--0:#d6deeb;--1:#403f53">web MIGRATED_UNVERIFIED — no</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button title="Copy to clipboard" data-copied="Copied!" data-code="$ spec propagation BILLING-002 .REPO STATE VIA DRIFT?shared MIGRATED_VERIFIED — nozed NO_DOMAIN_REFERENCE — noapi ON_PREDECESSOR BILLING-001 noweb MIGRATED_UNVERIFIED — no"><div></div></button></div></figure></div>
262
- <p>Here <code dir="auto">api</code> depends on <code dir="auto">shared</code> and <code dir="auto">web</code> on <code dir="auto">api</code>, so <code dir="auto">api</code> is the member to migrate next. A platform with no in-platform dependencies lists members by name, as before.</p> </div> <footer class="sl-flex astro-5h22m7ac"> <div class="meta sl-flex astro-5h22m7ac"> <a href="https://github.com/spec-engine/spec-engine/edit/main/packages/site/src/content/docs/platform-mapping.md" class="sl-flex print:hidden astro-txs4wy42"><svg aria-hidden="true" class="astro-txs4wy42 astro-lm5mbbcm" 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-7kn6nbmm" dir="ltr"> <a href="/architecture/" rel="prev" class="astro-7kn6nbmm"> <svg aria-hidden="true" class="astro-7kn6nbmm astro-lm5mbbcm" 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-7kn6nbmm"> Previous <br class="astro-7kn6nbmm"> <span class="link-title astro-7kn6nbmm">Architecture</span> </span> </a> <a href="/commands/" rel="next" class="astro-7kn6nbmm"> <svg aria-hidden="true" class="astro-7kn6nbmm astro-lm5mbbcm" 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-7kn6nbmm"> Next <br class="astro-7kn6nbmm"> <span class="link-title astro-7kn6nbmm">Commands</span> </span> </a> </div> </footer> </div> </div> </main> </div> </div> </div> </div> </body></html>
262
+ <p>Here <code dir="auto">api</code> depends on <code dir="auto">shared</code> and <code dir="auto">web</code> on <code dir="auto">api</code>, so <code dir="auto">api</code> is the member to migrate next. A platform with no in-platform dependencies lists members by name, as before.</p>
263
+ </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/platform-mapping.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="/architecture/" 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">Architecture</span></span></a><a href="/commands/" 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">Commands</span></span></a></div></footer></div></div></main></div></div></div></div></body></html>