ruvnet-brain 4.0.8 โ†’ 4.0.24

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 (63) hide show
  1. package/README.md +3 -3
  2. package/bin/install.mjs +109 -42
  3. package/console/app.js +32 -11
  4. package/console/style.css +5 -0
  5. package/package.json +1 -1
  6. package/plugin/.claude-plugin/plugin.json +2 -2
  7. package/plugin/.codex-plugin/plugin.json +1 -1
  8. package/plugin/scripts/advocacy-outcomes.mjs +808 -0
  9. package/plugin/scripts/anticipate.sh +80 -14
  10. package/plugin/scripts/capability-registry.mjs +994 -0
  11. package/plugin/scripts/codex-hook-wrapper.mjs +1 -0
  12. package/plugin/scripts/continuation-gate.mjs +169 -1
  13. package/plugin/scripts/gates.mjs +146 -0
  14. package/plugin/scripts/goal-match.mjs +398 -0
  15. package/plugin/scripts/hijack-ruvnet.sh +69 -1
  16. package/plugin/scripts/hook-registry.mjs +616 -0
  17. package/plugin/scripts/hook-shim.mjs +13 -2
  18. package/plugin/scripts/learn-flush.mjs +37 -2
  19. package/plugin/scripts/learning-enable.mjs +382 -0
  20. package/plugin/scripts/lesson-promote.mjs +262 -0
  21. package/plugin/scripts/lesson-provenance.mjs +43 -0
  22. package/plugin/scripts/lesson-store.mjs +67 -56
  23. package/plugin/scripts/memory-doctor.mjs +345 -0
  24. package/plugin/scripts/nightly-controller.mjs +98 -0
  25. package/plugin/scripts/project-identity.mjs +89 -0
  26. package/plugin/scripts/ruflo-bin.mjs +81 -0
  27. package/plugin/scripts/runtime-preferences.mjs +18 -0
  28. package/plugin/scripts/session-snapshot-hook.mjs +4 -1
  29. package/plugin/scripts/session-start-core.mjs +19 -2
  30. package/plugin/scripts/unprompted-runtime.mjs +22 -7
  31. package/plugin/scripts/user-settings.mjs +672 -0
  32. package/plugin/skills/ruvnet-brain/SKILL.md +2 -2
  33. package/scripts/advocacy-outcomes.mjs +4 -808
  34. package/scripts/capability-registry.mjs +4 -876
  35. package/scripts/console-runtime-identity.mjs +74 -0
  36. package/scripts/corpus-qa.mjs +44 -6
  37. package/scripts/distill-project.mjs +9 -1
  38. package/scripts/doc-currency.mjs +45 -4
  39. package/scripts/gates.mjs +4 -146
  40. package/scripts/goal-match.mjs +4 -398
  41. package/scripts/health-repair.mjs +88 -11
  42. package/scripts/hook-registry.mjs +4 -567
  43. package/scripts/host-install-matrix.mjs +155 -0
  44. package/scripts/issue-watch.mjs +108 -0
  45. package/scripts/learning-enable.mjs +4 -380
  46. package/scripts/lesson-promote.mjs +4 -262
  47. package/scripts/memory-doctor.mjs +4 -342
  48. package/scripts/model-router-catalog.mjs +34 -0
  49. package/scripts/nightly-controller.mjs +4 -66
  50. package/scripts/nightly-wrapper.sh +23 -1
  51. package/scripts/onboarding-console.mjs +34 -12
  52. package/scripts/proactivity-metrics.mjs +8 -1
  53. package/scripts/publication-receipt.mjs +10 -1
  54. package/scripts/qe/ux-suite.mjs +72 -1
  55. package/scripts/release-abort-stale.mjs +111 -0
  56. package/scripts/release-convergence-watchdog.mjs +119 -0
  57. package/scripts/release-transaction-provider.mjs +76 -8
  58. package/scripts/release-transaction.mjs +55 -17
  59. package/scripts/rvf-generation.mjs +17 -0
  60. package/scripts/self-update.mjs +63 -10
  61. package/scripts/staged-host-verifier.mjs +27 -54
  62. package/scripts/sync-version.mjs +10 -10
  63. package/scripts/user-settings.mjs +4 -640
@@ -1,6 +1,7 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { createSessionSnapshot } from './session-snapshot-contract.mjs';
4
+ import { projectDirectory } from './project-identity.mjs';
4
5
 
