ruvnet-brain 3.9.134-dev → 4.0.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 (218) hide show
  1. package/.claude-plugin/marketplace.json +14 -0
  2. package/README.md +5 -5
  3. package/bin/install.mjs +382 -36
  4. package/console/CONTRACT.md +172 -0
  5. package/console/activity.js +753 -0
  6. package/console/app.js +4189 -0
  7. package/console/architecture.html +1221 -0
  8. package/console/assets/depth-1.webp +0 -0
  9. package/console/assets/depth-2.webp +0 -0
  10. package/console/assets/depth-3.webp +0 -0
  11. package/console/assets/harness-vs-plain.svg +259 -0
  12. package/console/assets/hero.webp +0 -0
  13. package/console/assets/memory.webp +0 -0
  14. package/console/assets/metaharness.svg +247 -0
  15. package/console/index.html +777 -0
  16. package/console/install-architecture.html +162 -0
  17. package/console/install-mockup.html +543 -0
  18. package/console/style.css +2144 -0
  19. package/console/tips.css +926 -0
  20. package/console/tips.html +858 -0
  21. package/console/tips.js +128 -0
  22. package/docs/RELEASE-NOTES-4.0.md +88 -0
  23. package/kb/model-requirements.mjs +37 -6
  24. package/kb/zip-extract.mjs +53 -14
  25. package/keys/ruvnet-brain-signing.pub.pem +3 -0
  26. package/package.json +14 -22
  27. package/plugin/.claude-plugin/marketplace.json +14 -0
  28. package/plugin/.claude-plugin/plugin.json +22 -0
  29. package/plugin/.codex-plugin/plugin.json +21 -0
  30. package/plugin/.mcp.json +8 -0
  31. package/plugin/commands/brain-console.md +16 -0
  32. package/plugin/commands/configure.md +33 -0
  33. package/plugin/commands/rvbc.md +79 -0
  34. package/plugin/commands/rvcb.md +16 -0
  35. package/plugin/commands/whats-new.md +57 -0
  36. package/plugin/hooks/codex-hooks.json +160 -0
  37. package/plugin/hooks/hook-contracts.json +77 -0
  38. package/plugin/hooks/hooks.json +202 -0
  39. package/plugin/mcp/managed-cli-interface.mjs +47 -4
  40. package/plugin/mcp/server.mjs +56 -6
  41. package/plugin/scripts/anticipate.sh +534 -0
  42. package/plugin/scripts/codex-hook-adapter.mjs +96 -0
  43. package/plugin/scripts/continuation-gate.mjs +267 -0
  44. package/plugin/scripts/design-wall.sh +137 -0
  45. package/plugin/scripts/detach.mjs +182 -0
  46. package/plugin/scripts/first-session-worker.mjs +38 -0
  47. package/plugin/scripts/gate-receipt.sh +35 -0
  48. package/plugin/scripts/ground-before-write.sh +199 -0
  49. package/plugin/scripts/ground-ruvnet.sh +517 -0
  50. package/plugin/scripts/grounding-stamp.sh +113 -0
  51. package/plugin/scripts/grounding-substance.mjs +595 -0
  52. package/plugin/scripts/hijack-ruvnet.sh +81 -0
  53. package/plugin/scripts/hook-input.mjs +558 -0
  54. package/plugin/scripts/hook-shim-bash.mjs +55 -0
  55. package/plugin/scripts/hook-shim.mjs +303 -0
  56. package/plugin/scripts/host-update.mjs +58 -0
  57. package/plugin/scripts/kling-preflight.sh +146 -0
  58. package/plugin/scripts/learn-capture.sh +173 -0
  59. package/plugin/scripts/learn-flush.mjs +155 -0
  60. package/plugin/scripts/lesson-hooks.sh +213 -0
  61. package/plugin/scripts/md-stamp.mjs +219 -0
  62. package/plugin/scripts/protect-brain-state.sh +84 -0
  63. package/plugin/scripts/route-dispatch.sh +147 -0
  64. package/plugin/scripts/routing-outcome-capture.mjs +89 -0
  65. package/plugin/scripts/runtime-preferences.mjs +269 -0
  66. package/plugin/scripts/session-start-core.mjs +477 -0
  67. package/plugin/scripts/session-start.sh +13 -0
  68. package/plugin/scripts/signal-watch.mjs +193 -0
  69. package/plugin/scripts/unprompted-runtime.mjs +377 -0
  70. package/plugin/scripts/update-apply.mjs +419 -0
  71. package/plugin/scripts/verify-interface.sh +53 -0
  72. package/plugin/scripts/version-bump-gate.sh +112 -0
  73. package/plugin/skills/brain-build/SKILL.md +123 -0
  74. package/plugin/skills/brain-console/SKILL.md +22 -0
  75. package/plugin/skills/brain-prompt/SKILL.md +83 -0
  76. package/plugin/skills/brain-score/SKILL.md +101 -0
  77. package/plugin/skills/release-proof/SKILL.md +81 -0
  78. package/plugin/skills/release-proof/agents/openai.yaml +4 -0
  79. package/plugin/skills/release-proof/references/receipt-contract.md +38 -0
  80. package/plugin/skills/release-proof/scripts/release-proof.mjs +210 -0
  81. package/plugin/skills/ruvnet-brain/PLAYBOOK.md +121 -0
  82. package/plugin/skills/ruvnet-brain/SKILL.md +234 -0
  83. package/plugin/skills/rvbc/SKILL.md +23 -0
  84. package/plugin/skills/savings/SKILL.md +46 -0
  85. package/plugin/skills/whats-new/SKILL.md +22 -0
  86. package/scripts/adr-backfill.mjs +107 -0
  87. package/scripts/advocacy-outcomes.mjs +808 -0
  88. package/scripts/agentdb-context.mjs +216 -0
  89. package/scripts/agentdb-fleet-doctor.mjs +101 -0
  90. package/scripts/ascii-drift.mjs +236 -0
  91. package/scripts/behavioral-l1-l4.mjs +210 -0
  92. package/scripts/brain-capability-check.mjs +72 -0
  93. package/scripts/brain-grade-groundtruth.mjs +100 -0
  94. package/scripts/brain-latency-50.mjs +227 -0
  95. package/scripts/brain-novice-50.mjs +189 -0
  96. package/scripts/brain-stamp.mjs +94 -0
  97. package/scripts/brain-state.mjs +212 -0
  98. package/scripts/build-bundle.mjs +522 -0
  99. package/scripts/build-concepts.mjs +132 -0
  100. package/scripts/build-l2.mjs +71 -0
  101. package/scripts/build-primer.mjs +73 -0
  102. package/scripts/build-symbols.mjs +68 -0
  103. package/scripts/calibrate-router.mjs +97 -0
  104. package/scripts/capability-audit.mjs +321 -0
  105. package/scripts/capability-registry.mjs +876 -0
  106. package/scripts/check-indexation.mjs +108 -0
  107. package/scripts/check-legibility.mjs +189 -0
  108. package/scripts/ci/build-fixture-kb.mjs +67 -0
  109. package/scripts/ci/learning-replay-codex-adapter.mjs +62 -0
  110. package/scripts/ci/learning-replay-recorder.mjs +59 -0
  111. package/scripts/ci/mutate-hook-timeout.mjs +70 -0
  112. package/scripts/ci/stranger-fixture-stage.mjs +17 -0
  113. package/scripts/ci/stranger-scenario.mjs +228 -0
  114. package/scripts/ci/stranger-timeout.mjs +25 -0
  115. package/scripts/ci-verdict.mjs +29 -0
  116. package/scripts/claims-verify.mjs +710 -0
  117. package/scripts/clear-claude-tmp.sh +31 -0
  118. package/scripts/console-engine.mjs +434 -0
  119. package/scripts/console-engine.test.mjs +125 -0
  120. package/scripts/corpus-qa.mjs +250 -0
  121. package/scripts/correction-detect-embed.mjs +346 -0
  122. package/scripts/correction-detect-measure.mjs +270 -0
  123. package/scripts/correction-detect.mjs +686 -0
  124. package/scripts/count-chunks.mjs +54 -0
  125. package/scripts/described-questions.json +30 -0
  126. package/scripts/design-grade.mjs +58 -0
  127. package/scripts/dev-plugin-link.sh +105 -0
  128. package/scripts/distill-project.mjs +200 -0
  129. package/scripts/doc-currency.mjs +801 -0
  130. package/scripts/eval-brain.mjs +244 -0
  131. package/scripts/fix-metaharness-memretrieve.mjs +121 -0
  132. package/scripts/full-hints.mjs +87 -0
  133. package/scripts/gate.sh +39 -0
  134. package/scripts/gates.mjs +146 -0
  135. package/scripts/gen-console-images.mjs +54 -0
  136. package/scripts/gen-images.mjs +47 -0
  137. package/scripts/git-clone-refresh.mjs +52 -0
  138. package/scripts/git-hooks/pre-push +126 -0
  139. package/scripts/goal-match.mjs +398 -0
  140. package/scripts/goldie-research.mjs +223 -0
  141. package/scripts/goldie-weekly.sh +67 -0
  142. package/scripts/health-repair.mjs +250 -0
  143. package/scripts/helix-scenario-questions.json +10 -0
  144. package/scripts/ingest-gists.mjs +230 -0
  145. package/scripts/ingest-meeting.mjs +115 -0
  146. package/scripts/ingest-repo.mjs +79 -0
  147. package/scripts/install-npx-witness.sh +49 -0
  148. package/scripts/issue-fix.mjs +639 -0
  149. package/scripts/issue-watch.mjs +276 -0
  150. package/scripts/issue4-close-note.md +31 -0
  151. package/scripts/key-canary.mjs +91 -0
  152. package/scripts/latency-to-surface.mjs +233 -0
  153. package/scripts/learning-enable.mjs +380 -0
  154. package/scripts/learning-replay.mjs +1570 -0
  155. package/scripts/learnings.mjs +62 -0
  156. package/scripts/lesson-gate.mjs +680 -0
  157. package/scripts/lesson-lifecycle.mjs +449 -0
  158. package/scripts/lesson-promote.mjs +262 -0
  159. package/scripts/lesson-ratify.mjs +98 -0
  160. package/scripts/lesson-seed.mjs +252 -0
  161. package/scripts/lesson-store.mjs +447 -0
  162. package/scripts/loop-checkpoint.mjs +86 -0
  163. package/scripts/memdb-health.sh +14 -0
  164. package/scripts/memory-doctor.mjs +271 -0
  165. package/scripts/model-catalog.mjs +79 -0
  166. package/scripts/nightly-controller.mjs +66 -0
  167. package/scripts/nightly-gists.sh +72 -0
  168. package/scripts/nightly-wrapper.sh +180 -0
  169. package/scripts/notify.sh +12 -0
  170. package/scripts/npx-witness.sh +56 -0
  171. package/scripts/onboarding-console.mjs +2749 -0
  172. package/scripts/private-fence.mjs +69 -0
  173. package/scripts/proactivity-metrics.mjs +118 -0
  174. package/scripts/proof-questions.json +56 -0
  175. package/scripts/prove.mjs +95 -0
  176. package/scripts/proxy/claude-proxied.sh +57 -0
  177. package/scripts/proxy/proxy-revert.sh +59 -0
  178. package/scripts/proxy/proxy-up.sh +60 -0
  179. package/scripts/proxy/proxy-verify.mjs +142 -0
  180. package/scripts/published-surface-probe.mjs +241 -0
  181. package/scripts/qe/card-lane-gate.mjs +162 -0
  182. package/scripts/qe/session-start-gate.mjs +229 -0
  183. package/scripts/qe/ux-suite.mjs +323 -0
  184. package/scripts/reconcile-project.mjs +0 -0
  185. package/scripts/record-lesson.mjs +113 -0
  186. package/scripts/refresh-model-catalog.mjs +99 -0
  187. package/scripts/release-proof.mjs +9 -0
  188. package/scripts/release-vector.mjs +281 -0
  189. package/scripts/release.mjs +395 -0
  190. package/scripts/remedy-registry.mjs +247 -0
  191. package/scripts/rerank-cap-eval.mjs +265 -0
  192. package/scripts/rerank-cap-warm-ab.mjs +129 -0
  193. package/scripts/route-cheap.mjs +20 -15
  194. package/scripts/router-utilization.mjs +182 -0
  195. package/scripts/routing-flywheel.mjs +596 -0
  196. package/scripts/rvf-generation.mjs +104 -0
  197. package/scripts/rvf-index-audit.mjs +138 -0
  198. package/scripts/self-update.mjs +508 -0
  199. package/scripts/selfcheck.mjs +7 -1
  200. package/scripts/sign-bundle.mjs +69 -0
  201. package/scripts/signal-watch.mjs +171 -0
  202. package/scripts/stack-sync.mjs +469 -0
  203. package/scripts/stamp-existing-rvf-generations.mjs +53 -0
  204. package/scripts/stamp-sweep.mjs +144 -0
  205. package/scripts/status-honesty.mjs +102 -0
  206. package/scripts/sync-version.mjs +217 -0
  207. package/scripts/token-report.mjs +102 -0
  208. package/scripts/top100-benchmark.mjs +479 -0
  209. package/scripts/top100-corpus.mjs +112 -0
  210. package/scripts/top100-semantic-assertions.mjs +449 -0
  211. package/scripts/update-apply.mjs +9 -0
  212. package/scripts/upgrade-notice.mjs +14 -0
  213. package/scripts/verify-bundle.mjs +51 -0
  214. package/scripts/verify-channels.mjs +184 -0
  215. package/scripts/verify-model-catalog.mjs +104 -0
  216. package/scripts/verify-nightly-close-issue4.sh +31 -0
  217. package/scripts/version.mjs +40 -0
  218. package/scripts/wired-check.mjs +864 -0
