ruvnet-brain 4.0.1 → 4.0.4
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/.claude-plugin/marketplace.json +1 -0
- package/README.md +4 -4
- package/bin/install.mjs +303 -24
- package/console/CONTRACT.md +172 -0
- package/console/activity.js +753 -0
- package/console/app.js +4189 -0
- package/console/architecture.html +1221 -0
- package/console/assets/depth-1.webp +0 -0
- package/console/assets/depth-2.webp +0 -0
- package/console/assets/depth-3.webp +0 -0
- package/console/assets/harness-vs-plain.svg +259 -0
- package/console/assets/hero.webp +0 -0
- package/console/assets/memory.webp +0 -0
- package/console/assets/metaharness.svg +247 -0
- package/console/index.html +777 -0
- package/console/install-architecture.html +162 -0
- package/console/install-mockup.html +543 -0
- package/console/style.css +2144 -0
- package/console/tips.css +926 -0
- package/console/tips.html +858 -0
- package/console/tips.js +128 -0
- package/docs/RELEASE-NOTES-4.0.md +88 -0
- package/kb/model-requirements.mjs +37 -6
- package/keys/ruvnet-brain-signing.pub.pem +3 -0
- package/package.json +8 -22
- package/plugin/.claude-plugin/marketplace.json +1 -0
- package/plugin/.claude-plugin/plugin.json +2 -3
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/commands/brain-console.md +2 -2
- package/plugin/commands/configure.md +3 -2
- package/plugin/commands/rvbc.md +4 -3
- package/plugin/commands/rvcb.md +2 -2
- package/plugin/commands/whats-new.md +6 -6
- package/plugin/docs/RELEASE-NOTES-4.0.md +88 -0
- package/plugin/hooks/hooks.json +1 -2
- package/plugin/mcp/managed-cli-interface.mjs +47 -4
- package/plugin/mcp/server.mjs +90 -32
- package/plugin/scripts/detach.mjs +14 -0
- package/plugin/scripts/first-session-worker.mjs +38 -0
- package/plugin/scripts/ground-ruvnet.sh +16 -6
- package/plugin/scripts/hook-shim.mjs +34 -29
- package/plugin/scripts/learn-capture.sh +22 -3
- package/plugin/scripts/learn-flush.mjs +21 -4
- package/plugin/scripts/runtime-preferences.mjs +269 -0
- package/plugin/scripts/session-start-core.mjs +503 -0
- package/plugin/scripts/session-start.sh +3 -858
- package/plugin/scripts/whats-new.mjs +42 -0
- package/plugin/skills/brain-console/SKILL.md +4 -2
- package/plugin/skills/release-proof/SKILL.md +98 -0
- package/plugin/skills/release-proof/agents/openai.yaml +4 -0
- package/plugin/skills/release-proof/references/receipt-contract.md +44 -0
- package/plugin/skills/release-proof/scripts/release-proof.mjs +286 -0
- package/plugin/skills/ruvnet-brain/PLAYBOOK.md +5 -1
- package/plugin/skills/ruvnet-brain/SKILL.md +22 -7
- package/plugin/skills/rvbc/SKILL.md +9 -6
- package/plugin/skills/whats-new/SKILL.md +4 -4
- package/scripts/adr-backfill.mjs +107 -0
- package/scripts/advocacy-outcomes.mjs +808 -0
- package/scripts/agentdb-context.mjs +216 -0
- package/scripts/agentdb-fleet-doctor.mjs +101 -0
- package/scripts/ascii-drift.mjs +236 -0
- package/scripts/behavioral-l1-l4.mjs +210 -0
- package/scripts/brain-capability-check.mjs +72 -0
- package/scripts/brain-grade-groundtruth.mjs +100 -0
- package/scripts/brain-latency-50.mjs +227 -0
- package/scripts/brain-novice-50.mjs +189 -0
- package/scripts/brain-stamp.mjs +94 -0
- package/scripts/brain-state.mjs +212 -0
- package/scripts/build-bundle.mjs +531 -0
- package/scripts/build-concepts.mjs +132 -0
- package/scripts/build-l2.mjs +71 -0
- package/scripts/build-primer.mjs +73 -0
- package/scripts/build-symbols.mjs +68 -0
- package/scripts/calibrate-router.mjs +97 -0
- package/scripts/capability-audit.mjs +321 -0
- package/scripts/capability-registry.mjs +876 -0
- package/scripts/check-indexation.mjs +108 -0
- package/scripts/check-legibility.mjs +189 -0
- package/scripts/ci/build-fixture-kb.mjs +67 -0
- package/scripts/ci/learning-replay-codex-adapter.mjs +62 -0
- package/scripts/ci/learning-replay-recorder.mjs +59 -0
- package/scripts/ci/mutate-hook-timeout.mjs +70 -0
- package/scripts/ci/stranger-fixture-stage.mjs +17 -0
- package/scripts/ci/stranger-scenario.mjs +228 -0
- package/scripts/ci/stranger-timeout.mjs +25 -0
- package/scripts/ci-verdict.mjs +29 -0
- package/scripts/claims-verify.mjs +710 -0
- package/scripts/clear-claude-tmp.sh +31 -0
- package/scripts/console-engine.mjs +434 -0
- package/scripts/console-engine.test.mjs +125 -0
- package/scripts/corpus-qa.mjs +250 -0
- package/scripts/correction-detect-embed.mjs +346 -0
- package/scripts/correction-detect-measure.mjs +270 -0
- package/scripts/correction-detect.mjs +686 -0
- package/scripts/count-chunks.mjs +54 -0
- package/scripts/described-questions.json +30 -0
- package/scripts/design-grade.mjs +58 -0
- package/scripts/dev-plugin-link.sh +105 -0
- package/scripts/distill-project.mjs +200 -0
- package/scripts/doc-currency.mjs +801 -0
- package/scripts/eval-brain.mjs +244 -0
- package/scripts/fix-metaharness-memretrieve.mjs +121 -0
- package/scripts/fix-workstream.mjs +291 -0
- package/scripts/full-hints.mjs +87 -0
- package/scripts/gate.sh +39 -0
- package/scripts/gates.mjs +146 -0
- package/scripts/gen-console-images.mjs +54 -0
- package/scripts/gen-images.mjs +47 -0
- package/scripts/git-clone-refresh.mjs +52 -0
- package/scripts/git-hooks/pre-push +126 -0
- package/scripts/goal-match.mjs +398 -0
- package/scripts/goldie-research.mjs +223 -0
- package/scripts/goldie-weekly.sh +67 -0
- package/scripts/health-repair.mjs +237 -0
- package/scripts/helix-scenario-questions.json +10 -0
- package/scripts/ingest-gists.mjs +230 -0
- package/scripts/ingest-meeting.mjs +115 -0
- package/scripts/ingest-repo.mjs +79 -0
- package/scripts/install-npx-witness.sh +49 -0
- package/scripts/issue-fix.mjs +558 -0
- package/scripts/issue-watch.mjs +276 -0
- package/scripts/issue4-close-note.md +31 -0
- package/scripts/key-canary.mjs +91 -0
- package/scripts/latency-to-surface.mjs +233 -0
- package/scripts/learning-enable.mjs +380 -0
- package/scripts/learning-replay.mjs +1570 -0
- package/scripts/learnings.mjs +62 -0
- package/scripts/lesson-gate.mjs +680 -0
- package/scripts/lesson-lifecycle.mjs +449 -0
- package/scripts/lesson-promote.mjs +262 -0
- package/scripts/lesson-ratify.mjs +98 -0
- package/scripts/lesson-seed.mjs +252 -0
- package/scripts/lesson-store.mjs +447 -0
- package/scripts/loop-checkpoint.mjs +86 -0
- package/scripts/memdb-health.sh +14 -0
- package/scripts/memory-doctor.mjs +326 -0
- package/scripts/model-catalog.mjs +79 -0
- package/scripts/nightly-controller.mjs +66 -0
- package/scripts/nightly-gists.sh +72 -0
- package/scripts/nightly-wrapper.sh +172 -0
- package/scripts/notify.sh +12 -0
- package/scripts/npx-witness.sh +56 -0
- package/scripts/onboarding-console.mjs +2922 -0
- package/scripts/private-fence.mjs +69 -0
- package/scripts/proactivity-metrics.mjs +118 -0
- package/scripts/proof-questions.json +56 -0
- package/scripts/protected-release-invocation.mjs +76 -0
- package/scripts/prove.mjs +95 -0
- package/scripts/proxy/claude-proxied.sh +57 -0
- package/scripts/proxy/proxy-revert.sh +59 -0
- package/scripts/proxy/proxy-up.sh +60 -0
- package/scripts/proxy/proxy-verify.mjs +142 -0
- package/scripts/publication-receipt.mjs +307 -0
- package/scripts/published-surface-probe.mjs +241 -0
- package/scripts/qe/card-lane-gate.mjs +162 -0
- package/scripts/qe/session-start-gate.mjs +229 -0
- package/scripts/qe/ux-suite.mjs +323 -0
- package/scripts/reconcile-project.mjs +0 -0
- package/scripts/record-lesson.mjs +113 -0
- package/scripts/refresh-model-catalog.mjs +99 -0
- package/scripts/release-authority.mjs +93 -0
- package/scripts/release-proof.mjs +9 -0
- package/scripts/release-vector.mjs +281 -0
- package/scripts/release.mjs +439 -0
- package/scripts/remedy-registry.mjs +247 -0
- package/scripts/rerank-cap-eval.mjs +265 -0
- package/scripts/rerank-cap-warm-ab.mjs +129 -0
- package/scripts/route-cheap.mjs +20 -15
- package/scripts/router-utilization.mjs +182 -0
- package/scripts/routing-flywheel.mjs +596 -0
- package/scripts/rvf-generation.mjs +104 -0
- package/scripts/rvf-index-audit.mjs +138 -0
- package/scripts/self-update.mjs +296 -0
- package/scripts/selfcheck.mjs +7 -1
- package/scripts/sign-bundle.mjs +69 -0
- package/scripts/signal-watch.mjs +171 -0
- package/scripts/stabilization-receipt.mjs +108 -0
- package/scripts/stack-sync.mjs +469 -0
- package/scripts/stamp-existing-rvf-generations.mjs +53 -0
- package/scripts/stamp-sweep.mjs +144 -0
- package/scripts/status-honesty.mjs +102 -0
- package/scripts/sync-version.mjs +217 -0
- package/scripts/token-report.mjs +102 -0
- package/scripts/top100-benchmark.mjs +479 -0
- package/scripts/top100-corpus.mjs +112 -0
- package/scripts/top100-semantic-assertions.mjs +449 -0
- package/scripts/update-apply.mjs +9 -0
- package/scripts/upgrade-notice.mjs +14 -0
- package/scripts/verify-bundle.mjs +51 -0
- package/scripts/verify-channels.mjs +184 -0
- package/scripts/verify-model-catalog.mjs +104 -0
- package/scripts/verify-nightly-close-issue4.sh +31 -0
- package/scripts/version.mjs +40 -0
- package/scripts/wired-check.mjs +867 -0
- package/plugin/scripts/finalize-token-meter.mjs +0 -25
package/console/tips.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/* RuvNet Brain — How to use it (page two).
|
|
2
|
+
Two behaviors, both progressive enhancement — with JS off the page reads exactly as before:
|
|
3
|
+
1. The same theme toggle as the console (same 'rbc-theme' key, same data-theme mechanism).
|
|
4
|
+
2. Collapsible sections (owner, 2026-07-24: the page "gets too overwhelming as a wall of
|
|
5
|
+
text"). Every .depth.card collapses behind its own header; only the inventory — the
|
|
6
|
+
section that IS the page — starts open. Open state persists per browser; a #hash
|
|
7
|
+
deep-link always opens its target. */
|
|
8
|
+
(function () {
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
/* ── theme toggle (unchanged) ─────────────────────────────────────────────── */
|
|
12
|
+
var KEY = 'rbc-theme';
|
|
13
|
+
var btn = document.getElementById('theme-toggle');
|
|
14
|
+
function applyTheme(t) {
|
|
15
|
+
document.documentElement.dataset.theme = t;
|
|
16
|
+
try { localStorage.setItem(KEY, t); } catch (e) { /* private mode is fine */ }
|
|
17
|
+
}
|
|
18
|
+
if (btn) {
|
|
19
|
+
btn.addEventListener('click', function () {
|
|
20
|
+
applyTheme(document.documentElement.dataset.theme === 'light' ? 'dark' : 'light');
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* ── collapsible sections ─────────────────────────────────────────────────── */
|
|
25
|
+
var OPEN_KEY = 'rbc-tips-open';
|
|
26
|
+
var DEFAULT_OPEN = ['inventory']; // the lead section IS the page; everything else waits
|
|
27
|
+
var sections = Array.prototype.slice.call(document.querySelectorAll('section.depth.card'));
|
|
28
|
+
if (!sections.length) return;
|
|
29
|
+
|
|
30
|
+
function savedOpen() {
|
|
31
|
+
try {
|
|
32
|
+
var raw = localStorage.getItem(OPEN_KEY);
|
|
33
|
+
return raw ? JSON.parse(raw) : null;
|
|
34
|
+
} catch (e) { return null; }
|
|
35
|
+
}
|
|
36
|
+
function persist() {
|
|
37
|
+
try {
|
|
38
|
+
var open = sections.filter(function (s) { return !s.classList.contains('is-collapsed'); })
|
|
39
|
+
.map(function (s) { return s.id; });
|
|
40
|
+
localStorage.setItem(OPEN_KEY, JSON.stringify(open));
|
|
41
|
+
} catch (e) { /* private mode is fine */ }
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function setOpen(sec, open) {
|
|
45
|
+
sec.classList.toggle('is-collapsed', !open);
|
|
46
|
+
var head = sec.querySelector(':scope > .depth-head');
|
|
47
|
+
if (head) head.setAttribute('aria-expanded', open ? 'true' : 'false');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
var open = savedOpen() || DEFAULT_OPEN;
|
|
51
|
+
sections.forEach(function (sec) {
|
|
52
|
+
var head = sec.querySelector(':scope > .depth-head');
|
|
53
|
+
if (!head || !sec.id) return;
|
|
54
|
+
|
|
55
|
+
// Wrap EVERYTHING after the header — several sections carry an art <figure> as a sibling of
|
|
56
|
+
// .depth-body, and a collapsed section that still shows its full-bleed art has not collapsed.
|
|
57
|
+
// grid-template-rows animates the height without measuring it (no reflow jank).
|
|
58
|
+
var dc = document.createElement('div'); dc.className = 'dc';
|
|
59
|
+
var dci = document.createElement('div'); dci.className = 'dci';
|
|
60
|
+
var after = [];
|
|
61
|
+
var walk = head.nextElementSibling;
|
|
62
|
+
while (walk) { after.push(walk); walk = walk.nextElementSibling; }
|
|
63
|
+
if (!after.length) return;
|
|
64
|
+
sec.appendChild(dc); dc.appendChild(dci);
|
|
65
|
+
after.forEach(function (n) { dci.appendChild(n); });
|
|
66
|
+
|
|
67
|
+
// The header is the disclosure control: chevron, ARIA, keyboard.
|
|
68
|
+
var chev = document.createElement('span');
|
|
69
|
+
chev.className = 'dc-chev';
|
|
70
|
+
chev.setAttribute('aria-hidden', 'true');
|
|
71
|
+
var svgNS = 'http://www.w3.org/2000/svg';
|
|
72
|
+
var csvg = document.createElementNS(svgNS, 'svg'); csvg.setAttribute('viewBox', '0 0 24 24');
|
|
73
|
+
var cpath = document.createElementNS(svgNS, 'path'); cpath.setAttribute('d', 'M6 9l6 6 6-6');
|
|
74
|
+
csvg.appendChild(cpath); chev.appendChild(csvg);
|
|
75
|
+
head.appendChild(chev);
|
|
76
|
+
head.setAttribute('role', 'button');
|
|
77
|
+
head.setAttribute('tabindex', '0');
|
|
78
|
+
head.setAttribute('aria-controls', sec.id + '-body');
|
|
79
|
+
dc.id = sec.id + '-body';
|
|
80
|
+
sec.classList.add('dc-ready');
|
|
81
|
+
|
|
82
|
+
function toggle() { setOpen(sec, sec.classList.contains('is-collapsed')); persist(); }
|
|
83
|
+
head.addEventListener('click', function (e) {
|
|
84
|
+
if (e.target.closest && e.target.closest('a, button')) return; // links in headers stay links
|
|
85
|
+
toggle();
|
|
86
|
+
});
|
|
87
|
+
head.addEventListener('keydown', function (e) {
|
|
88
|
+
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggle(); }
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
setOpen(sec, open.indexOf(sec.id) !== -1);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// One small master switch, right-aligned above the first section.
|
|
95
|
+
var all = document.createElement('p');
|
|
96
|
+
all.className = 'dc-all';
|
|
97
|
+
var allBtn = document.createElement('button');
|
|
98
|
+
allBtn.type = 'button';
|
|
99
|
+
function anyCollapsed() {
|
|
100
|
+
return sections.some(function (s) { return s.classList.contains('is-collapsed'); });
|
|
101
|
+
}
|
|
102
|
+
function labelAll() { allBtn.textContent = anyCollapsed() ? 'expand all' : 'collapse all'; }
|
|
103
|
+
allBtn.addEventListener('click', function () {
|
|
104
|
+
var opening = anyCollapsed();
|
|
105
|
+
sections.forEach(function (s) { setOpen(s, opening); });
|
|
106
|
+
persist(); labelAll();
|
|
107
|
+
});
|
|
108
|
+
all.appendChild(allBtn);
|
|
109
|
+
sections[0].parentNode.insertBefore(all, sections[0]);
|
|
110
|
+
labelAll();
|
|
111
|
+
sections.forEach(function (s) {
|
|
112
|
+
var h = s.querySelector(':scope > .depth-head');
|
|
113
|
+
if (!h) return;
|
|
114
|
+
h.addEventListener('click', function () { setTimeout(labelAll, 0); });
|
|
115
|
+
h.addEventListener('keydown', function () { setTimeout(labelAll, 0); });
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// A #hash deep-link must always land on an OPEN section — from the console's cards, the
|
|
119
|
+
// metaharness cross-reference, or a shared URL.
|
|
120
|
+
function openHashTarget() {
|
|
121
|
+
var id = (location.hash || '').replace(/^#/, '');
|
|
122
|
+
if (!id) return;
|
|
123
|
+
var sec = document.getElementById(id);
|
|
124
|
+
if (sec && sec.classList.contains('depth')) { setOpen(sec, true); persist(); labelAll(); }
|
|
125
|
+
}
|
|
126
|
+
window.addEventListener('hashchange', openHashTarget);
|
|
127
|
+
openHashTarget();
|
|
128
|
+
}());
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# RuvNet-Brain 4.0 line — what's new (the major-release highlights)
|
|
2
|
+
|
|
3
|
+
Updated: 2026-08-01
|
|
4
|
+
|
|
5
|
+
> **Source of truth** for the `/whats-new` command and the first-run upgrade message. Curated, honest,
|
|
6
|
+
> major-only — not the point-release churn. If a claim here isn't true of the shipping build, it does not
|
|
7
|
+
> belong here. The self-measurement claims are deliberately hedged: they are *new and filling*, not
|
|
8
|
+
> *proven*.
|
|
9
|
+
>
|
|
10
|
+
> **VERSION STATUS:** the public release line is now 4.x. Publication does not erase the remaining
|
|
11
|
+
> acceptance obligations: the exact public artifact must still pass the fail-closed release contract
|
|
12
|
+
> through fresh Claude Code and Codex hosts. Anything not proven through that boundary is listed as a
|
|
13
|
+
> limitation, never converted into a capability claim.
|
|
14
|
+
|
|
15
|
+
**One line:** the 4.0 line is where the brain got **honest, legible, fast, and self-measuring** — and
|
|
16
|
+
it's landing now.
|
|
17
|
+
|
|
18
|
+
## The big things
|
|
19
|
+
|
|
20
|
+
### Release proof is fail-closed
|
|
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
|
|
23
|
+
`ruvnet-brain` self-RVF store, weak query-deadline margin, missing independent graders,
|
|
24
|
+
host/artifact mismatches, and public-byte drift are release failures rather than warnings.
|
|
25
|
+
`npm run release:proof -- --status --quick` shows the current live blockers.
|
|
26
|
+
|
|
27
|
+
### 1. The Console is the front door
|
|
28
|
+
Type `/rvbc` and your whole RuvNet stack is on one live local page: what's installed, what the AI has
|
|
29
|
+
actually learned from *your* projects (real memories + distilled lessons, drill-down to the verbatim
|
|
30
|
+
cards), which subscription pays for what, and one-click **reversible** fixes for anything stale. New in
|
|
31
|
+
4.0:
|
|
32
|
+
- a plain-English **explainer on every card** (no more guessing what "trust & provenance" means),
|
|
33
|
+
- every suggestion carries its **blast radius** — *just this project* vs *every project · this machine*,
|
|
34
|
+
- **safe on/off checkboxes** that appear *only* where the undo is proven,
|
|
35
|
+
- a **terminal-first install** — the granular "here's exactly what I'll do, uncheck any of it" flow runs
|
|
36
|
+
in your terminal, where an `npx` user expects it.
|
|
37
|
+
|
|
38
|
+
### 2. It will not lie about your machine
|
|
39
|
+
Every number is measured live from your setup. **"We couldn't check" never renders as "off."** One
|
|
40
|
+
project's state can never leak into another project's view (a real bug 4.0 fixed in the console itself).
|
|
41
|
+
Empty-first, honest-always.
|
|
42
|
+
|
|
43
|
+
### 3. Fast — and it tells you when it's ready
|
|
44
|
+
The console and tips page paint in **well under a second** (measured, with a QE suite that runs every
|
|
45
|
+
time). On a first scan it shows a **countdown** and then says *"it's live — take a look at your page,"*
|
|
46
|
+
so you're never staring at a blank screen wondering if it hung.
|
|
47
|
+
|
|
48
|
+
### 4. It measures itself now
|
|
49
|
+
The brain records when it offered help and whether you acted on it — so over time it can **prove** it's
|
|
50
|
+
improving instead of asserting it. **Honest caveat:** this instrumentation is *new* and has only just
|
|
51
|
+
started collecting. 4.0 is not a claim of "proven better in the field" — it is the release that makes
|
|
52
|
+
that proof *possible*, and the evidence accrues as you use it.
|
|
53
|
+
|
|
54
|
+
### 5. It learns across your projects
|
|
55
|
+
A lesson proven in one project can be **promoted to your global brain** and applied everywhere — and it
|
|
56
|
+
now **survives an update** (tested against the real updater, not argued).
|
|
57
|
+
|
|
58
|
+
### 6. Runs on your account, cheapest capable model
|
|
59
|
+
The QE suite and model routing use **your Claude account, not an API key**, at the least-powerful model
|
|
60
|
+
that does the job. Nothing bills silently.
|
|
61
|
+
|
|
62
|
+
### 7. Claude Code and Codex share one active runtime
|
|
63
|
+
Both hosts are wired to the same Stable Spine generation: the MCP search shell, lifecycle hooks,
|
|
64
|
+
skills and update behavior advance as one versioned runtime instead of being installed as unrelated
|
|
65
|
+
copies.
|
|
66
|
+
|
|
67
|
+
### 8. Source grounding is an RVF-native product surface
|
|
68
|
+
The Brain searches per-repository RuVector RVF stores, joins hits to their source passages, and
|
|
69
|
+
returns cited repository paths. Model memory is not accepted as evidence for rUv-stack claims.
|
|
70
|
+
|
|
71
|
+
### 9. Quality and harness workflows are explicit
|
|
72
|
+
Agentic-QE is the testing fleet. Harness scoring evaluates the orchestration layer, and cost-aware
|
|
73
|
+
routing can select cheaper capable models when the required provider access is configured. These are
|
|
74
|
+
named workflows a user can request, not silent substitutes.
|
|
75
|
+
|
|
76
|
+
## What 4.0 deliberately does NOT claim
|
|
77
|
+
Stated up front because overclaiming is the one thing this product cannot do:
|
|
78
|
+
- **Not** "proven X% better" — the outcome ledger is still filling (see #4).
|
|
79
|
+
- **Not** "fully proactive / anticipatory" — the brain still mostly speaks when you open the console or
|
|
80
|
+
ask; the in-session, unprompted surface is the next frontier, not a shipped 4.0 guarantee.
|
|
81
|
+
- **Not** independently graded ≥95 on the exact public artifact. A score is not a release substitute.
|
|
82
|
+
- **Not** fully accepted while any critical exact-artifact, host, retrieval, version-convergence or
|
|
83
|
+
recovery invariant is FAIL, UNKNOWN, skipped or mocked-only.
|
|
84
|
+
|
|
85
|
+
## For upgraders
|
|
86
|
+
On the first real major-version transition, the installer/session experience presents the concise
|
|
87
|
+
highlights once. Run `npx ruvnet-brain --whats-new` at any time to read this full list again, or
|
|
88
|
+
`npx ruvnet-brain --what-changed` to inspect the exact machine footprint and undo path for each piece.
|
|
@@ -19,19 +19,50 @@ export function modelCacheReady(modelCache, model, revision = null) {
|
|
|
19
19
|
].every((file) => fs.existsSync(file));
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
function acquireMaterializeLock(destination, timeoutMs = 30_000) {
|
|
23
|
+
const lock = `${destination}.materialize-lock`;
|
|
24
|
+
const started = Date.now();
|
|
25
|
+
fs.mkdirSync(path.dirname(destination), { recursive: true });
|
|
26
|
+
while (true) {
|
|
27
|
+
try {
|
|
28
|
+
fs.mkdirSync(lock);
|
|
29
|
+
return () => fs.rmSync(lock, { recursive: true, force: true });
|
|
30
|
+
} catch (error) {
|
|
31
|
+
if (error?.code !== 'EEXIST') throw error;
|
|
32
|
+
try {
|
|
33
|
+
const ageMs = Date.now() - fs.statSync(lock).mtimeMs;
|
|
34
|
+
if (ageMs > timeoutMs) {
|
|
35
|
+
fs.rmSync(lock, { recursive: true, force: true });
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
} catch { /* another process released it between checks */ }
|
|
39
|
+
if (Date.now() - started >= timeoutMs) {
|
|
40
|
+
throw new Error(`timed out waiting to materialize model cache: ${destination}`);
|
|
41
|
+
}
|
|
42
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 25);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
22
47
|
// Revision-pinned downloads live below <model>/<revision>/, while strict offline reads resolve
|
|
23
48
|
// <model>/ directly. Promote only the exact pinned files into that canonical offline location.
|
|
24
49
|
export function materializeModelRevision(modelCache, model, revision) {
|
|
25
50
|
if (!revision || !modelCacheReady(modelCache, model, revision)) return false;
|
|
26
51
|
const source = path.join(modelPath(modelCache, model), revision);
|
|
27
52
|
const destination = modelPath(modelCache, model);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
53
|
+
const release = acquireMaterializeLock(destination);
|
|
54
|
+
try {
|
|
55
|
+
if (modelCacheReady(modelCache, model)) return true;
|
|
56
|
+
for (const entry of fs.readdirSync(source)) {
|
|
57
|
+
fs.cpSync(path.join(source, entry), path.join(destination, entry), {
|
|
58
|
+
recursive: true,
|
|
59
|
+
force: true,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return modelCacheReady(modelCache, model);
|
|
63
|
+
} finally {
|
|
64
|
+
release();
|
|
33
65
|
}
|
|
34
|
-
return modelCacheReady(modelCache, model);
|
|
35
66
|
}
|
|
36
67
|
|
|
37
68
|
// The RVF sidecar is the source of truth for the query embedder. Only sidecars with a matching
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ruvnet-brain",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.4",
|
|
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": {
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"test": "node plugin/test/run-tests.mjs",
|
|
11
|
+
"release:proof": "node scripts/release-proof.mjs",
|
|
12
|
+
"benchmark:brain50": "node scripts/brain-latency-50.mjs",
|
|
13
|
+
"benchmark:novice50": "node scripts/brain-novice-50.mjs",
|
|
11
14
|
"version:check": "node scripts/sync-version.mjs --check",
|
|
12
15
|
"claims:verify": "node scripts/claims-verify.mjs",
|
|
13
16
|
"claims:fix": "node scripts/claims-verify.mjs --fix",
|
|
@@ -61,33 +64,16 @@
|
|
|
61
64
|
"!plugin/scripts/.ruvnet-brain/",
|
|
62
65
|
"!plugin/test/",
|
|
63
66
|
"README.md",
|
|
67
|
+
"docs/RELEASE-NOTES-4.0.md",
|
|
64
68
|
"LICENSE",
|
|
69
|
+
"console/",
|
|
65
70
|
"config/model-router/",
|
|
71
|
+
"scripts/",
|
|
66
72
|
"kb/verify-citation.mjs",
|
|
67
73
|
"kb/zip-extract.mjs",
|
|
68
74
|
"kb/brain-profile.mjs",
|
|
69
75
|
"kb/model-requirements.mjs",
|
|
70
|
-
"
|
|
71
|
-
"scripts/model-router-setup.mjs",
|
|
72
|
-
"scripts/model-router-status.mjs",
|
|
73
|
-
"scripts/model-router-outcome.mjs",
|
|
74
|
-
"scripts/subscription-hosts.mjs",
|
|
75
|
-
"scripts/dual-host-deliberation.mjs",
|
|
76
|
-
"scripts/dual-host-suggest.mjs",
|
|
77
|
-
"scripts/route-cheap.mjs",
|
|
78
|
-
"scripts/dispatch-receipt.mjs",
|
|
79
|
-
"scripts/metaharness-receipts.mjs",
|
|
80
|
-
"scripts/codex-routed.sh",
|
|
81
|
-
"scripts/metaharness-router.mjs",
|
|
82
|
-
"scripts/no-silent-substitution.mjs",
|
|
83
|
-
"scripts/user-settings.mjs",
|
|
84
|
-
"scripts/selfcheck.mjs",
|
|
85
|
-
"scripts/hook-registry.mjs",
|
|
86
|
-
"scripts/install-scope.mjs",
|
|
87
|
-
"scripts/upgrade-notice.mjs",
|
|
88
|
-
"scripts/falsify.mjs",
|
|
89
|
-
"scripts/nightly-watchdog.mjs",
|
|
90
|
-
"scripts/job-heartbeat.sh"
|
|
76
|
+
"keys/ruvnet-brain-signing.pub.pem"
|
|
91
77
|
],
|
|
92
78
|
"engines": {
|
|
93
79
|
"node": ">=18"
|
|
@@ -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 69 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 an enforced UserPromptSubmit retrieve-and-inject grounding hook that sharply reduces drift.",
|
|
4
|
-
"version": "4.0.
|
|
4
|
+
"version": "4.0.4",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Stuart Kerr"
|
|
7
7
|
},
|
|
@@ -18,6 +18,5 @@
|
|
|
18
18
|
"brain",
|
|
19
19
|
"mcp",
|
|
20
20
|
"claude-code"
|
|
21
|
-
]
|
|
22
|
-
"updated": "2026-07-30"
|
|
21
|
+
]
|
|
23
22
|
}
|
|
@@ -7,8 +7,8 @@ updated: 2026-07-20
|
|
|
7
7
|
correct the user's spelling.
|
|
8
8
|
|
|
9
9
|
1. Say: "Opening it now; it scans live while you watch."
|
|
10
|
-
2.
|
|
11
|
-
|
|
10
|
+
2. Use `${RUVNET_BRAIN_KB:-$HOME/.cache/ruvnet-brain/kb}/.console-runtime/scripts/onboarding-console.mjs`.
|
|
11
|
+
A current-repository copy is allowed only for an explicit developer checkout.
|
|
12
12
|
3. Run `node <resolved-script> --serve --open` in the background.
|
|
13
13
|
4. Give the URL immediately. Never promise a duration; the page reports its own progress.
|
|
14
14
|
|
|
@@ -8,8 +8,9 @@ their actual machine and lets them configure and (with consent) fix it.
|
|
|
8
8
|
|
|
9
9
|
Do this:
|
|
10
10
|
|
|
11
|
-
1. **Find the
|
|
12
|
-
|
|
11
|
+
1. **Find the installed runtime.** Use
|
|
12
|
+
`${RUVNET_BRAIN_KB:-$HOME/.cache/ruvnet-brain/kb}/.console-runtime/scripts/onboarding-console.mjs`.
|
|
13
|
+
A current-repository copy is allowed only for an explicit developer checkout.
|
|
13
14
|
|
|
14
15
|
2. **Start the server in the BACKGROUND** (it is a long-running process) so this turn keeps going, and
|
|
15
16
|
open the browser:
|
package/plugin/commands/rvbc.md
CHANGED
|
@@ -26,10 +26,11 @@ opening it now and it will scan itself live in their browser. Something in the s
|
|
|
26
26
|
Say it like a person, not a status bar. **Do not** promise 20 seconds, a minute, or any duration: the
|
|
27
27
|
page carries its own timing now, and a number invented here is a number the page will contradict.
|
|
28
28
|
|
|
29
|
-
## 2. Find the
|
|
29
|
+
## 2. Find the installed runtime
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
Use `${RUVNET_BRAIN_KB:-$HOME/.cache/ruvnet-brain/kb}/.console-runtime/scripts/onboarding-console.mjs`.
|
|
32
|
+
A current-repository copy is allowed only in an explicit developer checkout. Never guess a
|
|
33
|
+
`~/Code/ruvnet-brain` path: the installer persists this runtime for clean users.
|
|
33
34
|
|
|
34
35
|
## 3. Start it in the BACKGROUND and open the browser
|
|
35
36
|
|
package/plugin/commands/rvcb.md
CHANGED
|
@@ -7,8 +7,8 @@ updated: 2026-07-20
|
|
|
7
7
|
correct the user's spelling.
|
|
8
8
|
|
|
9
9
|
1. Say: "Opening it now; it scans live while you watch."
|
|
10
|
-
2.
|
|
11
|
-
|
|
10
|
+
2. Use `${RUVNET_BRAIN_KB:-$HOME/.cache/ruvnet-brain/kb}/.console-runtime/scripts/onboarding-console.mjs`.
|
|
11
|
+
A current-repository copy is allowed only for an explicit developer checkout.
|
|
12
12
|
3. Run `node <resolved-script> --serve --open` in the background.
|
|
13
13
|
4. Give the URL immediately. Never promise a duration; the page reports its own progress.
|
|
14
14
|
|
|
@@ -9,14 +9,15 @@ The user wants the headline story of the **major** release they're on — the 4.
|
|
|
9
9
|
**not** the "3.9.x → 3.9.y" point-release churn. Deliver it warmly and honestly, then offer the Console.
|
|
10
10
|
|
|
11
11
|
**First, ground — never recite this from memory (it drifts every release):**
|
|
12
|
-
1.
|
|
12
|
+
1. Run `node "${CLAUDE_PLUGIN_ROOT}/scripts/whats-new.mjs"`. This reads the running version and curated
|
|
13
|
+
notes from the same immutable installed payload. If it exits nonzero, report that exact failure;
|
|
14
|
+
do not substitute a checkout, download, or another installed version. State the version honestly.
|
|
13
15
|
**Do NOT claim "you're on 4.0"** unless the version literally starts with `4.` — per ADR-042 the
|
|
14
16
|
number stays `3.9.x-dev` until the 4.0 line is field-verified. The honest framing is: *"these are the
|
|
15
17
|
4.0-line enhancements, and you already have them — the version stamps to 4.0 once they're proven in
|
|
16
18
|
real use."*
|
|
17
|
-
2.
|
|
18
|
-
|
|
19
|
-
version framing.
|
|
19
|
+
2. Treat the executable's notes as the source of truth — summarize them, don't invent beside them,
|
|
20
|
+
and carry their honest version framing.
|
|
20
21
|
|
|
21
22
|
**Then tell them what the 4.0 line is — the honest headline (adapt to the notes file; do NOT overclaim):**
|
|
22
23
|
|
|
@@ -49,8 +50,7 @@ word — or type `/rvbc`."* If they say yes, follow `rvbc.md` in this same direc
|
|
|
49
50
|
warm heads-up about the ~20s scan).
|
|
50
51
|
|
|
51
52
|
**Honesty rules for this command (same as the product):**
|
|
52
|
-
- If
|
|
53
|
-
you can verify — never fabricate a highlight.
|
|
53
|
+
- If the installed executable fails, report its failure and do not fabricate a highlight.
|
|
54
54
|
- Never claim a metric ("40% better", "95/100") the release has not independently earned. The self-
|
|
55
55
|
measurement is new and still filling; say so plainly.
|
|
56
56
|
- This is the MAJOR story only. If the user wants the point-release detail, point them at the repo's
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# RuvNet-Brain 4.0 line — what's new (the major-release highlights)
|
|
2
|
+
|
|
3
|
+
Updated: 2026-08-01
|
|
4
|
+
|
|
5
|
+
> **Source of truth** for the `/whats-new` command and the first-run upgrade message. Curated, honest,
|
|
6
|
+
> major-only — not the point-release churn. If a claim here isn't true of the shipping build, it does not
|
|
7
|
+
> belong here. The self-measurement claims are deliberately hedged: they are *new and filling*, not
|
|
8
|
+
> *proven*.
|
|
9
|
+
>
|
|
10
|
+
> **VERSION STATUS:** the public release line is now 4.x. Publication does not erase the remaining
|
|
11
|
+
> acceptance obligations: the exact public artifact must still pass the fail-closed release contract
|
|
12
|
+
> through fresh Claude Code and Codex hosts. Anything not proven through that boundary is listed as a
|
|
13
|
+
> limitation, never converted into a capability claim.
|
|
14
|
+
|
|
15
|
+
**One line:** the 4.0 line is where the brain got **honest, legible, fast, and self-measuring** — and
|
|
16
|
+
it's landing now.
|
|
17
|
+
|
|
18
|
+
## The big things
|
|
19
|
+
|
|
20
|
+
### Release proof is fail-closed
|
|
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
|
|
23
|
+
`ruvnet-brain` self-RVF store, weak query-deadline margin, missing independent graders,
|
|
24
|
+
host/artifact mismatches, and public-byte drift are release failures rather than warnings.
|
|
25
|
+
`npm run release:proof -- --status --quick` shows the current live blockers.
|
|
26
|
+
|
|
27
|
+
### 1. The Console is the front door
|
|
28
|
+
Type `/rvbc` and your whole RuvNet stack is on one live local page: what's installed, what the AI has
|
|
29
|
+
actually learned from *your* projects (real memories + distilled lessons, drill-down to the verbatim
|
|
30
|
+
cards), which subscription pays for what, and one-click **reversible** fixes for anything stale. New in
|
|
31
|
+
4.0:
|
|
32
|
+
- a plain-English **explainer on every card** (no more guessing what "trust & provenance" means),
|
|
33
|
+
- every suggestion carries its **blast radius** — *just this project* vs *every project · this machine*,
|
|
34
|
+
- **safe on/off checkboxes** that appear *only* where the undo is proven,
|
|
35
|
+
- a **terminal-first install** — the granular "here's exactly what I'll do, uncheck any of it" flow runs
|
|
36
|
+
in your terminal, where an `npx` user expects it.
|
|
37
|
+
|
|
38
|
+
### 2. It will not lie about your machine
|
|
39
|
+
Every number is measured live from your setup. **"We couldn't check" never renders as "off."** One
|
|
40
|
+
project's state can never leak into another project's view (a real bug 4.0 fixed in the console itself).
|
|
41
|
+
Empty-first, honest-always.
|
|
42
|
+
|
|
43
|
+
### 3. Fast — and it tells you when it's ready
|
|
44
|
+
The console and tips page paint in **well under a second** (measured, with a QE suite that runs every
|
|
45
|
+
time). On a first scan it shows a **countdown** and then says *"it's live — take a look at your page,"*
|
|
46
|
+
so you're never staring at a blank screen wondering if it hung.
|
|
47
|
+
|
|
48
|
+
### 4. It measures itself now
|
|
49
|
+
The brain records when it offered help and whether you acted on it — so over time it can **prove** it's
|
|
50
|
+
improving instead of asserting it. **Honest caveat:** this instrumentation is *new* and has only just
|
|
51
|
+
started collecting. 4.0 is not a claim of "proven better in the field" — it is the release that makes
|
|
52
|
+
that proof *possible*, and the evidence accrues as you use it.
|
|
53
|
+
|
|
54
|
+
### 5. It learns across your projects
|
|
55
|
+
A lesson proven in one project can be **promoted to your global brain** and applied everywhere — and it
|
|
56
|
+
now **survives an update** (tested against the real updater, not argued).
|
|
57
|
+
|
|
58
|
+
### 6. Runs on your account, cheapest capable model
|
|
59
|
+
The QE suite and model routing use **your Claude account, not an API key**, at the least-powerful model
|
|
60
|
+
that does the job. Nothing bills silently.
|
|
61
|
+
|
|
62
|
+
### 7. Claude Code and Codex share one active runtime
|
|
63
|
+
Both hosts are wired to the same Stable Spine generation: the MCP search shell, lifecycle hooks,
|
|
64
|
+
skills and update behavior advance as one versioned runtime instead of being installed as unrelated
|
|
65
|
+
copies.
|
|
66
|
+
|
|
67
|
+
### 8. Source grounding is an RVF-native product surface
|
|
68
|
+
The Brain searches per-repository RuVector RVF stores, joins hits to their source passages, and
|
|
69
|
+
returns cited repository paths. Model memory is not accepted as evidence for rUv-stack claims.
|
|
70
|
+
|
|
71
|
+
### 9. Quality and harness workflows are explicit
|
|
72
|
+
Agentic-QE is the testing fleet. Harness scoring evaluates the orchestration layer, and cost-aware
|
|
73
|
+
routing can select cheaper capable models when the required provider access is configured. These are
|
|
74
|
+
named workflows a user can request, not silent substitutes.
|
|
75
|
+
|
|
76
|
+
## What 4.0 deliberately does NOT claim
|
|
77
|
+
Stated up front because overclaiming is the one thing this product cannot do:
|
|
78
|
+
- **Not** "proven X% better" — the outcome ledger is still filling (see #4).
|
|
79
|
+
- **Not** "fully proactive / anticipatory" — the brain still mostly speaks when you open the console or
|
|
80
|
+
ask; the in-session, unprompted surface is the next frontier, not a shipped 4.0 guarantee.
|
|
81
|
+
- **Not** independently graded ≥95 on the exact public artifact. A score is not a release substitute.
|
|
82
|
+
- **Not** fully accepted while any critical exact-artifact, host, retrieval, version-convergence or
|
|
83
|
+
recovery invariant is FAIL, UNKNOWN, skipped or mocked-only.
|
|
84
|
+
|
|
85
|
+
## For upgraders
|
|
86
|
+
On the first real major-version transition, the installer/session experience presents the concise
|
|
87
|
+
highlights once. Run `npx ruvnet-brain --whats-new` at any time to read this full list again, or
|
|
88
|
+
`npx ruvnet-brain --what-changed` to inspect the exact machine footprint and undo path for each piece.
|
package/plugin/hooks/hooks.json
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"_platform": "posix",
|
|
2
|
+
"description": "POSIX Stable Spine (ADR-023): every hook routes through hook-shim.mjs, which resolves the active generation per invocation. Advisory hooks fail open; blocking hooks preserve their exit-code contract.",
|
|
4
3
|
"hooks": {
|
|
5
4
|
"SessionStart": [
|
|
6
5
|
{
|
|
@@ -2,6 +2,7 @@ import { spawn } from 'node:child_process';
|
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
+
import { loadRuntimePreferences, runtimeChildEnv } from '../scripts/runtime-preferences.mjs';
|
|
5
6
|
|
|
6
7
|
export const MANAGED_EXECUTABLES = Object.freeze([
|
|
7
8
|
'ruflo',
|
|
@@ -142,9 +143,21 @@ function writeStamps(executable, argv, env) {
|
|
|
142
143
|
}
|
|
143
144
|
}
|
|
144
145
|
|
|
146
|
+
export function resolveManagedExecutable(executable, env = process.env) {
|
|
147
|
+
if (executable !== 'ruflo') return executable;
|
|
148
|
+
const home = env.HOME || os.homedir();
|
|
149
|
+
const canonical = path.join(home, '.npm-global', 'bin', 'ruflo');
|
|
150
|
+
try {
|
|
151
|
+
fs.accessSync(canonical, fs.constants.X_OK);
|
|
152
|
+
return canonical;
|
|
153
|
+
} catch {
|
|
154
|
+
return executable;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
145
158
|
function execute(executable, argv, env) {
|
|
146
159
|
return new Promise((resolve) => {
|
|
147
|
-
const child = spawn(executable, argv, {
|
|
160
|
+
const child = spawn(resolveManagedExecutable(executable, env), argv, {
|
|
148
161
|
env,
|
|
149
162
|
shell: false,
|
|
150
163
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
@@ -186,8 +199,9 @@ function execute(executable, argv, env) {
|
|
|
186
199
|
|
|
187
200
|
function resultOf(executable, argv, result) {
|
|
188
201
|
const output = [result.stdout, result.stderr].filter(Boolean).join(result.stdout && result.stderr ? '\n' : '');
|
|
189
|
-
|
|
190
|
-
|
|
202
|
+
const contradictoryFailure = /(?:^|\n)\s*(?:❌|\[ERROR\])|invalid pragma command|key not found/i.test(output);
|
|
203
|
+
if (result.error || result.code !== 0 || contradictoryFailure) {
|
|
204
|
+
const reason = result.error || (contradictoryFailure ? 'fatal output despite exit 0' : `exit ${result.code}`);
|
|
191
205
|
return {
|
|
192
206
|
content: [{ type: 'text', text: output || `${executable} ${argv.join(' ')} failed: ${reason}` }],
|
|
193
207
|
isError: true,
|
|
@@ -220,7 +234,36 @@ export async function callManagedCli(toolName, args, env = process.env) {
|
|
|
220
234
|
isError: true,
|
|
221
235
|
};
|
|
222
236
|
}
|
|
223
|
-
|
|
237
|
+
const policy = loadRuntimePreferences({ env, cwd: env.RUVNET_BRAIN_PROJECT_DIR || process.cwd() });
|
|
238
|
+
if (executable === 'agentic-flow' && policy.values.routing !== 'auto') {
|
|
239
|
+
return {
|
|
240
|
+
content: [{
|
|
241
|
+
type: 'text',
|
|
242
|
+
text: policy.values.routing === 'off'
|
|
243
|
+
? 'Token-smart routing is off in RuvNet Brain Console; agentic-flow was not started.'
|
|
244
|
+
: 'Token-smart routing has not been enabled in RuvNet Brain Console; agentic-flow was not started.',
|
|
245
|
+
}],
|
|
246
|
+
isError: true,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
const isFleetMutation = executable === 'agentic-qe'
|
|
250
|
+
&& argv[0] === 'fleet'
|
|
251
|
+
&& ['init', 'spawn', 'run'].includes(argv[1]);
|
|
252
|
+
if (isFleetMutation && policy.values.qeFleet !== true) {
|
|
253
|
+
return {
|
|
254
|
+
content: [{
|
|
255
|
+
type: 'text',
|
|
256
|
+
text: policy.values.qeFleet === false
|
|
257
|
+
? 'The Agentic-QE fleet is off in RuvNet Brain Console; no QE agents were started.'
|
|
258
|
+
: 'The Agentic-QE fleet has not been enabled in RuvNet Brain Console; no QE agents were started.',
|
|
259
|
+
}],
|
|
260
|
+
isError: true,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
const childEnv = (executable === 'agentic-flow' || executable === 'agentic-qe')
|
|
264
|
+
? runtimeChildEnv({ env, cwd: env.RUVNET_BRAIN_PROJECT_DIR || process.cwd() })
|
|
265
|
+
: env;
|
|
266
|
+
return resultOf(executable, argv, await execute(executable, argv, childEnv));
|
|
224
267
|
}
|
|
225
268
|
|
|
226
269
|
return {
|