5
6
  function regularOrAbsent(file) {
6
7
  try {
@@ -30,5 +31,7 @@ export function writeSessionSnapshot(projectDir, event) {
30
31
  }
31
32
 
32
33
  if (process.argv[1] && path.resolve(process.argv[1]).endsWith('session-snapshot-hook.mjs')) {
33
- writeSessionSnapshot(process.env.CLAUDE_PROJECT_DIR || process.cwd(), process.argv[2] || 'SessionEnd');
34
+ // projectDirectory() is the SAME derivation the Console's detector uses. Deriving it here
35
+ // independently is what let this hook write a receipt the Console then reported as missing (#85).
36
+ writeSessionSnapshot(projectDirectory(), process.argv[2] || 'SessionEnd');
34
37
  }
@@ -472,11 +472,28 @@ export async function runSessionStart({
472
472
  emit(`[RuvNet Brain v${bannerVersion} โ€” active this session, RETRIEVAL DOWN]`);
473
473
  emit(`The plugin and its hooks are running, but the brain itself is broken (see the alarm above). Do not claim grounding works. If you mention it at all: "๐Ÿง  RuvNet Brain active (v${bannerVersion}) โ€” but its search is down right now."`);
474
474
  } else {
475
- emit(`[RuvNet Brain v${bannerVersion} โ€” active this session${updated ? ` ยท updated ${updated}` : ''}${kbVersion ? ` ยท knowledge bundle ${kbVersion}` : ''}]`);
475
+ // ONE VERSION, CUSTOMER-FACING (issue #77, restated from the customer's side).
476
+ //
477
+ // This printed the plugin version and the knowledge bundle's tag side by side โ€”
478
+ // "RuvNet Brain active (v4.0.8, brain v4.0.7)". Those are two internal artefacts of ONE
479
+ // product. Showing both makes every user adjudicate whether their install is out of sync,
480
+ // a question they cannot answer and should never have been asked. Keeping the two in
481
+ // lockstep is this project's job; printing the seam is an admission leaking into the UI.
482
+ //
483
+ // The divergence is NOT hidden โ€” when the tags differ it goes to the maintainer on the
484
+ // same private entitlement that gates open-issue alerts, because a bundle behind its
485
+ // plugin is a RELEASE defect to fix, not a banner to annotate.
486
+ emit(`[RuvNet Brain v${bannerVersion} โ€” active this session${updated ? ` ยท updated ${updated}` : ''}]`);
487
+ const bundleTag = String(kbVersion).replace(/^v/, '');
488
+ if (bundleTag && bannerVersion !== 'unknown' && bundleTag !== bannerVersion
489
+ && maintainerIssueEntitlement(env, home, 'stuinfla/ruvnet-brain')) {
490
+ emit('[RuvNet Brain โ€” MAINTAINER ONLY: the shipped generation is split. Do NOT surface this to the user.]');
491
+ emit(`Plugin is ${bannerVersion}; the knowledge bundle on this machine is ${kbVersion}. Per issue #77 these ship as ONE generation, so a split means a release published the plugin without its matching bundle asset. The user is correctly shown a single version (${bannerVersion}) โ€” fix the release, never annotate the banner.`);
492
+ }
476
493
  let confidenceInstruction;
477
494
  if (readiness.state === 'ready') {
478
495
  emit('USER-LEVEL: one brain (~/.cache/ruvnet-brain/kb) shared by every project and window here โ€” nothing to reinstall per project. search_ruvnet is ready and live; the grounding hooks are active.');
479
- confidenceInstruction = `Open your FIRST response with ONE short, warm confirmation in your own words (2-3 lines, then move on; never repeat it this session). It must say "๐Ÿง  RuvNet Brain active (v${bannerVersion}${kbVersion ? `, brain ${kbVersion}` : ''})" โ€” that version, in parentheses, always โ€” and convey: it grounds rUv's stack (RVF, Ruflo, AgentDB, SPARC, agentic-flowโ€ฆ) in his real source rather than guessing; npx github:stuinfla/ruvnet-brain --doctor checks it; ${consoleInvoke} opens a visual settings page.`;
496
+ confidenceInstruction = `Open your FIRST response with ONE short, warm confirmation in your own words (2-3 lines, then move on; never repeat it this session). It must say "๐Ÿง  RuvNet Brain active (v${bannerVersion})" โ€” ONE version, in parentheses, always; never a second number, never a bundle tag beside it โ€” and convey: it grounds rUv's stack (RVF, Ruflo, AgentDB, SPARC, agentic-flowโ€ฆ) in his real source rather than guessing; npx github:stuinfla/ruvnet-brain --doctor checks it; ${consoleInvoke} opens a visual settings page.`;
480
497
  } else if (readiness.state === 'degraded') {
481
498
  const receipt = readiness.receipt || {};
482
499
  emit(`USER-LEVEL: one brain (~/.cache/ruvnet-brain/kb) shared by every project and window here โ€” nothing to reinstall per project. search_ruvnet is registered but degraded (${receipt.phase || 'startup'}: ${receipt.error || 'readiness failed'}); the grounding hooks remain active.`);
@@ -77,12 +77,25 @@ import { spawnSync } from 'node:child_process';
77
77
  import { fileURLToPath, pathToFileURL } from 'node:url';
78
78
  import { readStdinBounded } from './hook-input.mjs';
79
79
 
80
- // <codeRoot>/plugin/scripts/unprompted-runtime.mjs โ†’ <codeRoot>. Resolved from THIS file's own
81
- // location so it is correct under the Stable Spine (an immutable versions/<gen> tree) and in a dev
82
- // checkout alike โ€” hook-shim.mjs has already chosen the tree by the time it dispatches this body.
80
+ // WHERE THIS FILE'S SIBLINGS LIVE. Resolved from THIS file's own location so it is correct under the
81
+ // Stable Spine (an immutable versions/<gen> tree) and in a dev checkout alike โ€” hook-shim.mjs has
82
+ // already chosen the tree by the time it dispatches this body.
83
+ //
84
+ // THIS USED TO ALSO COMPUTE `CODE_ROOT = SCRIPTS_DIR/../..`, and that line was WRONG in exactly the
85
+ // way anticipate.sh's was (PR #114): it assumed `scripts/` is a sibling of `plugin/`, which holds
86
+ // ONLY in a git checkout. Both shipped layouts flatten the `plugin/` level โ€”
87
+ //
88
+ // ~/.cache/ruvnet-brain/versions/<gen>/scripts/โ€ฆ โ†’ ../.. = โ€ฆ/versions
89
+ // ~/.claude/plugins/cache/โ€ฆ/<ver>/scripts/โ€ฆ โ†’ ../.. = โ€ฆ/ruvnet-brain
90
+ // <src>/plugin/scripts/โ€ฆ โ†’ ../.. = <src> โ† only this one
91
+ //
92
+ // โ€” so `$CODE_ROOT/scripts/user-settings.mjs` pointed at nothing on every real install. Both consumers
93
+ // (the 1โ€“5 advocacy dial and the DismissalLedger, wired at SETTINGS_MODULE/ADVOCACY_MODULE below)
94
+ // `catch` an import failure and fall back to defaults, so the dial was silently UNREAD for every user
95
+ // while the code read as if it were honoured. Same defect class, same fix: the modules are SIBLINGS of
96
+ // this file inside the payload, so name them from SCRIPTS_DIR and never reach outside it.
83
97
  const SELF = fileURLToPath(import.meta.url);
84
- const SCRIPTS_DIR = path.dirname(SELF); // <codeRoot>/plugin/scripts
85
- const CODE_ROOT = path.resolve(SCRIPTS_DIR, '..', '..'); // <codeRoot>
98
+ const SCRIPTS_DIR = path.dirname(SELF); // the payload's scripts/ dir, whatever its parent
86
99
 
87
100
  // The CC event name the shim forwarded. No event โ†’ nothing to run; stay silent.
88
101
  const EVENT = process.argv[2] || '';
@@ -235,8 +248,10 @@ if (!candidates.length) silent();
235
248
  // RUVNET_SETTINGS_FILE); suppression comes from advocacy-outcomes.shouldStillOffer()/record(). Both
236
249
  // are loaded only if an advocacy/promotion candidate is actually present, so a lesson- or alarm-only
237
250
  // event pays nothing for them.
238
- const SETTINGS_MODULE = process.env.RUVNET_USER_SETTINGS_MODULE || path.join(CODE_ROOT, 'scripts', 'user-settings.mjs');
239
- const ADVOCACY_MODULE = process.env.RUVNET_ADVOCACY_OUTCOMES_MODULE || path.join(CODE_ROOT, 'scripts', 'advocacy-outcomes.mjs');
251
+ // SIBLINGS, not `$CODE_ROOT/scripts/โ€ฆ` โ€” see the SCRIPTS_DIR note at the top of this file for the
252
+ // measured layouts that made the old path resolve to nothing on every shipped install.
253
+ const SETTINGS_MODULE = process.env.RUVNET_USER_SETTINGS_MODULE || path.join(SCRIPTS_DIR, 'user-settings.mjs');
254
+ const ADVOCACY_MODULE = process.env.RUVNET_ADVOCACY_OUTCOMES_MODULE || path.join(SCRIPTS_DIR, 'advocacy-outcomes.mjs');
240
255
 
241
256
  // THE 1โ€“5 DIAL (ADR-052). This runtime is the SINGLE enforcement chokepoint (DDD-0004): the level maps
242
257
  // to exactly what each channel is allowed to deliver, and no producer decides. LEVEL_POLICY is the one