ruvnet-brain 4.3.25 → 4.3.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/bin/install.mjs +19 -4
- package/console/app.js +48 -0
- package/console/index.html +19 -0
- package/console/style.css +26 -0
- package/data/model-catalog.json +1 -1
- package/docs/RELEASE-NOTES-4.0.md +4 -3
- package/kb/capability-only.mjs +27 -0
- package/kb/capability-summaries/cognitum-ruos/CAPABILITIES.md +26 -0
- package/kb/verify-citation.mjs +16 -4
- package/package.json +5 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/docs/RELEASE-NOTES-4.0.md +4 -3
- package/plugin/hooks/codex-hooks.json +6 -1
- package/plugin/hooks/hook-contracts.json +24 -2
- package/plugin/hooks/hooks.json +6 -1
- package/plugin/scripts/capacity-aware-parallel-work.mjs +200 -0
- package/plugin/scripts/codex-hook-adapter.mjs +37 -0
- package/plugin/scripts/continuity-hook-policy.mjs +4 -0
- package/plugin/scripts/coverage-integrity.mjs +17 -0
- package/plugin/scripts/hook-shim.mjs +1 -0
- package/plugin/scripts/lesson-gate.mjs +4 -1
- package/plugin/scripts/project-progression-reader.mjs +12 -1
- package/plugin/scripts/project-progression-session-start.mjs +24 -6
- package/plugin/scripts/project-progression-store.mjs +76 -4
- package/plugin/skills/release-proof/SKILL.md +28 -4
- package/plugin/skills/release-proof/scripts/release-proof.mjs +48 -24
- package/scripts/brain-novice-50.mjs +14 -16
- package/scripts/build-bundle.mjs +2 -0
- package/scripts/corpus-dispatch-receipt.mjs +22 -0
- package/scripts/corpus-reconcile.mjs +26 -4
- package/scripts/doc-currency.mjs +12 -4
- package/scripts/eval-brain.mjs +7 -5
- package/scripts/gist-git-transport.mjs +218 -0
- package/scripts/gist-receipts.mjs +168 -38
- package/scripts/ingest-gists.mjs +5 -2
- package/scripts/installed-brain-health.mjs +99 -0
- package/scripts/onboarding-console.mjs +45 -1
- package/scripts/public-inputs.mjs +2 -1
- package/scripts/public-verification-inputs.mjs +14 -6
- package/scripts/refresh-capability-only-store.mjs +143 -0
- package/scripts/release-transaction-provider.mjs +25 -5
- package/scripts/release-transaction.mjs +40 -11
- package/scripts/release-vector.mjs +44 -20
- package/scripts/run-operational-benchmark.mjs +151 -0
- package/scripts/run-operational-benchmark.v3.mjs +194 -0
- package/scripts/self-update.mjs +2 -0
- package/scripts/source-coverage.mjs +6 -1
- package/scripts/sync-version.mjs +10 -2
- package/scripts/wired-check.mjs +73 -45
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Created: 2026-06-29 22:36:38 EDT
|
|
|
7
7
|
|
|
8
8
|
# 🧠 RuvNet Brain
|
|
9
9
|
|
|
10
|
-
### 🧠 RuvNet Brain — [](https://github.com/stuinfla/ruvnet-brain/blob/main/plugin/.claude-plugin/plugin.json)
|
|
11
11
|
|
|
12
12
|
**A portable, source-grounded brain over Reuven Cohen's (rUv's) RuvNet stack — delivered as a Claude Code plugin that makes Claude _use_ the stack instead of fighting it.**
|
|
13
13
|
|
|
@@ -562,7 +562,7 @@ node forge-ask-all.mjs --dir . --q "How does RuVector implement HNSW vector sear
|
|
|
562
562
|
|
|
563
563
|
This project versions in the open (see the live badge up top for the exact plugin version; the downloadable knowledge bundle is a separate track) — we don't claim “done,” “complete,” or “zero hallucinations.” Where it stands:
|
|
564
564
|
|
|
565
|
-
- ✅ **The grounding brain is real and proven** — 182 public stores · 143,
|
|
565
|
+
- ✅ **The grounding brain is real and proven** — 182 public stores · 143,682 public source chunks, dual embeddings, cross-encoder rerank, plugin (MCP tool + explicit skills; automatic hooks retired), all re-runnable.
|
|
566
566
|
- ✅ **Code-level depth** — the code-rich repos are indexed to full function bodies; “how is it implemented?” returns the implementation. Verified in the shipped bundle (clean-room 3/3).
|
|
567
567
|
- ✅ **Routing holds** — named 47/48, described 26/28, scenario 7/8; behavioral L1–L3 all pass (**L4 downgraded — it measures that the brain spoke, not that anything listened**); private stores fenced out of the public bundle (zero-leak verified).
|
|
568
568
|
- ⚠️ **Two routing residuals** (above) — surfaced, not hidden.
|
package/bin/install.mjs
CHANGED
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
} from '../kb/model-requirements.mjs';
|
|
31
31
|
import { applyManagedCatalogUpdate } from '../scripts/model-router-catalog.mjs';
|
|
32
32
|
import { cmpVersion } from '../scripts/stack-sync.mjs';
|
|
33
|
+
import { inspectInstalledBrain, classifySmokeEvidence, DOCTOR_SMOKE_QUERY, doctorSmokeArgs } from '../scripts/installed-brain-health.mjs';
|
|
33
34
|
import { validateCoverageDirectory } from '../plugin/scripts/coverage-integrity.mjs';
|
|
34
35
|
import {
|
|
35
36
|
continuityContractIds,
|
|
@@ -2402,9 +2403,9 @@ async function smokeQuery(cacheDir) {
|
|
|
2402
2403
|
if (!fs.existsSync(ask)) return { ran: false };
|
|
2403
2404
|
step(
|
|
2404
2405
|
'Asking the brain a real question',
|
|
2405
|
-
'this warms the local model
|
|
2406
|
+
'this warms the local model and checks that retrieval returns usable, cited evidence',
|
|
2406
2407
|
);
|
|
2407
|
-
const Q =
|
|
2408
|
+
const Q = DOCTOR_SMOKE_QUERY;
|
|
2408
2409
|
info(`Q: ${c.cyan(`"${Q}"`)}`);
|
|
2409
2410
|
info(c.dim('(first run downloads a small local model once — this can take a minute)'));
|
|
2410
2411
|
const started = Date.now();
|
|
@@ -2415,7 +2416,7 @@ async function smokeQuery(cacheDir) {
|
|
|
2415
2416
|
// absolute path via spawnSync (no shell involved) that identity check silently fails on this
|
|
2416
2417
|
// machine, so main() never runs — exit 0, zero stdout, zero stderr, no exception. Looks like a
|
|
2417
2418
|
// clean success; is actually a total no-op. Verified: switching to a relative name + cwd fixes it.
|
|
2418
|
-
r = spawnSync('node',
|
|
2419
|
+
r = spawnSync('node', doctorSmokeArgs(cacheDir), {
|
|
2419
2420
|
cwd: cacheDir,
|
|
2420
2421
|
encoding: 'utf8',
|
|
2421
2422
|
timeout: 240000,
|
|
@@ -2476,6 +2477,11 @@ async function smokeQuery(cacheDir) {
|
|
|
2476
2477
|
}
|
|
2477
2478
|
|
|
2478
2479
|
const v = await verifier.verifyGrounding(out, cacheDir);
|
|
2480
|
+
const evidence = classifySmokeEvidence(v, out);
|
|
2481
|
+
if (v.grounded && !evidence.usable) {
|
|
2482
|
+
warn(`the citation resolves, but the question was not answered with sufficient evidence (${evidence.reason})`);
|
|
2483
|
+
return { ran: true, grounded: false, citationResolved: true, reason: evidence.reason, secs };
|
|
2484
|
+
}
|
|
2479
2485
|
if (v.grounded) {
|
|
2480
2486
|
ok(`grounded in rUv's real source — verified in ${secs}s, not guessed ✦`);
|
|
2481
2487
|
console.log(` ${c.dim('cited:')} ${c.bold(v.receipt.path)}`);
|
|
@@ -2693,6 +2699,13 @@ async function doctor() {
|
|
|
2693
2699
|
// Two independent version streams (KB bundle vs plugin wrapper) — see checkVersionDrift()'s
|
|
2694
2700
|
// header comment for the full story. Silent unless they've genuinely diverged.
|
|
2695
2701
|
reportVersionDrift(cacheDir);
|
|
2702
|
+
const installedIdentity = inspectInstalledBrain(cacheDir, PACKAGE_VERSION);
|
|
2703
|
+
info(`installed identities: package ${installedIdentity.packageVersion || 'unknown'}; search engine ${installedIdentity.searchVersion || 'unknown'}; validator ${installedIdentity.validatorVersion || 'unknown'}`);
|
|
2704
|
+
if (installedIdentity.corpusTag) info(`corpus generation: ${installedIdentity.corpusTag}`);
|
|
2705
|
+
if (!installedIdentity.healthy) {
|
|
2706
|
+
for (const issue of installedIdentity.issues) warn(`installed identity: ${issue}`);
|
|
2707
|
+
info(`Repair the installed generation: ${c.bold('npx ruvnet-brain@latest --update')}`);
|
|
2708
|
+
}
|
|
2696
2709
|
// Extraction no longer needs an external binary at all — kb/zip-extract.mjs does it with node:zlib
|
|
2697
2710
|
// (see unzipInto()). So this reports the file's PRESENCE, not a PATH lookup: if it is missing from
|
|
2698
2711
|
// the install, extraction on Windows silently loses its primary method, which is exactly the class
|
|
@@ -2883,6 +2896,8 @@ async function doctor() {
|
|
|
2883
2896
|
const codexWiringFailed = Boolean(cx.host && !cx.wired);
|
|
2884
2897
|
const codexReadinessFailed = Boolean(codexMcp?.blocking);
|
|
2885
2898
|
const failed = (hookResult ? hookResult.exitCode !== 0 : !allGreen)
|
|
2899
|
+
|| !installedIdentity.healthy
|
|
2900
|
+
|| smoke.grounded !== true
|
|
2886
2901
|
|| groundingUnprovenPersisted
|
|
2887
2902
|
|| (codexLifecycleFailed && !codexTrustBypassed)
|
|
2888
2903
|
|| codexWiringFailed
|
|
@@ -3056,7 +3071,7 @@ function reportVersionDrift(cacheDir) {
|
|
|
3056
3071
|
const state = checkVersionDrift(cacheDir);
|
|
3057
3072
|
if (!state.drift) return state;
|
|
3058
3073
|
warn(`the brain (${c.bold(state.kb)}) and the Claude Code plugin (${c.bold(state.wrapper)}) have drifted apart —`);
|
|
3059
|
-
info(`
|
|
3074
|
+
info(`they update on separate schedules; this comparison does not prove either is healthy. To bring the`);
|
|
3060
3075
|
info(`plugin up to date: ${c.bold('claude plugin marketplace update ruvnet-brain')} ${c.dim('(body updates go live without a restart; boot-surface changes are called out)')}`);
|
|
3061
3076
|
return state;
|
|
3062
3077
|
}
|
package/console/app.js
CHANGED
|
@@ -2973,6 +2973,53 @@ function bpField(bp) {
|
|
|
2973
2973
|
return (bp && Array.isArray(bp.schema) && bp.schema[0]) || null;
|
|
2974
2974
|
}
|
|
2975
2975
|
|
|
2976
|
+
/* ------------------------------------------------------------ inventory */
|
|
2977
|
+
|
|
2978
|
+
// Renders /api/state's `inventory` section: the installed brain's stores BY NAME, joined with their
|
|
2979
|
+
// upstream repo and build commit. Ranked by recency (server-side) — never alphabetical. Read-only.
|
|
2980
|
+
function renderInventory(inv) {
|
|
2981
|
+
const body = $('#body-inventory');
|
|
2982
|
+
if (!body) return;
|
|
2983
|
+
if (!inv || inv.available !== true) {
|
|
2984
|
+
setChips('chips-inventory', [chip('can’t read the manifest', 'nt')]);
|
|
2985
|
+
body.replaceChildren(el('p', { class: 'muted' },
|
|
2986
|
+
inv && inv.reason ? inv.reason : 'The console could not read RVF-GENERATIONS.json from the installed brain, so it is not guessing a list.'));
|
|
2987
|
+
return;
|
|
2988
|
+
}
|
|
2989
|
+
const chips = [chip(`${fmtInt(inv.count)} repositories`, 'green')];
|
|
2990
|
+
if (inv.privateCount > 0) chips.push(chip(`${fmtInt(inv.privateCount)} private`, 'cyan', 'Fenced private stores — never leave this machine'));
|
|
2991
|
+
if (inv.releaseTag) chips.push(chip(`generation ${inv.releaseTag}`, 'grey'));
|
|
2992
|
+
setChips('chips-inventory', chips);
|
|
2993
|
+
|
|
2994
|
+
const mb = inv.totalBytes ? `${(inv.totalBytes / 1e6).toFixed(0)} MB on disk` : null;
|
|
2995
|
+
const summary = el('p', { class: 'muted' },
|
|
2996
|
+
`${fmtInt(inv.count)} searchable stores`,
|
|
2997
|
+
inv.withProvenance != null ? `, ${fmtInt(inv.withProvenance)} with a recorded upstream commit` : '',
|
|
2998
|
+
mb ? `, ${mb}.` : '.');
|
|
2999
|
+
|
|
3000
|
+
const rows = (inv.stores || []).map((s) => el('li', { class: 'inv-row', 'data-name': s.name.toLowerCase() },
|
|
3001
|
+
el('span', { class: 'mono inv-name' }, s.name),
|
|
3002
|
+
s.private ? chip('private', 'cyan') : null,
|
|
3003
|
+
s.sourceRepo && /^https?:\/\//.test(s.sourceRepo)
|
|
3004
|
+
? el('a', { class: 'inv-src', href: s.sourceRepo, target: '_blank', rel: 'noopener noreferrer' }, s.sourceRepo.replace(/^https?:\/\/(www\.)?github\.com\//, ''))
|
|
3005
|
+
: el('span', { class: 'muted inv-src' }, s.sourceRepo || '—'),
|
|
3006
|
+
el('span', { class: 'mono muted inv-meta' },
|
|
3007
|
+
s.sourceCommit ? `@${s.sourceCommit}` : '', s.builtUtc ? ` · built ${String(s.builtUtc).slice(0, 10)}` : ''),
|
|
3008
|
+
));
|
|
3009
|
+
const list = el('ul', { class: 'inv-list', 'aria-label': 'Repositories in the brain' }, ...rows);
|
|
3010
|
+
const filter = el('input', {
|
|
3011
|
+
class: 'inv-filter', type: 'search', placeholder: 'Filter by name…', 'aria-label': 'Filter repositories by name',
|
|
3012
|
+
oninput: (e) => {
|
|
3013
|
+
const q = String(e.target.value || '').trim().toLowerCase();
|
|
3014
|
+
let shown = 0;
|
|
3015
|
+
for (const li of list.children) { const hit = !q || li.dataset.name.includes(q); li.hidden = !hit; if (hit) shown += 1; }
|
|
3016
|
+
count.textContent = q ? `${fmtInt(shown)} of ${fmtInt(inv.count)} match` : '';
|
|
3017
|
+
},
|
|
3018
|
+
});
|
|
3019
|
+
const count = el('span', { class: 'muted inv-count', 'aria-live': 'polite' });
|
|
3020
|
+
body.replaceChildren(summary, el('div', { class: 'inv-tools' }, filter, count), list);
|
|
3021
|
+
}
|
|
3022
|
+
|
|
2976
3023
|
function renderBrainPower(bp) {
|
|
2977
3024
|
const body = $('#body-brain');
|
|
2978
3025
|
if (!body) return;
|
|
@@ -3663,6 +3710,7 @@ async function loadState({ landed = false } = {}) {
|
|
|
3663
3710
|
renderHost(state.host, state.generatedAt);
|
|
3664
3711
|
const s = state.sections || {};
|
|
3665
3712
|
renderBrainPower(s.brainPower);
|
|
3713
|
+
renderInventory(s.inventory);
|
|
3666
3714
|
renderWiring(s.wiring);
|
|
3667
3715
|
lastMemory = s.memory;
|
|
3668
3716
|
renderMemory(s.memory);
|
package/console/index.html
CHANGED
|
@@ -108,6 +108,25 @@
|
|
|
108
108
|
</div>
|
|
109
109
|
</section>
|
|
110
110
|
|
|
111
|
+
<!-- The one thing this page never showed: WHICH repositories are in the brain, by name. It always
|
|
112
|
+
carried the count and never the list. Read-only mirror of the installed manifest. -->
|
|
113
|
+
<section class="card rail-mirror" id="card-inventory" aria-labelledby="card-inventory-h">
|
|
114
|
+
<div class="qgroup-head">
|
|
115
|
+
<span class="card-ic ic-mirror" aria-hidden="true">
|
|
116
|
+
<svg viewBox="0 0 24 24"><path d="M4 6h16"/><path d="M4 12h16"/><path d="M4 18h10"/></svg>
|
|
117
|
+
</span>
|
|
118
|
+
<span class="card-head">
|
|
119
|
+
<span class="stage st-mirror">Mirror</span>
|
|
120
|
+
<h2 id="card-inventory-h">What’s in your brain</h2>
|
|
121
|
+
<span class="q">Every repository the brain can search right now, by name — where it came from and when it was built.</span>
|
|
122
|
+
</span>
|
|
123
|
+
<span class="chips" id="chips-inventory"><span class="chip tone-wait">counting…</span></span>
|
|
124
|
+
</div>
|
|
125
|
+
<div class="body" id="body-inventory">
|
|
126
|
+
<div class="skeleton" aria-hidden="true"><div class="sk-bar w40"></div><div class="sk-bar w75"></div></div>
|
|
127
|
+
</div>
|
|
128
|
+
</section>
|
|
129
|
+
|
|
111
130
|
<!-- ======================================================= HERO -->
|
|
112
131
|
<section class="intro">
|
|
113
132
|
<div class="intro-grid">
|
package/console/style.css
CHANGED
|
@@ -2147,3 +2147,29 @@ details.sub .sub-body > *:first-child { margin-top: 4px; }
|
|
|
2147
2147
|
#body-brain .fn-path {
|
|
2148
2148
|
font-family: var(--mono); font-size: 0.86em; color: var(--faint); overflow-wrap: anywhere;
|
|
2149
2149
|
}
|
|
2150
|
+
|
|
2151
|
+
/* ------------------------------------------------------------ inventory card
|
|
2152
|
+
The repository list, by name. Same row language as .cap-row (hairline separators, quiet meta),
|
|
2153
|
+
with a type-to-filter above it because 200+ names need a way in. Long upstream URLs wrap rather
|
|
2154
|
+
than overflow the card. */
|
|
2155
|
+
.inv-tools { display: flex; align-items: center; gap: 12px; margin: 10px 0 8px; flex-wrap: wrap; }
|
|
2156
|
+
.inv-filter {
|
|
2157
|
+
flex: 1 1 220px; min-width: 0; padding: 7px 10px; font: inherit; font-size: 13.5px;
|
|
2158
|
+
color: var(--ink); background: var(--panel-2, transparent);
|
|
2159
|
+
border: 1px solid var(--hair-strong); border-radius: 8px;
|
|
2160
|
+
}
|
|
2161
|
+
.inv-filter:focus { outline: 2px solid var(--cyan); outline-offset: 1px; }
|
|
2162
|
+
.inv-count { font-size: 12.5px; }
|
|
2163
|
+
.inv-list { list-style: none; margin: 0; padding: 0; max-height: 28rem; overflow: auto; border-top: 1px solid var(--hair); }
|
|
2164
|
+
.inv-row {
|
|
2165
|
+
display: grid; grid-template-columns: minmax(10ch, 16ch) auto 1fr auto; align-items: baseline; gap: 6px 12px;
|
|
2166
|
+
padding: 7px 4px; border-bottom: 1px solid var(--hair); font-size: 13.5px;
|
|
2167
|
+
}
|
|
2168
|
+
.inv-row[hidden] { display: none; }
|
|
2169
|
+
.inv-name { font-size: 13px; overflow-wrap: anywhere; }
|
|
2170
|
+
.inv-src { min-width: 0; overflow-wrap: anywhere; font-size: 12.5px; }
|
|
2171
|
+
.inv-meta { font-size: 12px; white-space: nowrap; }
|
|
2172
|
+
@media (max-width: 640px) {
|
|
2173
|
+
.inv-row { grid-template-columns: 1fr auto; }
|
|
2174
|
+
.inv-src, .inv-meta { grid-column: 1 / -1; white-space: normal; }
|
|
2175
|
+
}
|
package/data/model-catalog.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"generated": "2026-07-15",
|
|
5
5
|
"schema_version": 1,
|
|
6
6
|
"sources": {
|
|
7
|
-
"prices": "OpenRouter /api/v1/models live catalog, pulled 2026-09-
|
|
7
|
+
"prices": "OpenRouter /api/v1/models live catalog, pulled 2026-09-19 (in/out USD per Mtok).",
|
|
8
8
|
"rankings": "Artificial Analysis Intelligence Index (artificialanalysis.ai) + Arena/LMArena (arena.ai) — the ONLY independent evaluators carrying current-generation models as of 2026-07-15; each figure cross-verified twice.",
|
|
9
9
|
"provenance_rule": "rUv ADR-206: vendor-reported scores are optimistic and harness-confounded — trust independent (AA/Arena) numbers, treat vendor self-scaffold SWE-bench/LiveCodeBench figures as noisy features, never as truth.",
|
|
10
10
|
"benchmark_lag": "The canonical hard coding benchmarks (SWE-bench Verified standardized harness, LiveCodeBench, Aider polyglot) were ALL months stale on 2026-07-15 and carry NONE of these models. The '88.6% / 95% SWE-bench' figures in the press are vendor self-scaffold scores, not the standardized harness — excluded here.",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# RuvNet-Brain 4.0 line — what's new (the major-release highlights)
|
|
2
2
|
|
|
3
|
-
Updated: 2026-
|
|
3
|
+
Updated: 2026-09-20
|
|
4
4
|
|
|
5
5
|
> **Source of truth** for the `/whats-new` command and the first-run upgrade message. Curated, honest,
|
|
6
6
|
> major-only — not the point-release churn. If a claim here isn't true of the shipping build, it does not
|
|
@@ -19,10 +19,11 @@ it's landing now.
|
|
|
19
19
|
|
|
20
20
|
### Release proof is fail-closed
|
|
21
21
|
The 4.0 release path now separates a clean candidate seal from a post-publication seal. Dirty
|
|
22
|
-
lineage, zero/skipped/todo tests, open issues, red or pending exact-SHA workflows, a missing
|
|
22
|
+
lineage, zero/skipped/todo tests, open `release-blocker` issues, red or pending exact-SHA workflows, a missing
|
|
23
23
|
`ruvnet-brain` self-RVF store, weak query-deadline margin, missing independent graders,
|
|
24
24
|
host/artifact mismatches, and public-byte drift are release failures rather than warnings.
|
|
25
|
-
|
|
25
|
+
The local `release:proof --status --quick` command is only a diagnostic and cannot qualify a
|
|
26
|
+
candidate; use the exact-SHA preflight receipt and protected publisher evidence.
|
|
26
27
|
|
|
27
28
|
### 1. The Console is the front door
|
|
28
29
|
Type `/rvbc` and your whole RuvNet stack is on one live local page: what's installed, what the AI has
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
export const isCapabilityOnly = name => String(name).toLowerCase() === 'cognitum-ruos';
|
|
5
|
+
export const CAPABILITY_RETIRED_SUFFIXES = [
|
|
6
|
+
'-primer.md', '.symbols.json', '.rvf', '.rvf.idmap.json', '.rvf.embed.json', '.big.passages.jsonl', '.big.meta.json',
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
// Reject historical source-bearing stores at the final packaging boundary, even
|
|
10
|
+
// when their upstream SHA and signed generation receipt are otherwise current.
|
|
11
|
+
export function assertCapabilityOnlyStore(dir, name) {
|
|
12
|
+
if (!isCapabilityOnly(name)) return;
|
|
13
|
+
const expected = fs.readFileSync(new URL('./capability-summaries/cognitum-ruos/CAPABILITIES.md', import.meta.url), 'utf8');
|
|
14
|
+
const rows = fs.readFileSync(path.join(dir, `${name}.passages.jsonl`), 'utf8')
|
|
15
|
+
.trim().split('\n').map(line => JSON.parse(line));
|
|
16
|
+
if (rows.length !== 1 || rows[0].path !== 'CAPABILITIES.md' || rows[0].text !== expected) {
|
|
17
|
+
throw new Error(`${name}: capability-only policy requires the current curated summary, without source passages`);
|
|
18
|
+
}
|
|
19
|
+
const meta = JSON.parse(fs.readFileSync(path.join(dir, `${name}.meta.json`), 'utf8'));
|
|
20
|
+
const entries = Object.values(meta.entries || {});
|
|
21
|
+
if (entries.length !== 1 || entries[0].path !== 'CAPABILITIES.md' || entries[0].kind !== 'doc') {
|
|
22
|
+
throw new Error(`${name}: capability-only metadata contains unexpected source paths`);
|
|
23
|
+
}
|
|
24
|
+
if (CAPABILITY_RETIRED_SUFFIXES.some(suffix => fs.existsSync(path.join(dir, `${name}${suffix}`)))) {
|
|
25
|
+
throw new Error(`${name}: capability-only store must not carry a symbol index or legacy source sidecar`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Updated: 2026-09-19 | Version 1.0.0
|
|
2
|
+
Created: 2026-09-19
|
|
3
|
+
|
|
4
|
+
# Cognitum ruOS capabilities
|
|
5
|
+
|
|
6
|
+
Cognitum ruOS is an agentic operating system for AI workstations. It is designed
|
|
7
|
+
to observe workstation conditions, reason about what needs attention, and take
|
|
8
|
+
appropriate actions with less manual intervention.
|
|
9
|
+
|
|
10
|
+
Its documented capabilities include:
|
|
11
|
+
|
|
12
|
+
- Workstation health monitoring and recovery from service failures.
|
|
13
|
+
- Adapting performance profiles to workload and user context.
|
|
14
|
+
- Local AI assistance and persistent knowledge for workstation tasks.
|
|
15
|
+
- Learning from prior sessions and evaluating knowledge quality.
|
|
16
|
+
- Backup, recovery, and software updates.
|
|
17
|
+
- Voice interaction and optional sensing with user consent.
|
|
18
|
+
- Security checks around AI interactions.
|
|
19
|
+
|
|
20
|
+
It is relevant when a user wants a workstation that helps maintain itself and
|
|
21
|
+
supports ongoing AI-assisted work. These are documented capabilities, not a claim
|
|
22
|
+
that ruOS is installed, provisioned, or independently benchmarked on this machine.
|
|
23
|
+
|
|
24
|
+
This Brain entry intentionally covers capabilities and use cases only. Proprietary
|
|
25
|
+
source code, internal architecture, algorithms, configuration, and implementation
|
|
26
|
+
instructions are outside its published knowledge scope.
|
package/kb/verify-citation.mjs
CHANGED
|
@@ -42,7 +42,7 @@ import readline from 'node:readline';
|
|
|
42
42
|
export function parseCitations(stdout) {
|
|
43
43
|
const out = [];
|
|
44
44
|
const text = String(stdout ?? '');
|
|
45
|
-
const blockRe = /^#(\d+)\
|
|
45
|
+
const blockRe = /^#(\d+)[ \t]+repo=(\S+)([^\r\n]*)/gm;
|
|
46
46
|
const nextHeaderRe = /^#\d+\s+repo=\S+/gm;
|
|
47
47
|
let m;
|
|
48
48
|
let expectedRank = 1;
|
|
@@ -63,15 +63,27 @@ export function parseCitations(stdout) {
|
|
|
63
63
|
if (!pathM) continue;
|
|
64
64
|
expectedRank = rank + 1;
|
|
65
65
|
const repo = m[2];
|
|
66
|
+
// Metadata comes only from the header, never from a retrieved document body.
|
|
67
|
+
// A proof label is descriptive; consumers must independently validate its evidence.
|
|
68
|
+
const field = (name) => new RegExp(`(?:^|[ \\t])${name}=([^ \\t]+)`).exec(m[3])?.[1] ?? null;
|
|
69
|
+
const score = (name) => {
|
|
70
|
+
const value = field(name);
|
|
71
|
+
return value !== null && /^-?\d+(?:\.\d+)?$/.test(value) ? Number(value) : null;
|
|
72
|
+
};
|
|
66
73
|
const fullPath = pathM[1].trim();
|
|
67
74
|
// Strip the repo prefix the reader adds, so the remainder can be matched against the store.
|
|
68
75
|
const docPath = fullPath.startsWith(`${repo}/`) ? fullPath.slice(repo.length + 1) : fullPath;
|
|
76
|
+
// Retain only the reader's bounded document body. Missing/truncated delimiters fail
|
|
77
|
+
// closed, so evaluators cannot borrow claims from headers, diagnostics, or later hits.
|
|
78
|
+
const body = /^----- full document -----\r?\n([\s\S]*?)\r?\n={67}(?:\r?\n|$)/m.exec(block);
|
|
69
79
|
out.push({
|
|
70
80
|
rank,
|
|
71
81
|
repo,
|
|
72
|
-
ce:
|
|
73
|
-
vec:
|
|
74
|
-
kind:
|
|
82
|
+
ce: score('ce'),
|
|
83
|
+
vec: score('vec'),
|
|
84
|
+
kind: field('kind'),
|
|
85
|
+
proofMethod: field('proof'),
|
|
86
|
+
returnedText: body ? body[1] : null,
|
|
75
87
|
fullPath,
|
|
76
88
|
docPath,
|
|
77
89
|
title: titleM ? titleM[1].trim() : null,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ruvnet-brain",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.27",
|
|
4
4
|
"description": "One-command installer for RuvNet Brain — a portable, source-grounded brain over rUv's RuvNet building blocks, delivered as a Claude Code plugin so Claude uses the stack instead of fighting it.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
"release:proof": "node scripts/release-proof.mjs",
|
|
13
13
|
"benchmark:brain50": "node scripts/brain-latency-50.mjs",
|
|
14
14
|
"benchmark:novice50": "node scripts/brain-novice-50.mjs",
|
|
15
|
+
"benchmark:operational": "node scripts/run-operational-benchmark.v3.mjs",
|
|
16
|
+
"benchmark:operational:v2": "node scripts/run-operational-benchmark.mjs",
|
|
15
17
|
"version:check": "node scripts/sync-version.mjs --check",
|
|
16
18
|
"version:set": "node scripts/set-version.mjs",
|
|
17
19
|
"qa:pr": "node scripts/qa-runner.mjs",
|
|
@@ -94,6 +96,8 @@
|
|
|
94
96
|
"kb/verify-citation.mjs",
|
|
95
97
|
"kb/retrieval-result.mjs",
|
|
96
98
|
"kb/corpus-release-identity.mjs",
|
|
99
|
+
"kb/capability-only.mjs",
|
|
100
|
+
"kb/capability-summaries/",
|
|
97
101
|
"kb/zip-extract.mjs",
|
|
98
102
|
"kb/brain-profile.mjs",
|
|
99
103
|
"kb/lifecycle-evidence-retention.mjs",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ruvnet-brain",
|
|
3
3
|
"description": "RuvNet brain transplant for Claude Code — grounds every RuvNet decision in real source across 77 rUv repositories, prefers Ruflo / RuVector-RVF / AgentDB over training-prior defaults (pgvector, Pinecone, hand-rolled cosine), and can pull in any RuvNet repo on demand. Ships a UserPromptSubmit retrieve-and-inject grounding hook and a PreToolUse write gate that refuses ungrounded rUv-product code until search_ruvnet has been consulted (ADR-0012 / ADR-067).",
|
|
4
|
-
"version": "4.3.
|
|
4
|
+
"version": "4.3.27",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Stuart Kerr"
|
|
7
7
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# RuvNet-Brain 4.0 line — what's new (the major-release highlights)
|
|
2
2
|
|
|
3
|
-
Updated: 2026-
|
|
3
|
+
Updated: 2026-09-20
|
|
4
4
|
|
|
5
5
|
> **Source of truth** for the `/whats-new` command and the first-run upgrade message. Curated, honest,
|
|
6
6
|
> major-only — not the point-release churn. If a claim here isn't true of the shipping build, it does not
|
|
@@ -19,10 +19,11 @@ it's landing now.
|
|
|
19
19
|
|
|
20
20
|
### Release proof is fail-closed
|
|
21
21
|
The 4.0 release path now separates a clean candidate seal from a post-publication seal. Dirty
|
|
22
|
-
lineage, zero/skipped/todo tests, open issues, red or pending exact-SHA workflows, a missing
|
|
22
|
+
lineage, zero/skipped/todo tests, open `release-blocker` issues, red or pending exact-SHA workflows, a missing
|
|
23
23
|
`ruvnet-brain` self-RVF store, weak query-deadline margin, missing independent graders,
|
|
24
24
|
host/artifact mismatches, and public-byte drift are release failures rather than warnings.
|
|
25
|
-
|
|
25
|
+
The local `release:proof --status --quick` command is only a diagnostic and cannot qualify a
|
|
26
|
+
candidate; use the exact-SHA preflight receipt and protected publisher evidence.
|
|
26
27
|
|
|
27
28
|
### 1. The Console is the front door
|
|
28
29
|
Type `/rvbc` and your whole RuvNet stack is on one live local page: what's installed, what the AI has
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "RuvNet Brain continuity plane for Codex. Broad legacy automatic gates remain retired. Registrations here are MEASURED, not assumed: a probe hook was registered on all twelve event names the installed codex-cli 0.154.0 binary declares and a real `codex exec` run was observed (2026-09-11). SessionStart, UserPromptSubmit and SessionEnd FIRED and carry handlers. Stop keeps only the pre-existing, project-scoped continuation gate. PreCompact is DECLARED ABSENT here: the binary declares the event but the probe never observed it, and a capture registered on an unobserved event would look symmetrical while capturing nothing. All handlers are bounded and fail open. Amended 2026-09-11: UserPromptSubmit also runs ground-ruvnet (grounding injection, ADR-040 §Amendment). Amended 2026-09-12: the 2026-09-11 PreToolUse/PostToolUse \"not observed\" note was measured with a prompt (`codex exec \"reply OK\"`) that never invoked a tool, so neither event had anything to fire on — that was an untested path, not a failing one. Re-probed with prompts that actually call a tool: a real apply_patch write fired PreToolUse/PostToolUse with tool_name \"apply_patch\", and a real MCP call to this repo's own search_ruvnet server fired both with tool_name \"mcp__ruvnet_brain__search_ruvnet\". Both are now registered below: decision-gate's write route (matcher includes apply_patch, Codex's raw write-tool name) and grounding-stamp (unchanged matcher already recognizes the mcp__..__search_ruvnet shape). The bash route (exec_command) remains unregistered — today's measurement covered a write and an MCP call, not exec_command, and extending on that evidence would be the same unproven leap this note replaces. Also added 2026-09-12: grounding-turn-mark (UserPromptSubmit) and grounding-turn-gate (Stop), the \"answered without searching\" pair — a prompt-level grounding directive is advisory, so this records whether it fired and forces continuation at Stop if no search_ruvnet call was recorded since (reusing grounding-stamp's own stamp evidence). Both are registered on Codex identically to Claude: the Stop-block contract (hookSpecificOutput.additionalContext) already has a proven Codex translation via codex-hook-adapter.mjs's Stop branch (see tests/unit/codex-lifecycle-hooks.test.mjs), the same path continuation-gate already uses.",
|
|
2
|
+
"description": "RuvNet Brain continuity plane for Codex. Broad legacy automatic gates remain retired. Registrations here are MEASURED, not assumed: a probe hook was registered on all twelve event names the installed codex-cli 0.154.0 binary declares and a real `codex exec` run was observed (2026-09-11). SessionStart, UserPromptSubmit and SessionEnd FIRED and carry handlers. Stop keeps only the pre-existing, project-scoped continuation gate. PreCompact is DECLARED ABSENT here: the binary declares the event but the probe never observed it, and a capture registered on an unobserved event would look symmetrical while capturing nothing. All handlers are bounded and fail open. Amended 2026-09-11: UserPromptSubmit also runs ground-ruvnet (grounding injection, ADR-040 §Amendment). Amended 2026-09-12: the 2026-09-11 PreToolUse/PostToolUse \"not observed\" note was measured with a prompt (`codex exec \"reply OK\"`) that never invoked a tool, so neither event had anything to fire on — that was an untested path, not a failing one. Re-probed with prompts that actually call a tool: a real apply_patch write fired PreToolUse/PostToolUse with tool_name \"apply_patch\", and a real MCP call to this repo's own search_ruvnet server fired both with tool_name \"mcp__ruvnet_brain__search_ruvnet\". Both are now registered below: decision-gate's write route (matcher includes apply_patch, Codex's raw write-tool name) and grounding-stamp (unchanged matcher already recognizes the mcp__..__search_ruvnet shape). The bash route (exec_command) remains unregistered — today's measurement covered a write and an MCP call, not exec_command, and extending on that evidence would be the same unproven leap this note replaces. Also added 2026-09-12: grounding-turn-mark (UserPromptSubmit) and grounding-turn-gate (Stop), the \"answered without searching\" pair — a prompt-level grounding directive is advisory, so this records whether it fired and forces continuation at Stop if no search_ruvnet call was recorded since (reusing grounding-stamp's own stamp evidence). Both are registered on Codex identically to Claude: the Stop-block contract (hookSpecificOutput.additionalContext) already has a proven Codex translation via codex-hook-adapter.mjs's Stop branch (see tests/unit/codex-lifecycle-hooks.test.mjs), the same path continuation-gate already uses. Capacity-aware parallel-work guidance is also registered at UserPromptSubmit: it advises the coordinator to launch only real independent workers within sampled resource headroom and the live runtime/tool cap; it never spawns workers or claims execution.",
|
|
3
3
|
"hooks": {
|
|
4
4
|
"SessionStart": [
|
|
5
5
|
{
|
|
@@ -68,6 +68,11 @@
|
|
|
68
68
|
"command": "node -e \"const f=require('node:fs'),o=require('node:os'),p=require('node:path'),c=require('node:child_process'),d=process.env.CODEX_HOME||p.join(o.homedir(),'.codex'),b=process.env.RUVNET_BRAIN_HOME||p.join(p.dirname(d),'.cache','ruvnet-brain'),w=p.join(b,'codex-hook.mjs');let s;try{s=f.statSync(w)}catch{}if(!s?.isFile())process.exit(0);const r=c.spawnSync(process.execPath,[w,...process.argv.slice(2)],{stdio:['inherit','pipe','pipe'],encoding:'utf8',env:process.env,timeout:Number(process.argv[1]),killSignal:'SIGKILL'});if(r.status===0||r.status===2){if(r.stdout)process.stdout.write(r.stdout);if(r.stderr)process.stderr.write(r.stderr)}process.exit(r.status===2?2:0)\" 9000 ground-ruvnet",
|
|
69
69
|
"timeout": 10
|
|
70
70
|
},
|
|
71
|
+
{
|
|
72
|
+
"type": "command",
|
|
73
|
+
"command": "node -e \"const f=require('node:fs'),o=require('node:os'),p=require('node:path'),c=require('node:child_process'),d=process.env.CODEX_HOME||p.join(o.homedir(),'.codex'),b=process.env.RUVNET_BRAIN_HOME||p.join(p.dirname(d),'.cache','ruvnet-brain'),w=p.join(b,'codex-hook.mjs');let s;try{s=f.statSync(w)}catch{}if(!s?.isFile())process.exit(0);const r=c.spawnSync(process.execPath,[w,...process.argv.slice(2)],{stdio:['inherit','pipe','pipe'],encoding:'utf8',env:process.env,timeout:Number(process.argv[1]),killSignal:'SIGKILL'});if(r.status===0||r.status===2){if(r.stdout)process.stdout.write(r.stdout);if(r.stderr)process.stderr.write(r.stderr)}process.exit(r.status===2?2:0)\" 1500 capacity-aware-parallel-work",
|
|
74
|
+
"timeout": 2
|
|
75
|
+
},
|
|
71
76
|
{
|
|
72
77
|
"type": "command",
|
|
73
78
|
"command": "node -e \"const f=require('node:fs'),o=require('node:os'),p=require('node:path'),c=require('node:child_process'),d=process.env.CODEX_HOME||p.join(o.homedir(),'.codex'),b=process.env.RUVNET_BRAIN_HOME||p.join(p.dirname(d),'.cache','ruvnet-brain'),w=p.join(b,'codex-hook.mjs');let s;try{s=f.statSync(w)}catch{}if(!s?.isFile())process.exit(0);const r=c.spawnSync(process.execPath,[w,...process.argv.slice(2)],{stdio:['inherit','pipe','pipe'],encoding:'utf8',env:process.env,timeout:Number(process.argv[1]),killSignal:'SIGKILL'});if(r.status===0||r.status===2){if(r.stdout)process.stdout.write(r.stdout);if(r.stderr)process.stderr.write(r.stderr)}process.exit(r.status===2?2:0)\" 4500 grounding-turn-mark",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_note": "The legacy automatic gate collection remains retired. What is permitted is the continuity plane below and nothing else: SessionStart restores the canonical project checkpoint; UserPromptSubmit runs the single unprompted-speech chokepoint; Stop may nudge one explicitly authorized project-scoped objective AND capture a project snapshot; PreCompact and SessionEnd capture a project snapshot. Version 3 of this file permitted exactly two handlers, which was not a safety property but a contradiction: it demanded a restore while forbidding any event that could WRITE the journal the restore reads, so the canonical store held zero progression rows. Adding to this list is still a deliberate act that must pass `npm run hooks:check`; what changed is that the shape can now express the plane that actually works. Amended 2026-09-11 (Stuart): the continuity-only charter had retired the ONLY enforcement of ADR-0012 — never write rUv-product code the brain has not seen — and the failure it exists to prevent recurred the day it was measured absent. The plane now also carries three grounding registrations: ground-ruvnet (UserPromptSubmit, grounding injection — a second owner of that event, scoped by ADR-040 §Amendment 2026-09-11 to directives rather than speech), decision-gate’s write route (PreToolUse, the one refuser, ADR-067), and grounding-stamp (PostToolUse on a successful search_ruvnet, the receipt that opens the write gate). Amended 2026-09-12: the 2026-09-11 claim that Codex PreToolUse/PostToolUse delivery had never been observed was measured with a prompt that never invoked a tool (`codex exec \"reply OK\"`), so it was an untested path, not a failing one. Re-measured with prompts that actually call a tool (a real apply_patch write, a real MCP search_ruvnet call against this repo's own server): both events FIRED on codex-cli 0.154.0 with real payloads. decision-gate's write route and grounding-stamp are now dual-host (see _codexCapture and contracts below); the bash route (exec_command) remains Claude-only — today's measurement did not exercise it. Also amended 2026-09-12: added grounding-turn-mark (UserPromptSubmit) and grounding-turn-gate (Stop), the \"answered without searching\" pair — ground-ruvnet's Gate 1 directive is advisory, so nothing previously checked whether the model complied before the turn ended. grounding-turn-mark records that Gate 1 fired for a turn; grounding-turn-gate forces continuation at Stop if grounding-stamp's own evidence shows no search_ruvnet call happened since. Both dual-host from the start (the Stop-block contract is already proven on Codex via continuation-gate).",
|
|
3
|
-
"_version":
|
|
2
|
+
"_note": "The legacy automatic gate collection remains retired. What is permitted is the continuity plane below and nothing else: SessionStart restores the canonical project checkpoint; UserPromptSubmit runs the single unprompted-speech chokepoint; Stop may nudge one explicitly authorized project-scoped objective AND capture a project snapshot; PreCompact and SessionEnd capture a project snapshot. Version 3 of this file permitted exactly two handlers, which was not a safety property but a contradiction: it demanded a restore while forbidding any event that could WRITE the journal the restore reads, so the canonical store held zero progression rows. Adding to this list is still a deliberate act that must pass `npm run hooks:check`; what changed is that the shape can now express the plane that actually works. Amended 2026-09-11 (Stuart): the continuity-only charter had retired the ONLY enforcement of ADR-0012 — never write rUv-product code the brain has not seen — and the failure it exists to prevent recurred the day it was measured absent. The plane now also carries three grounding registrations: ground-ruvnet (UserPromptSubmit, grounding injection — a second owner of that event, scoped by ADR-040 §Amendment 2026-09-11 to directives rather than speech), decision-gate’s write route (PreToolUse, the one refuser, ADR-067), and grounding-stamp (PostToolUse on a successful search_ruvnet, the receipt that opens the write gate). Amended 2026-09-12: the 2026-09-11 claim that Codex PreToolUse/PostToolUse delivery had never been observed was measured with a prompt that never invoked a tool (`codex exec \"reply OK\"`), so it was an untested path, not a failing one. Re-measured with prompts that actually call a tool (a real apply_patch write, a real MCP search_ruvnet call against this repo's own server): both events FIRED on codex-cli 0.154.0 with real payloads. decision-gate's write route and grounding-stamp are now dual-host (see _codexCapture and contracts below); the bash route (exec_command) remains Claude-only — today's measurement did not exercise it. Also amended 2026-09-12: added grounding-turn-mark (UserPromptSubmit) and grounding-turn-gate (Stop), the \"answered without searching\" pair — ground-ruvnet's Gate 1 directive is advisory, so nothing previously checked whether the model complied before the turn ended. grounding-turn-mark records that Gate 1 fired for a turn; grounding-turn-gate forces continuation at Stop if grounding-stamp's own evidence shows no search_ruvnet call happened since. Both dual-host from the start (the Stop-block contract is already proven on Codex via continuation-gate). Added capacity-aware-parallel-work at UserPromptSubmit on both measured hosts: it is context-only, resource-bounded, and requires the coordinator to check actual tool/runtime slots; it does not spawn or claim workers.",
|
|
3
|
+
"_version": 8,
|
|
4
4
|
"_eventOwners": [
|
|
5
5
|
{
|
|
6
6
|
"event": "SessionStart",
|
|
@@ -70,6 +70,16 @@
|
|
|
70
70
|
],
|
|
71
71
|
"responsibility": "Injects a grounding directive into the model’s context when the prompt names the rUv stack, reaches for a classical default, or asks to build: call search_ruvnet before you assert. Not speech — emits no advocacy, promotion, lesson or alarm and reads no dial; silenced by the brain switch (ADR-054); scoped by ADR-040 §Amendment 2026-09-11."
|
|
72
72
|
},
|
|
73
|
+
{
|
|
74
|
+
"event": "UserPromptSubmit",
|
|
75
|
+
"owner": "capacity-aware-parallel-work",
|
|
76
|
+
"class": "capacity-aware coordination guidance",
|
|
77
|
+
"hosts": [
|
|
78
|
+
"claude",
|
|
79
|
+
"codex"
|
|
80
|
+
],
|
|
81
|
+
"responsibility": "For clearly substantial, independently splittable work, adds context-only guidance based on bounded memory-pressure, swap, compression, and normalized-load signals. It never creates workers, claims they are running, or overrides the coordinator’s live agent-tool/runtime cap; unknown capacity recommends serial execution."
|
|
82
|
+
},
|
|
73
83
|
{
|
|
74
84
|
"event": "PreToolUse",
|
|
75
85
|
"owner": "decision-gate",
|
|
@@ -228,6 +238,18 @@
|
|
|
228
238
|
"matcher": "*",
|
|
229
239
|
"timeout": 10
|
|
230
240
|
},
|
|
241
|
+
{
|
|
242
|
+
"id": "capacity-aware-parallel-work",
|
|
243
|
+
"event": "UserPromptSubmit",
|
|
244
|
+
"hosts": [
|
|
245
|
+
"claude",
|
|
246
|
+
"codex"
|
|
247
|
+
],
|
|
248
|
+
"mode": "advisory",
|
|
249
|
+
"offBehavior": "run",
|
|
250
|
+
"matcher": "*",
|
|
251
|
+
"timeout": 2
|
|
252
|
+
},
|
|
231
253
|
{
|
|
232
254
|
"id": "decision-gate",
|
|
233
255
|
"event": "PreToolUse",
|
package/plugin/hooks/hooks.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "RuvNet Brain lifecycle plane. The broad legacy routing, learning, and release interceptors remain retired. What is automatic is exactly: SessionStart restores the canonical project checkpoint; UserPromptSubmit runs the single unprompted-speech chokepoint
|
|
2
|
+
"description": "RuvNet Brain lifecycle plane. The broad legacy routing, learning, and release interceptors remain retired. What is automatic is exactly: SessionStart restores the canonical project checkpoint; UserPromptSubmit runs the single unprompted-speech chokepoint, ground-ruvnet grounding injection, and a capacity-aware context hint for clearly large independent work. The capacity hook uses bounded CPU/memory-pressure evidence, never starts agents, and tells the coordinator to check live tools and clamp to the runtime cap; it is not user-facing speech. ground-ruvnet remains a directive to the model, not speech — ADR-040 §Amendment 2026-09-11. PreToolUse runs decision-gate's write route, the ONE process that may refuse a Write/Edit/MultiEdit/NotebookEdit/apply_patch (ADR-067, composing ground-before-write per ADR-0012); PostToolUse on a successful search_ruvnet mints the grounding stamp that opens that gate. grounding-turn-mark (UserPromptSubmit) records that the grounding directive fired this turn, and grounding-turn-gate (Stop) forces continuation if no search_ruvnet call was recorded since. Stop also runs the ledger-scoped continuation handler and captures a project snapshot; PreCompact and SessionEnd capture a project snapshot. Every capture is bounded and fails open; only decision-gate may block on exit code, and it fails open on its own errors — the Stop stdout envelopes are advisory at the shim boundary but keep the agent working.",
|
|
3
3
|
"hooks": {
|
|
4
4
|
"SessionStart": [
|
|
5
5
|
{
|
|
@@ -27,6 +27,11 @@
|
|
|
27
27
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/hook-shim.mjs\" ground-ruvnet || true",
|
|
28
28
|
"timeout": 10
|
|
29
29
|
},
|
|
30
|
+
{
|
|
31
|
+
"type": "command",
|
|
32
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/hook-shim.mjs\" capacity-aware-parallel-work || true",
|
|
33
|
+
"timeout": 2
|
|
34
|
+
},
|
|
30
35
|
{
|
|
31
36
|
"type": "command",
|
|
32
37
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/hook-shim.mjs\" grounding-turn-mark || true",
|