ruvnet-brain 4.0.12 → 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.
- package/README.md +3 -3
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +2 -2
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/scripts/advocacy-outcomes.mjs +808 -0
- package/plugin/scripts/anticipate.sh +80 -14
- package/plugin/scripts/capability-registry.mjs +994 -0
- package/plugin/scripts/codex-hook-wrapper.mjs +1 -0
- package/plugin/scripts/continuation-gate.mjs +129 -1
- package/plugin/scripts/gates.mjs +146 -0
- package/plugin/scripts/goal-match.mjs +398 -0
- package/plugin/scripts/hijack-ruvnet.sh +69 -1
- package/plugin/scripts/hook-registry.mjs +616 -0
- package/plugin/scripts/hook-shim.mjs +13 -2
- package/plugin/scripts/learning-enable.mjs +382 -0
- package/plugin/scripts/lesson-promote.mjs +262 -0
- package/plugin/scripts/lesson-provenance.mjs +43 -0
- package/plugin/scripts/lesson-store.mjs +67 -56
- package/plugin/scripts/memory-doctor.mjs +345 -0
- package/plugin/scripts/nightly-controller.mjs +98 -0
- package/plugin/scripts/runtime-preferences.mjs +18 -0
- package/plugin/scripts/unprompted-runtime.mjs +22 -7
- package/plugin/scripts/user-settings.mjs +672 -0
- package/plugin/skills/ruvnet-brain/SKILL.md +2 -2
- package/scripts/advocacy-outcomes.mjs +4 -808
- package/scripts/capability-registry.mjs +4 -876
- package/scripts/corpus-qa.mjs +44 -6
- package/scripts/doc-currency.mjs +30 -2
- package/scripts/gates.mjs +4 -146
- package/scripts/goal-match.mjs +4 -398
- package/scripts/hook-registry.mjs +4 -567
- package/scripts/issue-watch.mjs +108 -0
- package/scripts/learning-enable.mjs +4 -380
- package/scripts/lesson-promote.mjs +4 -262
- package/scripts/memory-doctor.mjs +4 -345
- package/scripts/nightly-controller.mjs +4 -66
- package/scripts/nightly-wrapper.sh +23 -1
- package/scripts/proactivity-metrics.mjs +8 -1
- package/scripts/qe/ux-suite.mjs +72 -1
- package/scripts/release-abort-stale.mjs +111 -0
- package/scripts/release-convergence-watchdog.mjs +119 -0
- package/scripts/release-transaction-provider.mjs +46 -6
- package/scripts/release-transaction.mjs +55 -17
- package/scripts/self-update.mjs +63 -10
- package/scripts/user-settings.mjs +4 -640
|
@@ -64,28 +64,67 @@ set +e
|
|
|
64
64
|
SELF_DIR=$(CDPATH='' cd -- "$(dirname -- "$0")" 2>/dev/null && pwd)
|
|
65
65
|
[ -n "$SELF_DIR" ] || exit 0
|
|
66
66
|
|
|
67
|
-
#
|
|
68
|
-
#
|
|
69
|
-
#
|
|
70
|
-
#
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
# WHERE THE THREE MODULES LIVE — resolved by PROBE, not by assertion (2026-08-04).
|
|
68
|
+
#
|
|
69
|
+
# This block used to be one line — `CODE_ROOT=$SELF_DIR/../..` — justified by the claim, repeated in
|
|
70
|
+
# the ADVOCACY_MODULE comment below, that a dev checkout and the Stable Spine "both keep `scripts/`
|
|
71
|
+
# as a sibling of `plugin/`". MEASURED on a real install, that is FALSE in both shipped layouts, and
|
|
72
|
+
# true only in the one layout that never reaches a user:
|
|
73
|
+
#
|
|
74
|
+
# <plugin-cache>/ruvnet-brain/4.0.7/scripts/anticipate.sh → ../.. = <plugin-cache>/ruvnet-brain
|
|
75
|
+
# ~/.cache/ruvnet-brain/versions/<gen>/scripts/anticipate.sh → ../.. = .../versions
|
|
76
|
+
# <src>/plugin/scripts/anticipate.sh → ../.. = <src> ← only this
|
|
77
|
+
#
|
|
78
|
+
# Both distribution channels FLATTEN the `plugin/` level, so `../..` overshoots by one directory and
|
|
79
|
+
# $CODE_ROOT/scripts/goal-match.mjs never existed. The `[ -f "$GOAL_MATCH" ] || exit 0` guard below
|
|
80
|
+
# then did exactly what it promises — it stayed silent — so the L4 surface shipped permanently and
|
|
81
|
+
# INVISIBLY inert. A hook whose only failure mode is silence cannot report its own breakage; that is
|
|
82
|
+
# precisely why this needs a probe and not a comment.
|
|
83
|
+
#
|
|
84
|
+
# THE FIX IS TO ASK THE FILESYSTEM. Try each candidate directory and take the first that actually
|
|
85
|
+
# holds the matcher. That is the same discipline the rest of this file already applies to the
|
|
86
|
+
# machine's state: never render an assumption as a fact. Candidates, in order:
|
|
87
|
+
#
|
|
88
|
+
# 1. $SELF_DIR — modules shipped as SIBLINGS of this script (the flattened plugin
|
|
89
|
+
# zip and the Stable Spine, once packaging ships them; see below)
|
|
90
|
+
# 2. $SELF_DIR/../../scripts — the source/dev layout <src>/plugin/scripts → <src>/scripts
|
|
91
|
+
# 3. $SELF_DIR/../scripts — a root that keeps scripts/ one level up from this file
|
|
92
|
+
#
|
|
93
|
+
# PACKAGING IS THE OTHER HALF, and neither half works alone. goal-match.mjs, capability-registry.mjs
|
|
94
|
+
# and advocacy-outcomes.mjs currently live ONLY in the repo-root `scripts/`, which the plugin zip
|
|
95
|
+
# does not carry; this resolver finds nothing until they are shipped into `plugin/scripts/` beside
|
|
96
|
+
# this file. Fixing the path without the packaging leaves it silent, and vice versa.
|
|
97
|
+
#
|
|
98
|
+
# If NO candidate holds the matcher we deliberately fall through to the historical path, so the
|
|
99
|
+
# "missing module" diagnostics below still name the location a maintainer would expect — and the
|
|
100
|
+
# no-node fast path keeps this hook free. Silence on doubt, never a guess: rule 4, unchanged.
|
|
101
|
+
resolve_module_dir() {
|
|
102
|
+
for _cand in "$SELF_DIR" "$SELF_DIR/../../scripts" "$SELF_DIR/../scripts"; do
|
|
103
|
+
_r=$(CDPATH='' cd -- "$_cand" 2>/dev/null && pwd) || continue
|
|
104
|
+
if [ -n "$_r" ] && [ -f "$_r/goal-match.mjs" ]; then printf '%s' "$_r"; return 0; fi
|
|
105
|
+
done
|
|
106
|
+
_r=$(CDPATH='' cd -- "$SELF_DIR/../.." 2>/dev/null && pwd) || return 1
|
|
107
|
+
[ -n "$_r" ] && printf '%s' "$_r/scripts"
|
|
108
|
+
}
|
|
109
|
+
MODULE_DIR=$(resolve_module_dir)
|
|
110
|
+
[ -n "$MODULE_DIR" ] || exit 0
|
|
73
111
|
|
|
74
112
|
# All THREE module paths are env-overridable, matching the RUVNET_LESSON_STORE / RUVNET_SETTINGS_FILE
|
|
75
113
|
# idiom already used across this repo — so tests never load the real registry or touch a real user's
|
|
76
114
|
# state, and a future relocation needs no edit here.
|
|
77
|
-
GOAL_MATCH="${RUVNET_GOAL_MATCH:-$
|
|
78
|
-
CAP_REGISTRY="${RUVNET_CAPABILITY_REGISTRY:-$
|
|
115
|
+
GOAL_MATCH="${RUVNET_GOAL_MATCH:-$MODULE_DIR/goal-match.mjs}"
|
|
116
|
+
CAP_REGISTRY="${RUVNET_CAPABILITY_REGISTRY:-$MODULE_DIR/capability-registry.mjs}"
|
|
79
117
|
# THE SINGLE SUPPRESSION POLICY (2026-07-23). Until this build this file decided "is X suppressed"
|
|
80
118
|
# with its OWN local dismissed-Set in anticipate-state.json — one dismissal muted forever, no
|
|
81
119
|
# severity, no budget — while advocacy-outcomes.mjs's shouldStillOffer()/DISMISSAL_BUDGET (a nag dies
|
|
82
120
|
# on 1 dismissal, a high-severity finding needs 3, with a state-change reprieve) sat completely
|
|
83
121
|
# uncalled. Two thresholds for one decision is the exact hazard named below for the confidence floor;
|
|
84
122
|
# the fix is the same shape — wire this module the IDENTICAL env-var-with-a-default way as the two
|
|
85
|
-
# above, NOT a hardcoded `../scripts` path, so it resolves
|
|
86
|
-
#
|
|
87
|
-
# sibling of `plugin
|
|
88
|
-
|
|
123
|
+
# above, NOT a hardcoded `../scripts` path, so it resolves wherever this file actually runs from.
|
|
124
|
+
# (CORRECTED 2026-08-04: this comment previously asserted that a dev checkout and the Spine "both
|
|
125
|
+
# keep `scripts/` as a sibling of `plugin/`". They do not — see the measured table above. The three
|
|
126
|
+
# modules now resolve through MODULE_DIR, which probes rather than assumes.)
|
|
127
|
+
ADVOCACY_MODULE="${RUVNET_ADVOCACY_OUTCOMES_MODULE:-$MODULE_DIR/advocacy-outcomes.mjs}"
|
|
89
128
|
|
|
90
129
|
# ── Subcommands (dismiss/undismiss/status) run the same node program in a different mode ─────────
|
|
91
130
|
MODE="suggest"
|
|
@@ -525,10 +564,37 @@ NODE_PID=$!
|
|
|
525
564
|
# 5s hook budget that ground-ruvnet.sh has already partly spent. A SIGKILL mid-write can at worst
|
|
526
565
|
# truncate one advisory line — it can never fail the turn, and the state file was already committed
|
|
527
566
|
# by then (see the persist-first ordering above).
|
|
528
|
-
|
|
567
|
+
# THE SLEEP MUST BE OURS TO KILL (2026-08-06). This block used to be:
|
|
568
|
+
#
|
|
569
|
+
# ( sleep 2; kill -9 "$NODE_PID" 2>/dev/null ) &
|
|
570
|
+
# WATCHDOG_PID=$!
|
|
571
|
+
# wait "$NODE_PID"; kill "$WATCHDOG_PID"
|
|
572
|
+
#
|
|
573
|
+
# `kill` signals the SUBSHELL. The `sleep` it forked is a separate process this script never had a
|
|
574
|
+
# handle on, so it was simply ORPHANED and kept running for the remainder of its 2 seconds.
|
|
575
|
+
# selfcheck.mjs measures exactly that (§5 PROCESS-TREE HYGIENE, WATCHDOG_GRACE_MS = 2000) and
|
|
576
|
+
# reported it in BOTH the [valid] and [held] regimes as
|
|
577
|
+
# "left descendants alive after SIGTERM to its process group".
|
|
578
|
+
#
|
|
579
|
+
# It is deterministic on Linux rather than flaky because the watchdog's lifetime and the grace
|
|
580
|
+
# window are the SAME 2000ms, and the sleep starts marginally after the clock the checker uses — so
|
|
581
|
+
# it always outlives the probe by the spawn delta. macOS passes; ubuntu fails every time.
|
|
582
|
+
#
|
|
583
|
+
# It had never fired before because it was UNREACHABLE. Until the payload boundary was fixed
|
|
584
|
+
# (ADR-065) the `[ -f "$GOAL_MATCH" ] || exit 0` guard above returned first on every real install, so
|
|
585
|
+
# this line only ever ran in a dev checkout. Making L4 work is what woke it up — the fix did not
|
|
586
|
+
# create this leak, it revealed one that had been shipping dormant.
|
|
587
|
+
#
|
|
588
|
+
# FIX: fork the sleep as OUR OWN child so we hold its pid, and reap both. A `trap` inside the
|
|
589
|
+
# subshell was tried first and MEASURED WORSE (it defeats the shell's exec optimisation and leaked
|
|
590
|
+
# where the original did not) — hence the explicit two-pid form rather than anything cleverer.
|
|
591
|
+
sleep 2 &
|
|
592
|
+
SLEEP_PID=$!
|
|
593
|
+
( wait "$SLEEP_PID" 2>/dev/null && kill -9 "$NODE_PID" 2>/dev/null ) >/dev/null 2>&1 &
|
|
529
594
|
WATCHDOG_PID=$!
|
|
530
595
|
wait "$NODE_PID" 2>/dev/null
|
|
531
|
-
kill "$WATCHDOG_PID" 2>/dev/null
|
|
596
|
+
kill "$SLEEP_PID" "$WATCHDOG_PID" 2>/dev/null
|
|
597
|
+
wait "$SLEEP_PID" "$WATCHDOG_PID" 2>/dev/null
|
|
532
598
|
|
|
533
599
|
# ALWAYS. Every failure above already routed to silence; this makes the guarantee unconditional.
|
|
534
600
|
exit 0
|