@@ -0,0 +1,777 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <meta name="color-scheme" content="dark light" />
7
+ <title>RuvNet Brain — Onboarding Console</title>
8
+ <!-- Version-free brain mark (same glyph as explainer/favicon.svg): amber circuit-brain,
9
+ three signal nodes in the console's own semantics — cyan observed, amber acting, green grounded. -->
10
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 64 64%22><rect x=%222%22 y=%222%22 width=%2260%22 height=%2260%22 rx=%2216%22 fill=%22%230b0d12%22 stroke=%22%232c3850%22 stroke-width=%221.5%22/><path d=%22M25 48 C17 48 11.5 41.5 13.5 34.5 C10 29 13 21 19 19 C21 12.5 29 9.5 35 12 C43 9 50.5 14.5 50.5 22 C55 26 55 34.5 50 38 C49 43.5 43 47.5 37 46.5 L31 47.5 Z%22 fill=%22none%22 stroke=%22%23f0a830%22 stroke-width=%223.4%22 stroke-linejoin=%22round%22/><path d=%22M31 47 L31 33 M31 33 L24 27 M31 33 L40 24.5 M31 33 L41 36.5%22 fill=%22none%22 stroke=%22%23f0a830%22 stroke-width=%222.4%22 stroke-linecap=%22round%22 opacity=%22.9%22/><circle cx=%2224%22 cy=%2227%22 r=%223.4%22 fill=%22%235ad6ff%22/><circle cx=%2240%22 cy=%2224.5%22 r=%223.4%22 fill=%22%23f4b13a%22/><circle cx=%2241%22 cy=%2236.5%22 r=%223.4%22 fill=%22%235fd38a%22/></svg>" />
11
+
12
+ <!-- The server inlines the per-launch token here at render time:
13
+ <script>window.__CONSOLE_TOKEN__="…"</script>
14
+ The frontend tolerates it being absent (static preview). -->
15
+
16
+ <script>
17
+ /* Resolve theme BEFORE first paint: stored preference wins, else the OS. */
18
+ (function () {
19
+ var t = null;
20
+ try { t = localStorage.getItem('rbc-theme'); } catch (e) {}
21
+ if (t !== 'light' && t !== 'dark') {
22
+ try { t = matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'; }
23
+ catch (e) { t = 'dark'; }
24
+ }
25
+ document.documentElement.dataset.theme = t;
26
+ })();
27
+ </script>
28
+
29
+ <link rel="stylesheet" href="style.css" />
30
+ </head>
31
+ <body>
32
+
33
+ <a class="skip-link" href="#main">Skip to content</a>
34
+
35
+ <header class="head">
36
+ <div class="wrap head-inner">
37
+ <div class="brand">
38
+ <!-- The brain, worn openly: the same version-free circuit-brain as the favicon and the
39
+ explainer. Node colors ARE the page's semantics: cyan observed · amber acting · green grounded. -->
40
+ <svg class="mark" viewBox="0 0 64 64" aria-hidden="true">
41
+ <rect class="mk-plate" x="2" y="2" width="60" height="60" rx="16" />
42
+ <path class="mk-brain" d="M25 48 C17 48 11.5 41.5 13.5 34.5 C10 29 13 21 19 19 C21 12.5 29 9.5 35 12 C43 9 50.5 14.5 50.5 22 C55 26 55 34.5 50 38 C49 43.5 43 47.5 37 46.5 L31 47.5 Z" />
43
+ <path class="mk-branch" d="M31 47 L31 33 M31 33 L24 27 M31 33 L40 24.5 M31 33 L41 36.5" />
44
+ <circle class="n2" cx="24" cy="27" r="4" /><circle class="n1" cx="40" cy="24.5" r="4" /><circle class="n3" cx="41" cy="36.5" r="4" />
45
+ </svg>
46
+ <span class="brand-text">RuvNet Brain <span class="brand-sub">Onboarding Console</span></span>
47
+ <!-- The MARK stays version-free; the heading no longer is (owner, 2026-07-24: "put the version
48
+ in the heading so it's very clear what version they're on"). The gong sounds ONLY on a
49
+ KNOWN newer release, and — because an update has no verified undo — clicking hands you
50
+ the command (instructions, not a switch), per the contract in the intro. -->
51
+ <span class="ver-chip mono" id="brain-ver" hidden title="The RuvNet-Brain version running on this machine"></span>
52
+ <button class="update-gong mono" id="brain-update" hidden type="button"
53
+ title="A newer release is out — click to copy the update command"></button>
54
+ </div>
55
+ <div class="head-right">
56
+ <!-- Its own class on purpose: this is a DOOR, not machine chrome. It once borrowed
57
+ .host-chip and vanished with the readout on phones (see THE TIPS DOOR in style.css). -->
58
+ <a class="tips-link mono" href="tips.html" title="How to actually use the Brain — three depths, one visual page"><span class="tl-long">how to use it</span><span class="tl-short">tips</span> →</a>
59
+ <span class="host-chip mono" id="host-chip" hidden></span>
60
+ <button class="theme-toggle" id="recheck-btn" type="button" aria-label="Re-check my machine now"
61
+ title="Re-check my machine — refresh every card from live state (runs automatically after every fix)">↻</button>
62
+ <button class="theme-toggle" id="theme-toggle" type="button" aria-label="Switch color theme">
63
+ <svg class="ic-sun" viewBox="0 0 24 24" aria-hidden="true">
64
+ <circle cx="12" cy="12" r="4.5" />
65
+ <g class="rays"><line x1="12" y1="2" x2="12" y2="5"/><line x1="12" y1="19" x2="12" y2="22"/><line x1="2" y1="12" x2="5" y2="12"/><line x1="19" y1="12" x2="22" y2="12"/><line x1="4.9" y1="4.9" x2="7" y2="7"/><line x1="17" y1="17" x2="19.1" y2="19.1"/><line x1="4.9" y1="19.1" x2="7" y2="17"/><line x1="17" y1="7" x2="19.1" y2="4.9"/></g>
66
+ </svg>
67
+ <svg class="ic-moon" viewBox="0 0 24 24" aria-hidden="true">
68
+ <path d="M20.4 14.3A8.5 8.5 0 0 1 9.7 3.6a8.5 8.5 0 1 0 10.7 10.7Z" />
69
+ </svg>
70
+ </button>
71
+ </div>
72
+ </div>
73
+ <div class="spectrum-edge" aria-hidden="true"></div>
74
+ </header>
75
+
76
+ <main id="main" class="wrap">
77
+
78
+ <!-- ===========================================================================================
79
+ THE MASTER SWITCH, WHERE A MASTER SWITCH GOES (owner, 2026-07-27).
80
+
81
+ ADR-054 shipped the brain's on/off switch and the console rendered it — as one field inside the
82
+ Settings card, several sections down, behind a chevron. The owner opened the page, looked for
83
+ "a big on/off switch", could not find it, and asked the only question that matters about it:
84
+ "if it didn't show up in the console, how can it be implemented?" He is right. A control that
85
+ governs every other thing on the page cannot live below the things it governs, and a switch
86
+ nobody can find is, from where the user stands, a switch that does not exist.
87
+
88
+ So it is its own card, first on the page, always open (a plain <section>, never <details> —
89
+ nothing about the power switch may be one click away), and there is exactly ONE of it: the
90
+ duplicate rendering inside Settings is gone, replaced by a line pointing here. Same endpoint,
91
+ same single writer (/api/save-brain-power → saveBrainPower), same read-back-from-disk
92
+ discipline; only the prominence changed. -->
93
+ <section class="card brain-card rail-act" id="card-brain" aria-labelledby="card-brain-h">
94
+ <div class="qgroup-head">
95
+ <span class="card-ic ic-act" aria-hidden="true">
96
+ <svg viewBox="0 0 24 24"><path d="M12 3.5v7.2"/><path d="M7.6 6.4a7 7 0 1 0 8.8 0"/></svg>
97
+ </span>
98
+ <span class="card-head">
99
+ <span class="stage st-act">Act</span>
100
+ <h2 id="card-brain-h">Brain power</h2>
101
+ <span class="q">The one switch. Everything else on this page is what the brain does — this is whether it does it at all.</span>
102
+ </span>
103
+ <span class="chips" id="chips-brain"><span class="chip tone-wait">checking…</span></span>
104
+ </div>
105
+ <div class="body" id="body-brain">
106
+ <div class="skeleton" aria-hidden="true"><div class="sk-bar w40"></div><div class="sk-bar w75"></div></div>
107
+ </div>
108
+ </section>
109
+
110
+ <!-- ======================================================= HERO -->
111
+ <section class="intro">
112
+ <div class="intro-grid">
113
+ <div class="intro-copy">
114
+ <p class="eyebrow">RuvNet Brain · your machine, mirrored</p>
115
+ <h1>Your invisible AI stack, <em>made visible.</em></h1>
116
+ <p class="lede">rUv's tools do their best work invisibly — memory learning in the background,
117
+ agents routing work, audits keeping score. This page makes it all visible and puts it to work
118
+ for you: what's installed, what it's doing right now, and one-click ways to get more from it.
119
+ You get thinking that runs months ahead of the mainstream without having to master every tool —
120
+ the Brain acts as the expert at your side. Every suggestion arrives with evidence, a cost, and
121
+ its undo — nothing changes until you say so.</p>
122
+ <p class="motto mono" aria-label="How this console works, in order">
123
+ <span class="m m-mirror">Mirror</span><span class="sep">→</span><span class="m m-mirror">Explain</span><span class="sep">→</span><span class="m m-rec">Recommend</span><span class="sep">→</span><span class="m m-rec">Apply</span><span class="m-note">with your consent</span><span class="sep">→</span><span class="m m-undo">Undo</span>
124
+ </p>
125
+
126
+ <!-- THE CONTRACT. The owner's own words (2026-07-24), near-verbatim and deliberately placed
127
+ ABOVE the fold rather than in a footer: the people this page is for are experienced
128
+ enough to be wary of a tool that touches their environment, and wariness is answered
129
+ before the first switch is seen or not at all. "Nothing is permanent" is not a slogan
130
+ here — every control on this page has a verified reverse, and any capability whose undo
131
+ we cannot verify is rendered as instructions instead of as a switch. -->
132
+ <p class="contract">
133
+ <strong>You don't need to decide any of this right now.</strong> Nothing here is permanent —
134
+ every switch on this page is reversible, and you stay in control the whole way through.
135
+ We'll make recommendations, but you know your system better than we do. This is here to make
136
+ more of the rUv stack easy to reach, not to make choices for you.
137
+ </p>
138
+ </div>
139
+
140
+ <!-- Machine meta (user · platform · node · npm) is a grid sibling of the copy, not part
141
+ of it: on desktop it keeps its old seat under the motto; on phones it yields its
142
+ rows to the tips door and follows the hero instead (style.css places it). -->
143
+ <div class="meta-row mono" id="host-meta" hidden></div>
144
+
145
+ <!-- The right column: the door first, then the art. The tips CTA lives HERE — in the dead
146
+ space above the hero art — because the only link to tips.html was dressed as header
147
+ chrome and nobody saw it. The glyph is the tips page's own metaphor in miniature
148
+ (strata since 2026-07-24 — the rings retired with the tips hero): your prompt's caret
149
+ at the surface, three depth strata beneath — solid cyan always-on · dashed amber
150
+ say-it · dotted green name-it. -->
151
+ <div class="intro-side">
152
+ <a class="tips-cta" href="tips.html">
153
+ <span class="tc-glyph" aria-hidden="true">
154
+ <svg viewBox="0 0 64 64">
155
+ <rect class="tc-caret" x="30.9" y="8" width="2.2" height="8" rx="1.1"/>
156
+ <line class="tc-r1" x1="11" y1="27" x2="53" y2="27"/>
157
+ <line class="tc-r2" x1="11" y1="41" x2="53" y2="41"/>
158
+ <line class="tc-r3" x1="11" y1="55" x2="53" y2="55"/>
159
+ </svg>
160
+ </span>
161
+ <span class="tc-text">
162
+ <span class="tc-kicker mono">new here? start with this</span>
163
+ <span class="tc-title">Go to the usage tips page <span class="tc-arrow" aria-hidden="true">→</span></span>
164
+ <span class="tc-sub">How to actually use the Brain — three depths on one visual page.
165
+ The first depth is doing nothing: it's already working.</span>
166
+ <span class="tc-depths mono">
167
+ <span class="td"><span class="td-dot dd-1"></span>1 · do nothing</span>
168
+ <span class="td"><span class="td-dot dd-2"></span>2 · say it plain</span>
169
+ <span class="td"><span class="td-dot dd-3"></span>3 · name the tool</span>
170
+ </span>
171
+ </span>
172
+ </a>
173
+
174
+ <!-- Hero art: assets/hero.webp when present; the authored constellation
175
+ beneath it means the frame is never empty or broken. -->
176
+ <figure class="hero-art" aria-hidden="true">
177
+ <svg class="hero-scene" viewBox="0 0 640 420" preserveAspectRatio="xMidYMid slice">
178
+ <defs>
179
+ <radialGradient id="hgA" cx="16%" cy="10%" r="65%">
180
+ <stop offset="0" stop-color="#f0a830" stop-opacity="0.35"/><stop offset="1" stop-color="#f0a830" stop-opacity="0"/>
181
+ </radialGradient>
182
+ <radialGradient id="hgB" cx="90%" cy="26%" r="60%">
183
+ <stop offset="0" stop-color="#5ad6ff" stop-opacity="0.28"/><stop offset="1" stop-color="#5ad6ff" stop-opacity="0"/>
184
+ </radialGradient>
185
+ <radialGradient id="hgC" cx="52%" cy="100%" r="60%">
186
+ <stop offset="0" stop-color="#5fd38a" stop-opacity="0.22"/><stop offset="1" stop-color="#5fd38a" stop-opacity="0"/>
187
+ </radialGradient>
188
+ </defs>
189
+ <rect width="640" height="420" fill="#0b0d12"/>
190
+ <rect width="640" height="420" fill="url(#hgA)"/>
191
+ <rect width="640" height="420" fill="url(#hgB)"/>
192
+ <rect width="640" height="420" fill="url(#hgC)"/>
193
+ <g class="hs-edges" fill="none" stroke="#3a4152" stroke-width="1">
194
+ <path d="M96 312 L172 218 L262 276 L96 312"/>
195
+ <path d="M172 218 L306 152 L404 226 L262 276"/>
196
+ <path d="M306 152 L214 92 M306 152 L474 120 L560 186 L524 268 L404 226"/>
197
+ <path d="M404 226 L386 334 L262 276 M524 268 L386 334"/>
198
+ </g>
199
+ <g class="hs-nodes">
200
+ <circle cx="96" cy="312" r="4" fill="#59617a"/>
201
+ <circle cx="172" cy="218" r="5" fill="#59617a"/>
202
+ <circle cx="262" cy="276" r="4" fill="#59617a"/>
203
+ <circle cx="214" cy="92" r="3.4" fill="#59617a"/>
204
+ <circle cx="560" cy="186" r="3.6" fill="#59617a"/>
205
+ <circle cx="524" cy="268" r="4.2" fill="#59617a"/>
206
+ <circle class="hs-glow g1" cx="306" cy="152" r="7" fill="#f0a830"/>
207
+ <circle class="hs-glow g2" cx="474" cy="120" r="6" fill="#5ad6ff"/>
208
+ <circle class="hs-glow g3" cx="386" cy="334" r="6" fill="#5fd38a"/>
209
+ </g>
210
+ <circle cx="306" cy="152" r="17" fill="none" stroke="#f0a830" stroke-opacity="0.35" class="hs-ring"/>
211
+ </svg>
212
+ <img class="hero-img" src="assets/hero.webp" alt="" onerror="this.remove()" />
213
+ <figcaption class="hero-cap mono">read locally · written never (until you say)</figcaption>
214
+ </figure>
215
+ </div><!-- /intro-side -->
216
+ </div>
217
+
218
+ <!-- "We looked at your computer and found…" — filled from live state -->
219
+ <!-- THE VERDICT LINE. The one sentence the page never said — see updateVerdict() in app.js.
220
+ Sits ABOVE the ribbon of raw counts on purpose: the answer first, the receipts under it. -->
221
+ <p class="verdict" id="verdict" hidden></p>
222
+ <div class="found-strip" id="found-strip" hidden></div>
223
+ <!-- Page-level standby line: shown until the first card hydrates, then fades (app.js). -->
224
+ <p class="standby-note" id="standby-note">Stand by — we're auditing how you use these tools
225
+ across the projects on your computer. This is private: it runs locally and only you can see it.
226
+ Coding setups are personal, so the recommendations are built for yours.</p>
227
+ <div class="banner-error" id="global-error" role="alert" hidden></div>
228
+ </section>
229
+
230
+ <noscript>
231
+ <div class="banner-error" role="alert">
232
+ This console needs JavaScript — it renders your machine's live state, and there is nothing to
233
+ show without it. No scripts load from the network; everything runs locally.
234
+ </div>
235
+ </noscript>
236
+
237
+ <!-- One line that names the color system every card wears (rail, stage chip, icon).
238
+ Static semantics, not data — safe to show before anything hydrates. -->
239
+ <p class="stage-legend mono" aria-label="What the card colors mean">
240
+ <span class="lg-cap">card colors</span>
241
+ <span class="lg"><span class="lg-dot d-cyan"></span>cyan observes</span>
242
+ <span class="lg"><span class="lg-dot d-green"></span>green proves it live</span>
243
+ <span class="lg"><span class="lg-dot d-amber"></span>amber acts — only with your consent</span>
244
+ </p>
245
+
246
+
247
+ <!-- ===========================================================================================
248
+ FOUR SECTIONS, ONE PER QUESTION A PERSON ACTUALLY ASKS (design-grade -5, 2026-07-24 owner spec).
249
+ Twelve peer <details class="card"> used to sit flat under <main> — five of them thin collapsed
250
+ strips in a row ("memory / routing / published / settings / which-copy"), reading as a wall of
251
+ unopened drawers. The fix is structural, not cosmetic: group the same 12 cards under 4 top-level
252
+ sections, each answering one question. Every #body-*/#chips-* id app.js hydrates by is untouched
253
+ and unmoved in meaning — only the PARENT element changed, so hydration keeps working unmodified.
254
+
255
+ A question-group (`.qgroup`) is a plain, ALWAYS-VISIBLE <section>, not a fifth flavor of
256
+ collapsible chrome that can't actually toggle — it reuses `.card`'s box (border/shadow/rail/
257
+ radius) for visual consistency, but its header has no chevron and no hover state, so nobody
258
+ expects a click that would do nothing. Every card nested inside keeps its own independent
259
+ open/closed state and its own `app.js`-driven behavior exactly as before (e.g. `#card-stack`'s
260
+ "only expand when it has something to say" logic is a plain `getElementById` lookup and does
261
+ not care how deep it's nested). Nested cards get `.sub-card`, a quieter variant (no shadow, no
262
+ deep-shadow-on-open) so they read as the CONTENTS of an open section, not more drawers in a row. -->
263
+
264
+ <!-- ================================================= GROUP 1 · WHAT HAVE I GOT? -->
265
+ <section class="card qgroup rail-mirror" id="group-inventory" aria-labelledby="group-inventory-h">
266
+ <div class="qgroup-head">
267
+ <span class="card-ic ic-mirror" aria-hidden="true">
268
+ <svg viewBox="0 0 24 24"><rect x="3" y="3" width="8" height="8" rx="1.8"/><rect x="13" y="3" width="8" height="8" rx="1.8"/><rect x="3" y="13" width="8" height="8" rx="1.8"/><rect x="13" y="13" width="8" height="8" rx="1.8"/></svg>
269
+ </span>
270
+ <span class="card-head">
271
+ <span class="stage st-mirror">Mirror</span>
272
+ <h2 id="group-inventory-h">What have I got?</h2>
273
+ <span class="q">Every rUv tool on this machine — what's installed, whether it's really what we published, and where each project launches it from.</span>
274
+ </span>
275
+ </div>
276
+ <div class="qgroup-body">
277
+
278
+ <!-- 1a · YOUR STACK (leads; Stuart 2026-07-16)
279
+ Starts EXPANDED only when it has something to say: an action to take, or the user's first
280
+ visit. A clean, all-current stack on a repeat visit starts collapsed — app.js decides. -->
281
+ <details class="card sub-card rail-mirror" id="card-stack">
282
+ <summary>
283
+ <span class="card-ic ic-mirror" aria-hidden="true">
284
+ <svg viewBox="0 0 24 24"><path d="M12 3 3.5 7.5 12 12l8.5-4.5L12 3Z"/><path d="M4.5 12 12 16l7.5-4"/><path d="M4.5 16 12 20l7.5-4"/></svg>
285
+ </span>
286
+ <span class="card-head">
287
+ <span class="stage st-mirror">Mirror</span>
288
+ <h2>Your stack</h2>
289
+ <span class="q">Every rUv tool on your machine, kept at its best — and one click when anything drifts.</span>
290
+ </span>
291
+ <span class="chips" id="chips-stack"><span class="chip tone-wait">checking…</span></span>
292
+ <span class="chev" aria-hidden="true">›</span>
293
+ </summary>
294
+ <div class="body" id="body-stack">
295
+ <div class="skeleton" aria-hidden="true">
296
+ <div class="sk-bar w35"></div>
297
+ <div class="sk-bar w90"></div>
298
+ <div class="sk-bar w85"></div>
299
+ <div class="sk-bar w88"></div>
300
+ <div class="sk-bar w60"></div>
301
+ </div>
302
+ <p class="loading-note">Auditing your installed packages against the registry — this one touches
303
+ the network and usually takes 5–20 seconds. Private by design: the registry only ever sees
304
+ ordinary version lookups — nothing about you or your projects leaves this machine. Everything
305
+ below is already live.</p>
306
+ </div>
307
+ </details>
308
+
309
+ <!-- 1b · TRUST & PROVENANCE (v3.3 preview)
310
+ PROVE-stage: what you install is what we published. One number is REAL today (the release
311
+ bundle's published sha256); the empty rows say exactly what will fill them and when —
312
+ never placeholder data. -->
313
+ <details class="card sub-card rail-prove" id="card-trust">
314
+ <summary>
315
+ <span class="card-ic ic-prove" aria-hidden="true">
316
+ <svg viewBox="0 0 24 24"><path d="M12 3.5 5 6v5.5c0 4.4 2.9 7.5 7 9 4.1-1.5 7-4.6 7-9V6l-7-2.5Z"/><path d="m8.8 12 2.3 2.3 4.1-4.6"/></svg>
317
+ </span>
318
+ <span class="card-head">
319
+ <span class="stage st-prove">Prove</span>
320
+ <h2>Is this really what we published?</h2>
321
+ <span class="q">Is the Brain you're running the one we published? Checked against the release, not asserted.</span>
322
+ </span>
323
+ <span class="chips" id="chips-trust"><span class="chip tone-wait">checking…</span></span>
324
+ <span class="chev" aria-hidden="true">›</span>
325
+ </summary>
326
+ <div class="body" id="body-trust">
327
+ <div class="skeleton" aria-hidden="true"><div class="sk-bar w45"></div><div class="sk-bar w70"></div></div>
328
+ <p class="loading-note">Reading the published release fingerprint from GitHub (read-only metadata —
329
+ the one network touch this card makes) and your plugin cache on disk.</p>
330
+ </div>
331
+ </details>
332
+
333
+ <!-- 1c · HOW IT'S WIRED -->
334
+ <details class="card sub-card rail-mirror" id="card-wiring">
335
+ <summary>
336
+ <span class="card-ic ic-mirror" aria-hidden="true">
337
+ <svg viewBox="0 0 24 24"><circle cx="5" cy="19" r="2.2"/><path d="M6.6 17.4 11 13h5.5"/><rect x="16.5" y="9.5" width="5.5" height="7" rx="1.6"/><path d="M11 13V6.5h5.5"/></svg>
338
+ </span>
339
+ <span class="card-head">
340
+ <span class="stage st-mirror">Explain</span>
341
+ <h2>Which copy of the tools each project runs</h2>
342
+ <span class="q">Where each project launches rUv's tools from — and one click to the fastest, safest wiring.</span>
343
+ </span>
344
+ <span class="chips" id="chips-wiring"><span class="chip tone-wait">…</span></span>
345
+ <span class="chev" aria-hidden="true">›</span>
346
+ </summary>
347
+ <div class="body" id="body-wiring">
348
+ <div class="skeleton" aria-hidden="true"><div class="sk-bar w50"></div><div class="sk-bar w80"></div></div>
349
+ <p class="loading-note">Scanning your projects' hook files locally — how you launch your tools is
350
+ personal, and it stays on this machine.</p>
351
+ </div>
352
+ </details>
353
+
354
+ </div>
355
+ </section>
356
+
357
+ <!-- ================================================= GROUP 2 · WHAT'S ON — AND WHAT WE'D SUGGEST -->
358
+ <section class="card qgroup rail-act" id="group-suggested" aria-labelledby="group-suggested-h">
359
+ <div class="qgroup-head">
360
+ <span class="card-ic ic-act" aria-hidden="true">
361
+ <svg viewBox="0 0 24 24"><path d="M4 16a8 8 0 1 1 16 0"/><path d="M12 16 16.2 9.6"/><circle cx="12" cy="16" r="1.6"/></svg>
362
+ </span>
363
+ <span class="card-head">
364
+ <span class="stage st-rec">Recommend</span>
365
+ <h2 id="group-suggested-h">What's on — and what we'd suggest</h2>
366
+ <span class="q">The black box opened: every capability's real state, the settings you actually control, and the specific fixes we'd propose — each with evidence and an undo.</span>
367
+ </span>
368
+ </div>
369
+ <div class="qgroup-body">
370
+
371
+ <!-- 2a · WHAT'S ON, WHAT'S OFF
372
+ THE MURK, NAMED (owner, 2026-07-22): "a ton of people don't know what is or isn't turned on
373
+ because it's very much a black box." Starts open on purpose — a card that answers the
374
+ central complaint must not be behind a click. Every row is rendered from /api/capabilities
375
+ at runtime; there is deliberately not one capability name in this markup. -->
376
+ <details class="card sub-card rail-mirror" id="card-capabilities" open>
377
+ <summary>
378
+ <span class="card-ic ic-mirror" aria-hidden="true">
379
+ <!-- two switches, one thrown each way — the card's whole question in one glyph -->
380
+ <svg viewBox="0 0 24 24"><rect x="2.6" y="4.2" width="18.8" height="7.2" rx="3.6"/><circle cx="17.8" cy="7.8" r="1.7"/><rect x="2.6" y="12.6" width="18.8" height="7.2" rx="3.6"/><circle cx="6.2" cy="16.2" r="1.7"/></svg>
381
+ </span>
382
+ <span class="card-head">
383
+ <span class="stage st-mirror">Mirror</span>
384
+ <h2>What's on, what's off</h2>
385
+ <span class="q">The black box, opened: every capability with its state, what it buys you, and the evidence we actually observed.</span>
386
+ </span>
387
+ <span class="chips" id="chips-capabilities"><span class="chip tone-wait">…</span></span>
388
+ <span class="chev" aria-hidden="true">›</span>
389
+ </summary>
390
+ <div class="body" id="body-capabilities">
391
+ <div class="skeleton" aria-hidden="true"><div class="sk-bar w40"></div><div class="sk-bar w80"></div><div class="sk-bar w65"></div></div>
392
+ <p class="loading-note">Checking each capability against this machine — local and read-only.
393
+ Anything we can't establish is reported as “not checked”, never as “off”.</p>
394
+ </div>
395
+ </details>
396
+
397
+ <!-- 2b · SETTINGS -->
398
+ <details class="card sub-card rail-act" id="card-settings">
399
+ <summary>
400
+ <span class="card-ic ic-act" aria-hidden="true">
401
+ <svg viewBox="0 0 24 24"><path d="M5 4v6.5M5 15v5"/><circle cx="5" cy="12.8" r="2.1"/><path d="M12 4v2M12 10.5v9.5"/><circle cx="12" cy="8.3" r="2.1"/><path d="M19 4v9M19 17.5V20"/><circle cx="19" cy="15.3" r="2.1"/></svg>
402
+ </span>
403
+ <span class="card-head">
404
+ <span class="stage st-rec">Apply</span>
405
+ <h2>Settings</h2>
406
+ <span class="q">Tune how the stack works for you — each choice names the runtime it changes, and every save is reversible.</span>
407
+ </span>
408
+ <span class="chips" id="chips-settings"><span class="chip tone-wait">…</span></span>
409
+ <span class="chev" aria-hidden="true">›</span>
410
+ </summary>
411
+ <div class="body" id="body-settings">
412
+ <div class="skeleton" aria-hidden="true"><div class="sk-bar w50"></div><div class="sk-bar w65"></div></div>
413
+ <p class="loading-note">Reading one settings file from your user folder — local, yours, and the
414
+ only thing this page ever writes.</p>
415
+ </div>
416
+ </details>
417
+
418
+ <!-- 2c · WHAT WE'D SUGGEST -->
419
+ <details class="card sub-card rail-act" id="card-recs">
420
+ <summary>
421
+ <span class="card-ic ic-act" aria-hidden="true">
422
+ <svg viewBox="0 0 24 24"><path d="M9.7 18h4.6"/><path d="M10.4 21h3.2"/><path d="M8.6 14.4C7 13.1 6 11.3 6 9.4a6 6 0 1 1 12 0c0 1.9-1 3.7-2.6 5-.6.5-.9 1.3-.9 2.1v.5H9.5v-.5c0-.8-.3-1.6-.9-2.1Z"/></svg>
423
+ </span>
424
+ <span class="card-head">
425
+ <span class="stage st-rec">Recommend</span>
426
+ <h2>What we'd suggest</h2>
427
+ <span class="q">Evidence, cost, and an undo for every proposal — Apply is always your call.</span>
428
+ </span>
429
+ <span class="chips" id="chips-recs"><span class="chip tone-wait">…</span></span>
430
+ <span class="chev" aria-hidden="true">›</span>
431
+ </summary>
432
+ <div class="body" id="body-recs">
433
+ <div id="recs-batch"></div>
434
+ <div id="recs-list"></div>
435
+ <p class="pending-note" id="recs-pending">Still auditing your stack — more suggestions may appear here in a moment.</p>
436
+ <div id="recs-empty" hidden></div>
437
+ </div>
438
+ </details>
439
+
440
+ <!-- 2d · WHAT "PROACTIVE" MEANS (the L0-L5 ladder)
441
+ The product's central adjective was used everywhere and defined nowhere. STATIC MARKUP, ON
442
+ PURPOSE: this is the one card that must render before any fetch resolves, so hydrating it
443
+ from an endpoint would make the definition of our own claim contingent on a network call.
444
+ Closed by default. Nested HERE, in the settings/suggestions group, rather than floating
445
+ between two unrelated cards — it explains the software; the one real control it names
446
+ (the advocacy dial) lives in the Settings card right above it in this same section, and
447
+ the pointer paragraph at the end of this card's body links straight to it. -->
448
+ <details class="card sub-card rail-mirror" id="card-proactive">
449
+ <summary>
450
+ <span class="card-ic ic-mirror" aria-hidden="true">
451
+ <!-- a rising flight of steps: the ladder itself, five treads, one of them marked -->
452
+ <svg viewBox="0 0 24 24"><path d="M2.5 20.5h4v-4h4v-4h4v-4h4v-4"/><circle cx="10.5" cy="12.5" r="1.6"/></svg>
453
+ </span>
454
+ <span class="card-head">
455
+ <span class="stage st-mirror">Mirror</span>
456
+ <h2>What “proactive” means here</h2>
457
+ <!-- "Five levels" over a six-rung L0-L5 list, and a tooltip saying "the top TWO are not
458
+ built" directly above fineprint saying "L3, L4 and L5 are not built". ADR-0028 is the
459
+ authority and says six rungs, L0-L5, with three unbuilt; this matches it. -->
460
+ <span class="q">Six levels, L0 to L5, and an honest marker of which one this build has actually reached.</span>
461
+ </span>
462
+ <span class="chips"><span class="chip tone-nt" title="Where this build sits on the ladder below — L3, L4 and L5 are not built.">at level 2 of 5</span></span>
463
+ <span class="chev" aria-hidden="true">›</span>
464
+ </summary>
465
+ <div class="body">
466
+ <p>“Proactive” is the claim this whole product rests on, so here is exactly what it commits us
467
+ to — and where it currently stops.</p>
468
+ <ol class="ladder">
469
+ <li class="lv done"><b>L0 · Reactive</b><span>Answers when you ask. A question gets a grounded, cited answer.</span></li>
470
+ <li class="lv done"><b>L1 · Observant</b><span>Notices and displays the state of your machine — the capabilities card above, in this section.</span></li>
471
+ <li class="lv here"><b>L2 · Advocating</b><span>Finds a dormant capability, proposes the fix, applies it once you consent, and can undo it. Every suggestion resolves to one working executor and one real undo. <b>This build is here.</b></span></li>
472
+ <li class="lv todo"><b>L3 · Contextual</b><span>Speaks up inside your working session, at the moment it matters, without you opening this page.</span></li>
473
+ <li class="lv todo"><b>L4 · Anticipatory</b><span>Works out what you are trying to do and names the better path before you commit to the worse one.</span></li>
474
+ <li class="lv todo"><b>L5 · Compounding</b><span>Checks whether its own advice was right, and promotes what held up so every project inherits it.</span></li>
475
+ </ol>
476
+ <p class="fineprint">L3, L4 and L5 are <b>not built</b>, and this page will not imply otherwise —
477
+ each level is a falsifiable test, not a mood, and the top three do not pass yet. The capabilities
478
+ card in this section is L1 doing its job; anything with an undo behind it is L2. Full definitions
479
+ and the tests each level has to pass: <code>docs/adr/0028</code>.</p>
480
+ <p class="fineprint">The one thing on this list you can actually set is the volume on advocacy
481
+ itself: the <a href="#field-advocacy"><b>“How much it volunteers”</b></a> dial, in the Settings
482
+ card in this same section. Everything above is a description of the software, not a switch.</p>
483
+ </div>
484
+ </details>
485
+
486
+ </div>
487
+ </section>
488
+
489
+ <!-- ===================================== GROUP 3 · WHAT IT'S LEARNED FROM YOU (the Learn pillar)
490
+ No wrapper needed — this card already answers its own question on its own, so it stands as the
491
+ third top-level peer exactly as before (still open, still first of the four to load).
492
+
493
+ THE GAP THIS CLOSES. Sixteen lessons — thirteen of them the owner's OWN WORDS, one enforcing at
494
+ BLOCK level — lived in a JSON file with a CLI over it and appeared NOWHERE on this page. The
495
+ owner's phrasing (2026-07-24): "murky things in a .claude file nobody sees." lesson-store.mjs's
496
+ own `pending()` is documented as "what the management surface must show first"; there was no
497
+ management surface. A rule you cannot SEE is a rule you never consented to, and an unconsented
498
+ rule that BLOCKS your work is the shortest path to someone deleting this product.
499
+
500
+ AMBER, NOT CYAN. This card's first job is the count awaiting YOUR decision — it is a decision
501
+ surface, not a mirror. It shares the palette of Recommend/Apply because it asks the same thing
502
+ of you. No fourth colour was invented for it; the palette has three semantic colours and a
503
+ fourth would be decoration pretending to be meaning.
504
+
505
+ Every row carries provenance in plain words ("you taught me this" vs "I inferred this"), because
506
+ the ratification boundary is the whole trust story: the model may not ratify its own rules, and
507
+ a model-inferred lesson can never reach BLOCK however often it fires (lesson-store.mjs:380). -->
508
+ <details class="card rail-act" id="card-lessons" open>
509
+ <summary>
510
+ <span class="card-ic ic-rec" aria-hidden="true">
511
+ <!-- an open book with a check — what was learned, and what you signed off on -->
512
+ <svg viewBox="0 0 24 24"><path d="M3 5.2h6.4a2.6 2.6 0 0 1 2.6 2.6v11a2.2 2.2 0 0 0-2.2-2.2H3Z"/><path d="M21 5.2h-6.4a2.6 2.6 0 0 0-2.6 2.6v11a2.2 2.2 0 0 1 2.2-2.2H21Z"/><path d="m15.4 11.3 1.5 1.5 3-3"/></svg>
513
+ </span>
514
+ <span class="card-head">
515
+ <span class="stage st-rec">Learn</span>
516
+ <h2>What it's learned from you</h2>
517
+ <span class="q">Every rule this AI now works by — where it came from, what it does to me, and a switch on each one. Nothing here was ratified by the model itself.</span>
518
+ </span>
519
+ <span class="chips" id="chips-lessons"><span class="chip tone-wait">…</span></span>
520
+ <span class="chev" aria-hidden="true">›</span>
521
+ </summary>
522
+ <div class="body" id="body-lessons">
523
+ <div class="skeleton" aria-hidden="true"><div class="sk-bar w45"></div><div class="sk-bar w85"></div><div class="sk-bar w70"></div></div>
524
+ <p class="loading-note">Reading the lesson store on this machine — local and read-only.
525
+ Turning one off is reversible: it hides the rule without deleting the record of where you taught it.</p>
526
+ </div>
527
+ </details>
528
+
529
+ <!-- ================================================= GROUP 4 · PROVE IT'S WORKING -->
530
+ <section class="card qgroup rail-prove" id="group-prove" aria-labelledby="group-prove-h">
531
+ <div class="qgroup-head">
532
+ <span class="card-ic ic-prove" aria-hidden="true">
533
+ <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.6"/><path d="m8.2 12.4 2.6 2.6 5.2-5.6"/></svg>
534
+ </span>
535
+ <span class="card-head">
536
+ <span class="stage st-prove">Prove</span>
537
+ <h2 id="group-prove-h">Prove it's working</h2>
538
+ <span class="q">Live checks, not claims: what your AI has actually done, whether memory really crosses projects, whether routing is saving anything, and what the guardrails have stopped.</span>
539
+ </span>
540
+ </div>
541
+ <div class="qgroup-body">
542
+
543
+ <details class="card sub-card rail-mirror" id="card-activity" open>
544
+ <summary>
545
+ <span class="card-ic ic-mirror" aria-hidden="true">
546
+ <svg viewBox="0 0 24 24"><path d="M3 12h4l2.5-6 4 12L16 12h5"/></svg>
547
+ </span>
548
+ <span class="card-head">
549
+ <span class="stage st-mirror">Mirror</span>
550
+ <h2>What is happening in <em>this</em> project</h2>
551
+ <span class="q">What your AI learned &amp; did — live from AgentDB.</span>
552
+ </span>
553
+ <span class="chips" id="chips-activity"><span class="chip tone-wait">…</span></span>
554
+ <span class="chev" aria-hidden="true">›</span>
555
+ </summary>
556
+ <div class="body" id="body-activity">
557
+ <div class="skeleton" aria-hidden="true"><div class="sk-bar w40"></div><div class="sk-bar w75"></div></div>
558
+ </div>
559
+ </details>
560
+
561
+ <!-- MEMORY HEALTH -->
562
+ <details class="card sub-card rail-prove" id="card-memory">
563
+ <summary>
564
+ <span class="card-ic ic-prove" aria-hidden="true">
565
+ <svg viewBox="0 0 24 24"><ellipse cx="12" cy="6" rx="7.5" ry="3"/><path d="M4.5 6v12c0 1.7 3.4 3 7.5 3s7.5-1.3 7.5-3V6"/><path d="M4.5 12c0 1.7 3.4 3 7.5 3s7.5-1.3 7.5-3"/></svg>
566
+ </span>
567
+ <span class="card-head">
568
+ <span class="stage st-prove">Prove</span>
569
+ <h2>Your memory, across <em>every</em> project</h2>
570
+ <span class="q">Your system learns and shares intelligence across projects — this card tests it live, so you never have to wonder.</span>
571
+ </span>
572
+ <span class="chips" id="chips-memory"><span class="chip tone-wait">…</span></span>
573
+ <span class="chev" aria-hidden="true">›</span>
574
+ </summary>
575
+ <div class="body" id="body-memory">
576
+ <div class="skeleton" aria-hidden="true"><div class="sk-bar w40"></div><div class="sk-bar w75"></div></div>
577
+ <p class="loading-note">Reading your local memory stores — everything stays on this machine. Recall quality is
578
+ reported as not-tested until a real probe runs; nothing here is scored on a guess.</p>
579
+ </div>
580
+ </details>
581
+
582
+ <!-- SMART ROUTING (MetaHarness)
583
+ NOT `open`: a card ASKING FOR A DECISION outranking cards REPORTING STATE was a ranking
584
+ error. State first, choices second. The engine keeps its real name inside the body, where
585
+ naming it is information rather than a hurdle. -->
586
+ <details class="card sub-card rail-prove" id="card-savings">
587
+ <summary>
588
+ <span class="card-ic ic-prove" aria-hidden="true">
589
+ <svg viewBox="0 0 24 24"><path d="M3.5 12h5c3.5 0 3.5-5.5 7-5.5h4.5"/><path d="M8.5 12c3.5 0 3.5 5.5 7 5.5H20"/><path d="m17.5 3.8 3 2.7-3 2.7"/><path d="m17.5 14.8 3 2.7-3 2.7"/></svg>
590
+ </span>
591
+ <span class="card-head">
592
+ <span class="stage st-prove">Prove</span>
593
+ <h2>Smart model routing</h2>
594
+ <span class="q">Cheap tasks go to cheap models, and every routing decision leaves a receipt. Off by default — rUv would rather you chose it. (The engine is called MetaHarness; it's explained inside.)</span>
595
+ </span>
596
+ <span class="chips" id="chips-savings"><span class="chip tone-wait">…</span></span>
597
+ <span class="chev" aria-hidden="true">›</span>
598
+ </summary>
599
+ <div class="body" id="body-savings">
600
+ <div class="skeleton" aria-hidden="true"><div class="sk-bar w45"></div><div class="sk-bar w70"></div></div>
601
+ <p class="loading-note">Reading your real routing receipts from this machine — local and private,
602
+ measured from your own work, never projected.</p>
603
+ </div>
604
+ </details>
605
+
606
+ <!-- WHAT CAUGHT CLAUDE
607
+ The wiring card (in "What have I got?") says where tools launch from. This one answers the
608
+ question the whole harness exists for: what stands between the model and your machine, and
609
+ has it ever actually stopped it? An empty ledger says "nothing caught yet" — it never guesses. -->
610
+ <details class="card sub-card rail-prove" id="card-gates" open>
611
+ <summary>
612
+ <span class="card-ic ic-prove" aria-hidden="true">
613
+ <svg viewBox="0 0 24 24"><path d="M12 3 4.5 6v6c0 4.4 3.2 8.2 7.5 9 4.3-.8 7.5-4.6 7.5-9V6z"/><path d="M9 12l2.2 2.2L15.5 10"/></svg>
614
+ </span>
615
+ <span class="card-head">
616
+ <span class="stage st-prove">Prove</span>
617
+ <h2>What the guardrails stopped</h2>
618
+ <span class="q">Your AI doesn't work alone here — gates read every move before it lands. This is what they stopped.</span>
619
+ </span>
620
+ <span class="chips" id="chips-gates"><span class="chip tone-wait">…</span></span>
621
+ <span class="chev" aria-hidden="true">›</span>
622
+ </summary>
623
+ <div class="body" id="body-gates">
624
+ <div class="skeleton" aria-hidden="true"><div class="sk-bar w50"></div><div class="sk-bar w80"></div></div>
625
+ </div>
626
+ </details>
627
+
628
+ </div>
629
+ </section>
630
+
631
+ </main>
632
+
633
+ <footer class="foot">
634
+ <div class="wrap foot-inner">
635
+ <p class="foot-line">RuvNet Brain · Onboarding Console — served locally from <code>127.0.0.1</code>. No project code or prompts leave your machine; the package audit and trust card fetch version metadata from npm and GitHub.</p>
636
+ <p class="foot-meta mono" id="foot-generated"></p>
637
+ </div>
638
+ </footer>
639
+
640
+ <div class="visually-hidden" role="status" aria-live="polite" id="live-region"></div>
641
+
642
+ <!-- ============================================================ SPOT ILLUSTRATIONS
643
+ Hand-drawn, theme-aware (all colors come from CSS custom properties).
644
+ Cloned into section bodies by app.js. One visual language: 2px round-cap
645
+ line work, tinted plates, one accent per idea. -->
646
+ <div id="illos" hidden>
647
+
648
+ <!-- Your stack: the tidy stack, and the dashed shadow copy beside it -->
649
+ <template id="illo-stack">
650
+ <svg class="illo" viewBox="0 0 220 150" role="img" aria-label="A stack of installed packages with one duplicate shadow copy beside it">
651
+ <g fill="none" stroke="var(--illo-stroke)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
652
+ <rect x="34" y="92" width="88" height="30" rx="7" fill="var(--illo-plate)"/>
653
+ <rect x="40" y="66" width="88" height="30" rx="7" fill="var(--illo-plate)"/>
654
+ <rect x="46" y="40" width="88" height="30" rx="7" fill="var(--illo-plate)"/>
655
+ <line x1="46" y1="54" x2="134" y2="54" stroke="var(--amber)" stroke-opacity="0.9"/>
656
+ <circle cx="60" cy="47" r="2.6" fill="var(--amber)" stroke="none"/>
657
+ </g>
658
+ <g fill="none" stroke="var(--cyan)" stroke-width="2" stroke-linecap="round" stroke-dasharray="5 6">
659
+ <rect x="152" y="58" width="54" height="26" rx="7"/>
660
+ <path d="M134 52 C 146 46, 150 48, 156 54"/>
661
+ </g>
662
+ <circle cx="200" cy="58" r="6.5" fill="var(--surface)" stroke="var(--cyan)" stroke-width="2"/>
663
+ <line x1="197" y1="58" x2="203" y2="58" stroke="var(--cyan)" stroke-width="2" stroke-linecap="round"/>
664
+ </svg>
665
+ </template>
666
+
667
+ <!-- No illo-capabilities template on purpose: spot illustrations are switched off page-wide
668
+ (.illo-box { display: none } — "the decorative doodle stole the width the data needs"), so
669
+ authoring a new one would ship a doodle this repo already decided against. The capability
670
+ card still wraps its body in withIllo() like every other section, for the shared
671
+ .sect-main layout; illoBox() simply returns null when no template exists. -->
672
+
673
+ <!-- How it's wired: one prompt, two routes — the winding cache detour vs the straight binary -->
674
+ <template id="illo-wiring">
675
+ <svg class="illo" viewBox="0 0 220 150" role="img" aria-label="Two resolution paths from a terminal: a winding route through a cache, and a straight route to one binary">
676
+ <g fill="none" stroke="var(--illo-stroke)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
677
+ <rect x="14" y="56" width="52" height="40" rx="8" fill="var(--illo-plate)"/>
678
+ <path d="M26 70 l7 6 -7 6"/>
679
+ <line x1="40" y1="83" x2="52" y2="83"/>
680
+ </g>
681
+ <g fill="none" stroke="var(--cyan)" stroke-width="2" stroke-linecap="round" stroke-dasharray="4 6">
682
+ <path d="M66 66 C 92 34, 104 40, 118 44"/>
683
+ <path d="M150 44 C 166 46, 176 38, 186 40"/>
684
+ </g>
685
+ <rect x="114" y="32" width="40" height="22" rx="11" fill="none" stroke="var(--cyan)" stroke-width="2"/>
686
+ <rect x="186" y="28" width="22" height="22" rx="6" fill="var(--illo-plate)" stroke="var(--illo-stroke)" stroke-width="2"/>
687
+ <g fill="none" stroke="var(--amber)" stroke-width="2.4" stroke-linecap="round">
688
+ <path d="M66 90 L 184 106"/>
689
+ <path d="M177 99 l8 7 -10 3"/>
690
+ </g>
691
+ <rect x="186" y="98" width="22" height="22" rx="6" fill="var(--illo-plate)" stroke="var(--amber)" stroke-width="2"/>
692
+ <circle cx="197" cy="109" r="3" fill="var(--amber)"/>
693
+ </svg>
694
+ </template>
695
+
696
+ <!-- What we'd suggest: a proposal card wrapped in its own undo loop -->
697
+ <template id="illo-recs">
698
+ <svg class="illo" viewBox="0 0 220 150" role="img" aria-label="A proposal card wrapped in an undo arrow">
699
+ <g fill="none" stroke="var(--illo-stroke)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
700
+ <rect x="66" y="36" width="92" height="80" rx="10" fill="var(--illo-plate)"/>
701
+ <line x1="80" y1="58" x2="128" y2="58"/>
702
+ <line x1="80" y1="74" x2="144" y2="74"/>
703
+ <line x1="80" y1="90" x2="120" y2="90"/>
704
+ </g>
705
+ <circle cx="152" cy="44" r="11" fill="var(--surface)" stroke="var(--amber)" stroke-width="2"/>
706
+ <path d="M147 44 l4 4 7 -8" fill="none" stroke="var(--amber)" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
707
+ <g fill="none" stroke="var(--green)" stroke-width="2.2" stroke-linecap="round">
708
+ <path d="M170 96 A 58 46 0 1 1 166 52"/>
709
+ <path d="M162 44 l6 8 -10 2"/>
710
+ </g>
711
+ <g fill="var(--cyan)" stroke="none">
712
+ <circle cx="84" cy="106" r="2.6"/><circle cx="96" cy="106" r="2.6"/><circle cx="108" cy="106" r="2.6"/>
713
+ </g>
714
+ </svg>
715
+ </template>
716
+
717
+ <!-- Memory: the cluster, and one fact recalled up into the light -->
718
+ <template id="illo-memory">
719
+ <svg class="illo" viewBox="0 0 220 150" role="img" aria-label="A memory cluster with one node being recalled upward">
720
+ <g fill="none" stroke="var(--illo-faint)" stroke-width="1.6">
721
+ <path d="M78 96 L108 78 L142 92 L128 118 L92 120 Z"/>
722
+ <path d="M108 78 L128 118 M78 96 L142 92"/>
723
+ </g>
724
+ <g fill="var(--illo-stroke)" stroke="none">
725
+ <circle cx="78" cy="96" r="4"/><circle cx="142" cy="92" r="4"/>
726
+ <circle cx="128" cy="118" r="4"/><circle cx="92" cy="120" r="4"/>
727
+ </g>
728
+ <circle cx="108" cy="78" r="6" fill="var(--amber)"/>
729
+ <path d="M108 70 C 106 54, 112 48, 118 40" fill="none" stroke="var(--amber)" stroke-width="2.2" stroke-linecap="round"/>
730
+ <path d="M112 44 l6 -6 2 9" fill="none" stroke="var(--amber)" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
731
+ <rect x="94" y="14" width="64" height="22" rx="11" fill="var(--illo-plate)" stroke="var(--cyan)" stroke-width="2"/>
732
+ <circle cx="108" cy="25" r="2.6" fill="var(--cyan)"/>
733
+ <line x1="118" y1="25" x2="146" y2="25" stroke="var(--cyan)" stroke-width="2" stroke-linecap="round"/>
734
+ </svg>
735
+ </template>
736
+
737
+ <!-- Savings: a real receipt — measured lines and a total that happened -->
738
+ <template id="illo-savings">
739
+ <svg class="illo" viewBox="0 0 220 150" role="img" aria-label="A printed receipt of measured savings">
740
+ <path d="M74 22 h74 v96 l-9 -7 -9 7 -9 -7 -10 7 -9 -7 -9 7 -10 -7 -9 7 Z"
741
+ fill="var(--illo-plate)" stroke="var(--illo-stroke)" stroke-width="2" stroke-linejoin="round"/>
742
+ <g stroke="var(--illo-faint)" stroke-width="2" stroke-linecap="round">
743
+ <line x1="86" y1="42" x2="128" y2="42"/>
744
+ <line x1="86" y1="56" x2="136" y2="56"/>
745
+ <line x1="86" y1="70" x2="122" y2="70"/>
746
+ </g>
747
+ <line x1="86" y1="90" x2="136" y2="90" stroke="var(--green)" stroke-width="2.6" stroke-linecap="round"/>
748
+ <circle cx="166" cy="102" r="13" fill="var(--surface)" stroke="var(--amber)" stroke-width="2"/>
749
+ <path d="M166 96 v12 M162 99.5 h6.5 a3 3 0 1 1 0 6 h-6.5" fill="none" stroke="var(--amber)" stroke-width="1.8" stroke-linecap="round"/>
750
+ </svg>
751
+ </template>
752
+
753
+ <!-- Settings: three faders, set by hand -->
754
+ <template id="illo-settings">
755
+ <svg class="illo" viewBox="0 0 220 150" role="img" aria-label="Three slider controls at hand-set positions">
756
+ <g stroke="var(--illo-faint)" stroke-width="2.4" stroke-linecap="round">
757
+ <line x1="76" y1="30" x2="76" y2="120"/>
758
+ <line x1="112" y1="30" x2="112" y2="120"/>
759
+ <line x1="148" y1="30" x2="148" y2="120"/>
760
+ </g>
761
+ <line x1="76" y1="58" x2="76" y2="120" stroke="var(--amber)" stroke-width="2.4" stroke-linecap="round"/>
762
+ <line x1="112" y1="96" x2="112" y2="120" stroke="var(--cyan)" stroke-width="2.4" stroke-linecap="round"/>
763
+ <line x1="148" y1="74" x2="148" y2="120" stroke="var(--green)" stroke-width="2.4" stroke-linecap="round"/>
764
+ <circle cx="76" cy="58" r="8" fill="var(--surface)" stroke="var(--amber)" stroke-width="2.4"/>
765
+ <circle cx="112" cy="96" r="8" fill="var(--surface)" stroke="var(--cyan)" stroke-width="2.4"/>
766
+ <circle cx="148" cy="74" r="8" fill="var(--surface)" stroke="var(--green)" stroke-width="2.4"/>
767
+ </svg>
768
+ </template>
769
+
770
+ </div>
771
+
772
+ <!-- Classic deferred script (no imports needed): unlike type="module", it also
773
+ runs from file:// during static preview, where modules are CORS-blocked. -->
774
+ <script defer src="app.js"></script>
775
+ <script defer src="activity.js"></script>
776
+ </body>
777
+ </html>