ruvnet-brain 4.7.20 → 4.7.21
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 +494 -97
- package/kb/download-retry.mjs +93 -21
- package/kb/forge-guard-injection.mjs +277 -0
- package/kb/forge-update.mjs +166 -38
- package/kb/lifecycle-evidence-retention.mjs +151 -14
- package/kb/model-requirements.mjs +4 -1
- package/kb/refresh-run.mjs +175 -27
- package/kb/verify-citation.mjs +15 -2
- package/package.json +3 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/mcp/managed-cli-interface.mjs +16 -8
- package/plugin/scripts/adr-currency-gate.mjs +2 -1
- package/plugin/scripts/advisory-contract.mjs +21 -0
- package/plugin/scripts/advocacy-route.mjs +5 -4
- package/plugin/scripts/agentdb-recall.mjs +15 -5
- package/plugin/scripts/automatic-update.mjs +9 -1
- package/plugin/scripts/brain-confirmation.mjs +2 -1
- package/plugin/scripts/brain-footprint.mjs +72 -11
- package/plugin/scripts/capability-registry.mjs +1 -1
- package/plugin/scripts/capacity-aware-parallel-work.mjs +2 -1
- package/plugin/scripts/codex-overnight-notice.mjs +33 -0
- package/plugin/scripts/completion-claim-evidence.mjs +56 -12
- package/plugin/scripts/continuation-gate.mjs +28 -9
- package/plugin/scripts/decision-gate.mjs +13 -63
- package/plugin/scripts/decision-outcomes.mjs +36 -0
- package/plugin/scripts/decision-recall-gate.mjs +40 -5
- package/plugin/scripts/decision-record.mjs +8 -3
- package/plugin/scripts/degradation-watch.mjs +2 -1
- package/plugin/scripts/developer-update-lock.mjs +172 -33
- package/plugin/scripts/developer-update-owner.mjs +8 -5
- package/plugin/scripts/developer-update-policy.mjs +4 -1
- package/plugin/scripts/developer-update.mjs +155 -53
- package/plugin/scripts/doc-currency.mjs +2 -16
- package/plugin/scripts/duplicate-gate.mjs +2 -1
- package/plugin/scripts/entrypoint.mjs +34 -0
- package/plugin/scripts/footprint-io.mjs +135 -8
- package/plugin/scripts/grok-hook-adapter.mjs +2 -1
- package/plugin/scripts/ground-ruvnet.sh +6 -3
- package/plugin/scripts/grounding-answer.mjs +2 -1
- package/plugin/scripts/grounding-code-projection.mjs +2 -1
- package/plugin/scripts/grounding-substance.mjs +2 -1
- package/plugin/scripts/grounding-turn-gate.mjs +2 -2
- package/plugin/scripts/grounding-turn-mark.mjs +2 -2
- package/plugin/scripts/hook-context-budget.mjs +2 -1
- package/plugin/scripts/hook-input.mjs +2 -2
- package/plugin/scripts/hook-shim.mjs +9 -2
- package/plugin/scripts/host-update.mjs +29 -5
- package/plugin/scripts/identifier-preflight.mjs +2 -1
- package/plugin/scripts/kb-copy-proof.mjs +57 -9
- package/plugin/scripts/learn-capture.mjs +2 -1
- package/plugin/scripts/learning-store.mjs +62 -16
- package/plugin/scripts/lesson-bridge.mjs +2 -2
- package/plugin/scripts/lesson-promote.mjs +83 -22
- package/plugin/scripts/md-stamp.mjs +2 -1
- package/plugin/scripts/native-turn-transcript.mjs +98 -6
- package/plugin/scripts/nightly-scheduler.mjs +10 -5
- package/plugin/scripts/package-recommender.mjs +2 -2
- package/plugin/scripts/project-store-resolver.mjs +19 -0
- package/plugin/scripts/routing-outcome-capture.mjs +2 -1
- package/plugin/scripts/session-snapshot-hook.mjs +24 -4
- package/plugin/scripts/session-start-core.mjs +5 -15
- package/plugin/scripts/session-start-health.mjs +97 -10
- package/plugin/scripts/session-start-issue-alert.mjs +63 -0
- package/plugin/scripts/session-start-update-plane.mjs +15 -1
- package/plugin/scripts/signal-watch.mjs +2 -1
- package/plugin/scripts/spend-guard.mjs +2 -1
- package/plugin/scripts/substitution-wall.mjs +2 -1
- package/plugin/scripts/turn-outcome-capture.mjs +7 -3
- package/plugin/scripts/unprompted-runtime.mjs +20 -3
- package/plugin/scripts/update-apply.mjs +186 -15
- package/plugin/skills/release-proof/scripts/release-proof.mjs +2 -1
- package/plugin/skills/ruvnet-brain/PLAYBOOK.md +2 -2
- package/plugin/skills/ruvnet-brain/SKILL.md +3 -2
- package/scripts/adr-072-completion.mjs +2 -1
- package/scripts/agentdb-context.mjs +2 -1
- package/scripts/agentdb-fleet-doctor.mjs +30 -8
- package/scripts/approved-runtime.mjs +2 -1
- package/scripts/architecture-review-lock.mjs +2 -1
- package/scripts/ascii-drift.mjs +2 -1
- package/scripts/brain-latency-50.mjs +2 -1
- package/scripts/brain-novice-50.mjs +2 -16
- package/scripts/brain-score.mjs +13 -2
- package/scripts/build-bundle.mjs +2 -1
- package/scripts/build-concepts.mjs +2 -1
- package/scripts/candidate-ci-receipt.mjs +2 -1
- package/scripts/candidate-host-evidence.mjs +2 -1
- package/scripts/card-from-source.mjs +2 -1
- package/scripts/ci/warm-brain-models.mjs +2 -1
- package/scripts/claims-verify.mjs +7 -3
- package/scripts/claude-controlled-terminal.mjs +2 -1
- package/scripts/claude-terminal-mod.mjs +2 -1
- package/scripts/code-release-corpus.mjs +2 -1
- package/scripts/codex-hook-trust-reconcile.mjs +67 -1
- package/scripts/codex-hook-trust.mjs +40 -1
- package/scripts/codex-hook-wrapper-history.mjs +2 -1
- package/scripts/codex-host-execution-proof.mjs +2 -1
- package/scripts/completion-claim-replay.mjs +2 -1
- package/scripts/console-engine.mjs +8 -3
- package/scripts/corpus-canary.mjs +2 -1
- package/scripts/corpus-candidate.mjs +2 -2
- package/scripts/corpus-coverage-sidecar.mjs +2 -1
- package/scripts/corpus-dispatch-decision.mjs +2 -1
- package/scripts/corpus-dispatch-receipt.mjs +2 -1
- package/scripts/corpus-next-seed.mjs +2 -1
- package/scripts/corpus-qa.mjs +2 -1
- package/scripts/corpus-reconcile.mjs +2 -2
- package/scripts/corpus-watchdog.mjs +2 -1
- package/scripts/count-chunks.mjs +2 -1
- package/scripts/customer-state-matrix.mjs +2 -1
- package/scripts/derive-passage-content-map.mjs +2 -1
- package/scripts/development-push-check.mjs +2 -1
- package/scripts/dispatch-receipt.mjs +2 -1
- package/scripts/doc-currency.mjs +2 -1
- package/scripts/dream-issue-gate.mjs +2 -1
- package/scripts/dual-host-deliberation.mjs +2 -16
- package/scripts/dual-host-suggest.mjs +2 -16
- package/scripts/eval-brain.mjs +7 -3
- package/scripts/execution-policy.mjs +2 -1
- package/scripts/execution-preflight.mjs +2 -1
- package/scripts/falsify.mjs +2 -1
- package/scripts/fix-metaharness-memretrieve.mjs +2 -1
- package/scripts/fix-workstream.mjs +2 -1
- package/scripts/full-hints.mjs +2 -1
- package/scripts/full-suite-gate.mjs +2 -1
- package/scripts/grok-host.mjs +68 -0
- package/scripts/hook-qualify-core.mjs +3 -1
- package/scripts/hook-qualify.mjs +2 -1
- package/scripts/hook-retirement-check.mjs +2 -1
- package/scripts/host-registry.mjs +2 -1
- package/scripts/independent-review-receipt.mjs +2 -1
- package/scripts/ingest-new-repos.mjs +2 -1
- package/scripts/ingest-repo.mjs +12 -2
- package/scripts/integration-evidence.mjs +2 -1
- package/scripts/issue-fix.mjs +7 -24
- package/scripts/issue-watch.mjs +116 -40
- package/scripts/job-heartbeat.sh +54 -19
- package/scripts/key-canary.mjs +9 -3
- package/scripts/latency-to-surface.mjs +2 -1
- package/scripts/learning-replay-cli.mjs +97 -19
- package/scripts/learning-replay-execution.mjs +2 -0
- package/scripts/learning-replay-fixture.mjs +3 -0
- package/scripts/learning-replay-proof.mjs +14 -13
- package/scripts/learning-replay.mjs +3 -3
- package/scripts/learnings.mjs +2 -1
- package/scripts/lesson-ratify.mjs +88 -40
- package/scripts/loop-checkpoint.mjs +2 -1
- package/scripts/metaharness-receipts.mjs +2 -1
- package/scripts/model-catalog.mjs +2 -1
- package/scripts/model-currency-evidence.mjs +6 -4
- package/scripts/model-currency.mjs +33 -3
- package/scripts/model-native-catalog.mjs +2 -1
- package/scripts/model-router-agent-hook.mjs +2 -1
- package/scripts/model-router-dispatch.mjs +2 -1
- package/scripts/model-router-engine.mjs +2 -1
- package/scripts/model-router-outcome.mjs +2 -1
- package/scripts/model-router-setup.mjs +2 -1
- package/scripts/model-routing-eval.mjs +2 -1
- package/scripts/model-routing-gateway.mjs +2 -1
- package/scripts/model-routing-launchers.mjs +4 -1
- package/scripts/model-terminal-gateway.mjs +2 -1
- package/scripts/model-terminal-launchers.mjs +2 -1
- package/scripts/model-weekly-analyst.mjs +2 -1
- package/scripts/model-weekly-cycle.mjs +2 -1
- package/scripts/model-weekly-qualification.mjs +2 -1
- package/scripts/nightly-gists.sh +26 -20
- package/scripts/nightly-two-run-proof.mjs +2 -1
- package/scripts/nightly-watchdog.mjs +158 -47
- package/scripts/no-silent-substitution.mjs +2 -1
- package/scripts/notify.sh +11 -6
- package/scripts/ntfy-inbox.mjs +41 -18
- package/scripts/onboarding-console.mjs +47 -8
- package/scripts/oracle/abstain-threshold-sweep.mjs +2 -1
- package/scripts/oracle/abstain-trace.mjs +2 -1
- package/scripts/oracle/doc2query-generate.mjs +2 -1
- package/scripts/oracle/doc2query-reach.mjs +2 -1
- package/scripts/oracle/judge-train.mjs +2 -1
- package/scripts/oracle/need-set-split.mjs +2 -1
- package/scripts/oracle/produce-questions.mjs +2 -16
- package/scripts/oracle/repo-recall.mjs +2 -2
- package/scripts/oracle/retrieval-accuracy.mjs +2 -2
- package/scripts/oracle/sona-query-adapter-eval.mjs +2 -1
- package/scripts/oracle/source-tree.mjs +2 -15
- package/scripts/oracle/source-units.mjs +2 -16
- package/scripts/oracle/spike-run.mjs +2 -16
- package/scripts/oracle/validate-labels.mjs +2 -16
- package/scripts/org-repo-count.mjs +2 -1
- package/scripts/package-cards.mjs +2 -1
- package/scripts/prepublication-evidence.mjs +2 -1
- package/scripts/private-overlay.mjs +2 -1
- package/scripts/product-integrity-contract.mjs +2 -1
- package/scripts/protected-release-invocation.mjs +2 -1
- package/scripts/public-verification-abandon.mjs +2 -1
- package/scripts/public-verification-aggregate.mjs +2 -1
- package/scripts/public-verification-finalizer.mjs +2 -1
- package/scripts/public-verification-inputs.mjs +2 -1
- package/scripts/public-verification-lane.mjs +2 -1
- package/scripts/publication-receipt.mjs +2 -1
- package/scripts/published-surface-probe.mjs +2 -1
- package/scripts/qe/card-lane-gate.mjs +2 -16
- package/scripts/qe/session-start-gate.mjs +2 -16
- package/scripts/qe/ux-suite.mjs +2 -1
- package/scripts/qualified-candidate-check.mjs +2 -1
- package/scripts/rebuild-gists-from-receipts.mjs +2 -1
- package/scripts/recommendation-eval.mjs +2 -1
- package/scripts/recommendation-floor.mjs +2 -1
- package/scripts/recommendation-judge-score.mjs +2 -1
- package/scripts/recommendation-real-host-score.mjs +2 -1
- package/scripts/recommendation-real-host.mjs +2 -1
- package/scripts/refresh-capability-only-store.mjs +2 -1
- package/scripts/refresh-model-catalog.mjs +2 -1
- package/scripts/rehearse-corpus-pipeline.mjs +2 -1
- package/scripts/release-authority.mjs +2 -1
- package/scripts/release-evidence-aggregate.mjs +2 -1
- package/scripts/release-payload.mjs +2 -1
- package/scripts/release-projection.mjs +2 -1
- package/scripts/release-proof.mjs +2 -1
- package/scripts/release-qualification-contract.mjs +64 -28
- package/scripts/release-qualification.mjs +8 -1
- package/scripts/release-vector.mjs +2 -1
- package/scripts/restore-local-ingests.mjs +2 -1
- package/scripts/retrieval-canary.mjs +2 -1
- package/scripts/route-cheap.mjs +2 -1
- package/scripts/route-gold-rank.mjs +2 -1
- package/scripts/route-index-memory.mjs +2 -1
- package/scripts/route-latency-warm.mjs +2 -1
- package/scripts/router-utilization.mjs +2 -1
- package/scripts/routing-flywheel.mjs +2 -1
- package/scripts/run-operational-benchmark.mjs +2 -1
- package/scripts/run-operational-benchmark.v3.mjs +2 -1
- package/scripts/rvf-index-audit.mjs +2 -16
- package/scripts/seal-gist-receipt.mjs +2 -1
- package/scripts/security-guidance-codex-compat.mjs +2 -1
- package/scripts/selfcheck.mjs +2 -1
- package/scripts/signal-watch.mjs +2 -1
- package/scripts/source-coverage.mjs +2 -1
- package/scripts/stabilization-receipt.mjs +2 -1
- package/scripts/stamp-sweep.mjs +2 -1
- package/scripts/status-honesty.mjs +2 -1
- package/scripts/sync-commands.mjs +2 -2
- package/scripts/top100-benchmark.mjs +2 -1
- package/scripts/top100-corpus.mjs +2 -1
- package/scripts/user-model-hook-install.mjs +2 -1
- package/scripts/user-model-prompt-hook.mjs +2 -1
- package/scripts/verify-bundle.mjs +3 -1
- package/scripts/verify-model-catalog.mjs +2 -1
- package/scripts/version.mjs +2 -1
- package/scripts/wired-check.mjs +11 -5
- package/scripts/worktree-integrity.mjs +2 -2
|
@@ -29,6 +29,7 @@ import fs from 'node:fs';
|
|
|
29
29
|
import path from 'node:path';
|
|
30
30
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
31
31
|
import { wilson, repoMatchesExpected } from './eval-brain.mjs';
|
|
32
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
32
33
|
|
|
33
34
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
34
35
|
|
|
@@ -151,6 +152,6 @@ async function main() {
|
|
|
151
152
|
console.log(JSON.stringify(brief, null, 1));
|
|
152
153
|
}
|
|
153
154
|
|
|
154
|
-
if (
|
|
155
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
155
156
|
await main();
|
|
156
157
|
}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import fs from 'node:fs';
|
|
14
14
|
import path from 'node:path';
|
|
15
15
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
16
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
16
17
|
|
|
17
18
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
18
19
|
const arg = (name) => { const i = process.argv.indexOf(name); return i >= 0 ? process.argv[i + 1] : undefined; };
|
|
@@ -48,4 +49,4 @@ async function main() {
|
|
|
48
49
|
console.log(JSON.stringify({ impl: rel.startsWith('..') ? '<impl>' : rel, kbBuild, stores: repos.length, coldMs, warmMs, retained: retained(before, after) }));
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
if (
|
|
52
|
+
if (isDirectInvocation(import.meta.url)) await main();
|
|
@@ -22,6 +22,7 @@ import fs from 'node:fs';
|
|
|
22
22
|
import os from 'node:os';
|
|
23
23
|
import path from 'node:path';
|
|
24
24
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
25
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
25
26
|
|
|
26
27
|
export const percentile = (xs, p) => {
|
|
27
28
|
const s = [...xs].sort((a, b) => a - b);
|
|
@@ -120,4 +121,4 @@ async function main() {
|
|
|
120
121
|
process.exit(0);
|
|
121
122
|
}
|
|
122
123
|
|
|
123
|
-
if (
|
|
124
|
+
if (isDirectInvocation(import.meta.url)) await main();
|
|
@@ -179,4 +179,5 @@ export function mainUtil() {
|
|
|
179
179
|
|
|
180
180
|
import { fileURLToPath } from 'node:url';
|
|
181
181
|
import path from 'node:path';
|
|
182
|
-
|
|
182
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
183
|
+
if (isDirectInvocation(import.meta.url)) mainUtil();
|
|
@@ -55,6 +55,7 @@ import {
|
|
|
55
55
|
import { effectivePrices, loadLabelledRows, OUTCOMES } from './metaharness-router.mjs';
|
|
56
56
|
import { assertEvolutionAllowed } from './metaharness-gate.mjs';
|
|
57
57
|
import { loadCatalog, applyProfile, loadProfile } from './model-router-engine.mjs';
|
|
58
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
58
59
|
|
|
59
60
|
// ─── HARD CAPS — the self-DDoS fence. Clamped, never raised by flags. ─────────────────────────────
|
|
60
61
|
export const HARD_MAX_GENERATIONS = 6;
|
|
@@ -599,7 +600,7 @@ async function main() {
|
|
|
599
600
|
}
|
|
600
601
|
}
|
|
601
602
|
|
|
602
|
-
if (
|
|
603
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
603
604
|
main().catch((e) => {
|
|
604
605
|
process.stderr.write(`routing-flywheel: ${e.stack || e.message}\n`);
|
|
605
606
|
process.exit(1);
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
latencyDistribution,
|
|
15
15
|
verifyFixtureSourceSupport,
|
|
16
16
|
} from '../evals/operational-benchmark.v2.mjs';
|
|
17
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
17
18
|
|
|
18
19
|
const execFileAsync = promisify(execFile);
|
|
19
20
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
@@ -146,6 +147,6 @@ async function main() {
|
|
|
146
147
|
if (report.passed !== report.total || report.unavailable.length) process.exitCode = 1;
|
|
147
148
|
}
|
|
148
149
|
|
|
149
|
-
if (
|
|
150
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
150
151
|
main().catch((error) => { console.error(error.stack || error.message); process.exitCode = 2; });
|
|
151
152
|
}
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
preflightOperationalOracle,
|
|
17
17
|
} from '../evals/operational-benchmark.v3.mjs';
|
|
18
18
|
import { verifyGrounding as evaluatorVerifyGrounding } from '../kb/verify-citation.mjs';
|
|
19
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
19
20
|
|
|
20
21
|
const execFileAsync = promisify(execFile);
|
|
21
22
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
@@ -189,6 +190,6 @@ async function main() {
|
|
|
189
190
|
if (!report.qualificationPass) process.exitCode = 1;
|
|
190
191
|
}
|
|
191
192
|
|
|
192
|
-
if (
|
|
193
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
193
194
|
main().catch((error) => { console.error(error.stack || error.message); process.exitCode = 2; });
|
|
194
195
|
}
|
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
writeRvfGeneration,
|
|
38
38
|
} from './rvf-generation.mjs';
|
|
39
39
|
import { metricFromId, readRvfStoredVectors } from './rvf-wire.mjs';
|
|
40
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
40
41
|
|
|
41
42
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
42
43
|
export const RVF_HNSW_THRESHOLD = 1024;
|
|
@@ -675,22 +676,7 @@ async function main() {
|
|
|
675
676
|
if (failed.length) process.exitCode = 1;
|
|
676
677
|
}
|
|
677
678
|
|
|
678
|
-
|
|
679
|
-
// NOT follow symlinks, while import.meta.url IS symlink-resolved by Node. Through a symlink (npm bin
|
|
680
|
-
// shims, wrapper scripts, and every os.tmpdir() path on macOS) the two sides disagree, so main()
|
|
681
|
-
// never runs -- and because nothing throws, the process exits 0. A silent exit 0 is indistinguishable
|
|
682
|
-
// from "ran, found nothing", which is how prepareCorpusCandidate once reported SUCCESS with no
|
|
683
|
-
// archive on disk. Reproduced live 2026-07-27; pinned by tests/unit/entrypoint-symlink.test.mjs.
|
|
684
|
-
function isDirectInvocation() {
|
|
685
|
-
try {
|
|
686
|
-
if (!process.argv[1]) return false;
|
|
687
|
-
return fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url));
|
|
688
|
-
} catch {
|
|
689
|
-
return false;
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
if (isDirectInvocation()) {
|
|
679
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
694
680
|
main().catch((error) => {
|
|
695
681
|
console.error(error.stack || error.message);
|
|
696
682
|
process.exitCode = 1;
|
|
@@ -13,6 +13,7 @@ import fs from 'node:fs';
|
|
|
13
13
|
import { fileURLToPath } from 'node:url';
|
|
14
14
|
import { observeSourceUniverse } from './source-coverage.mjs';
|
|
15
15
|
import { buildGistAggregate } from './gist-receipts.mjs';
|
|
16
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
16
17
|
|
|
17
18
|
export const REPO_KB = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'kb');
|
|
18
19
|
|
|
@@ -57,7 +58,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
57
58
|
return 0;
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
if (
|
|
61
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
61
62
|
main().then((code) => { process.exitCode = code; }).catch((error) => {
|
|
62
63
|
console.error(`[seal-gist-receipt] ${error.message}`);
|
|
63
64
|
process.exitCode = 1;
|
|
@@ -14,6 +14,7 @@ import path from 'node:path';
|
|
|
14
14
|
import os from 'node:os';
|
|
15
15
|
import crypto from 'node:crypto';
|
|
16
16
|
import { fileURLToPath } from 'node:url';
|
|
17
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
17
18
|
|
|
18
19
|
export const COMPATIBILITY = Object.freeze({
|
|
19
20
|
version: '2.0.9', nativeContract: 'Codex 0.160.0 PostToolUse',
|
|
@@ -128,7 +129,7 @@ export function repairSecurityGuidance({ codexHome = process.env.CODEX_HOME || p
|
|
|
128
129
|
return { ...receipt, status: 'patched', backup, patchedSha256: sha256(readRegular(target).bytes) };
|
|
129
130
|
}
|
|
130
131
|
|
|
131
|
-
if (
|
|
132
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
132
133
|
try {
|
|
133
134
|
const args = process.argv.slice(2);
|
|
134
135
|
let codexHome; let apply = false;
|
package/scripts/selfcheck.mjs
CHANGED
|
@@ -67,6 +67,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
67
67
|
// THE canonical continuity policy — the same module bin/install.mjs and scripts/hook-retirement-check.mjs
|
|
68
68
|
// import. Never re-implement this predicate locally; see the note below the imports.
|
|
69
69
|
import { isAllowedContinuityRegistration } from '../plugin/scripts/continuity-hook-policy.mjs';
|
|
70
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
70
71
|
|
|
71
72
|
// ── contract constants (ADR-053 §2.5 / §2.3) ────────────────────────────────────────────────────
|
|
72
73
|
export const STDOUT_CAP_BYTES = 4096; // it lands in the user's context window
|
|
@@ -739,7 +740,7 @@ export function formatVerdict(result, { color = null } = {}) {
|
|
|
739
740
|
}
|
|
740
741
|
|
|
741
742
|
// ── CLI ─────────────────────────────────────────────────────────────────────────────────────────
|
|
742
|
-
if (
|
|
743
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
743
744
|
const noSecurity = process.argv.includes('--no-security');
|
|
744
745
|
const json = process.argv.includes('--json');
|
|
745
746
|
const result = await selfCheck({ security: !noSecurity });
|
package/scripts/signal-watch.mjs
CHANGED
|
@@ -47,6 +47,7 @@ import os from 'node:os';
|
|
|
47
47
|
import { spawnSync } from 'node:child_process';
|
|
48
48
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
49
49
|
import { assessCiGate } from './ci-verdict.mjs';
|
|
50
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
50
51
|
|
|
51
52
|
const BRAIN_HOME = process.env.RUVNET_BRAIN_HOME || path.join(os.homedir(), '.cache', 'ruvnet-brain');
|
|
52
53
|
const SIGNAL_DIR = process.env.RUVNET_SIGNAL_DIR || path.join(BRAIN_HOME, 'external-signals');
|
|
@@ -164,7 +165,7 @@ function main() {
|
|
|
164
165
|
}
|
|
165
166
|
|
|
166
167
|
function isMain() {
|
|
167
|
-
try { return
|
|
168
|
+
try { return isDirectInvocation(import.meta.url); }
|
|
168
169
|
catch { return false; }
|
|
169
170
|
}
|
|
170
171
|
|
|
@@ -10,6 +10,7 @@ import { canonicalJson, coverageGenerationFor, digest, validateGistAggregateRece
|
|
|
10
10
|
import { repositoryNames } from '../kb/card-lane.mjs';
|
|
11
11
|
import { rootNeverMaterialized, storeRoot } from '../kb/store-root.mjs';
|
|
12
12
|
import { isTransientText, retryTransient, sleepSync } from './transient-gh.mjs';
|
|
13
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
13
14
|
|
|
14
15
|
export { canonicalJson, digest } from './coverage-integrity.mjs';
|
|
15
16
|
|
|
@@ -759,6 +760,6 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
759
760
|
return 0;
|
|
760
761
|
}
|
|
761
762
|
|
|
762
|
-
if (
|
|
763
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
763
764
|
process.exitCode = await main();
|
|
764
765
|
}
|
|
@@ -8,6 +8,7 @@ import path from 'node:path';
|
|
|
8
8
|
import { spawnSync } from 'node:child_process';
|
|
9
9
|
import { pathToFileURL } from 'node:url';
|
|
10
10
|
import { evaluateStabilizationCandidateReceipt } from './release-proof.mjs';
|
|
11
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
11
12
|
|
|
12
13
|
const readJson = (file) => JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
13
14
|
const sha256 = (file) => crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex');
|
|
@@ -115,4 +116,4 @@ export function main(args = process.argv.slice(2)) {
|
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
if (
|
|
119
|
+
if (isDirectInvocation(import.meta.url)) process.exitCode = main();
|
package/scripts/stamp-sweep.mjs
CHANGED
|
@@ -39,6 +39,7 @@ import path from 'node:path';
|
|
|
39
39
|
import { spawnSync } from 'node:child_process';
|
|
40
40
|
import { fileURLToPath } from 'node:url';
|
|
41
41
|
import { ensureStamp, hasStamp, stampInsertionPoint } from '../plugin/scripts/md-stamp.mjs';
|
|
42
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
42
43
|
|
|
43
44
|
const HERE = path.dirname(fileURLToPath(import.meta.url));
|
|
44
45
|
export const REPO_ROOT = path.resolve(HERE, '..');
|
|
@@ -137,7 +138,7 @@ function main() {
|
|
|
137
138
|
}
|
|
138
139
|
|
|
139
140
|
function isMain() {
|
|
140
|
-
try { return
|
|
141
|
+
try { return isDirectInvocation(import.meta.url); }
|
|
141
142
|
catch { return false; }
|
|
142
143
|
}
|
|
143
144
|
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
import fs from 'node:fs';
|
|
29
29
|
import path from 'node:path';
|
|
30
30
|
import { fileURLToPath } from 'node:url';
|
|
31
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
31
32
|
|
|
32
33
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
33
34
|
|
|
@@ -115,7 +116,7 @@ export function scanRepo(root = ROOT) {
|
|
|
115
116
|
return out;
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
if (
|
|
119
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
119
120
|
const bad = scanRepo();
|
|
120
121
|
if (bad.length) {
|
|
121
122
|
console.error('status-honesty: ASSERTED (underived) terminal success literals found:\n');
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
import fs from 'node:fs';
|
|
35
35
|
import path from 'node:path';
|
|
36
36
|
import { fileURLToPath } from 'node:url';
|
|
37
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
37
38
|
|
|
38
39
|
const ROOT = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
|
|
39
40
|
const DIR = path.join(ROOT, 'plugin', 'commands');
|
|
@@ -76,8 +77,7 @@ function rebuild(aliasText, canonicalFrontmatter, canonicalBody) {
|
|
|
76
77
|
// able to crash the caller that merely imported this module: not-resolvable means not-main.
|
|
77
78
|
function resolvedIsMain() {
|
|
78
79
|
try {
|
|
79
|
-
return
|
|
80
|
-
&& fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url));
|
|
80
|
+
return isDirectInvocation(import.meta.url);
|
|
81
81
|
} catch { return false; }
|
|
82
82
|
}
|
|
83
83
|
if (!resolvedIsMain()) { /* imported for its exports — do nothing else */ } else {
|
|
@@ -10,6 +10,7 @@ import { performance } from 'node:perf_hooks';
|
|
|
10
10
|
import { createHash } from 'node:crypto';
|
|
11
11
|
import { execFileSync } from 'node:child_process';
|
|
12
12
|
import { pathToFileURL, fileURLToPath } from 'node:url';
|
|
13
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
13
14
|
|
|
14
15
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
15
16
|
const CORPUS = path.join(ROOT, 'evals', 'top-100.json');
|
|
@@ -476,4 +477,4 @@ Use --out when a durable evidence artifact is intentional; release checks are pu
|
|
|
476
477
|
});
|
|
477
478
|
}
|
|
478
479
|
|
|
479
|
-
if (
|
|
480
|
+
if (isDirectInvocation(import.meta.url)) await main();
|
|
@@ -5,6 +5,7 @@ import path from 'node:path';
|
|
|
5
5
|
import { createHash } from 'node:crypto';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { semanticAssertionsFor } from './top100-semantic-assertions.mjs';
|
|
8
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
8
9
|
|
|
9
10
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
10
11
|
const HELD_OUT = path.join(ROOT, 'evals', 'held-out.json');
|
|
@@ -105,7 +106,7 @@ export function corpusHash(corpus) {
|
|
|
105
106
|
return createHash('sha256').update(JSON.stringify(corpus.questions)).digest('hex');
|
|
106
107
|
}
|
|
107
108
|
|
|
108
|
-
if (
|
|
109
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
109
110
|
const corpus = buildTop100();
|
|
110
111
|
fs.writeFileSync(OUT, JSON.stringify({ ...corpus, sha256: corpusHash(corpus) }, null, 2) + '\n');
|
|
111
112
|
console.log(`${OUT}: ${corpus.questions.length} questions, sha256=${corpusHash(corpus)}`);
|
|
@@ -5,6 +5,7 @@ import path from 'node:path';
|
|
|
5
5
|
import os from 'node:os';
|
|
6
6
|
import crypto from 'node:crypto';
|
|
7
7
|
import { pathToFileURL } from 'node:url';
|
|
8
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
8
9
|
|
|
9
10
|
export function shellQuote(value) { return `'${value.replaceAll("'", "'\\''")}'`; }
|
|
10
11
|
|
|
@@ -134,7 +135,7 @@ export function applyUserModelHooks(plan) {
|
|
|
134
135
|
return { applied: true, written };
|
|
135
136
|
}
|
|
136
137
|
|
|
137
|
-
if (
|
|
138
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
138
139
|
try {
|
|
139
140
|
const args = process.argv.slice(2);
|
|
140
141
|
if (args.some(arg => !['--apply', '--dry-run', '--plan'].includes(arg))) throw new Error('Usage: user-model-hook-install.mjs [--apply|--dry-run|--plan]');
|
|
@@ -8,6 +8,7 @@ import os from 'node:os';
|
|
|
8
8
|
import { spawnSync } from 'node:child_process';
|
|
9
9
|
import { pathToFileURL } from 'node:url';
|
|
10
10
|
import { weeklyCycleStatus } from './model-weekly-cycle.mjs';
|
|
11
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
11
12
|
|
|
12
13
|
export const PRESENTATION = 'For terminal briefings: give concise executive status; use narrow padded ASCII tables with borders, plain cell text, aligned columns and short rows. Never send pipe-delimited Markdown tables to this terminal. Use short lists when a table would wrap. Do not flood the response with commands or technical logs.';
|
|
13
14
|
|
|
@@ -65,6 +66,6 @@ async function main() {
|
|
|
65
66
|
process.stdout.write(JSON.stringify(envelope(promptContext(payload))) + '\n');
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
if (
|
|
69
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
69
70
|
main().catch(() => process.stdout.write(JSON.stringify(envelope(PRESENTATION)) + '\n'));
|
|
70
71
|
}
|
|
@@ -42,7 +42,9 @@ export function verifyBundle(bundlePath, sigPath = `${bundlePath}.sig`, pubPath
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
// CLI
|
|
45
|
-
|
|
45
|
+
// Copied ALONE into every brain bundle (scripts/build-bundle.mjs), so it cannot import
|
|
46
|
+
// plugin/scripts/entrypoint.mjs; this is that helper's comparison, inline: real paths on both sides.
|
|
47
|
+
if ((() => { try { return Boolean(process.argv[1]) && fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url)); } catch { return false; } })()) {
|
|
46
48
|
const [bundle, sig] = process.argv.slice(2);
|
|
47
49
|
if (!bundle) { console.error('Usage: node scripts/verify-bundle.mjs <bundle.zip> [<bundle.zip.sig>]'); process.exit(2); }
|
|
48
50
|
const r = verifyBundle(bundle, sig);
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
import fs from 'node:fs';
|
|
16
16
|
import path from 'node:path';
|
|
17
17
|
import { fileURLToPath } from 'node:url';
|
|
18
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
18
19
|
|
|
19
20
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
20
21
|
const ROOT = path.resolve(__dirname, '..');
|
|
@@ -99,6 +100,6 @@ export async function main(argv = process.argv) {
|
|
|
99
100
|
console.log(`✓ model-catalog VERIFIED: ${r.checked} model facts match the ${live ? 'LIVE OpenRouter' : 'committed snapshot'} catalog (pulled ${source.pulledAt}, ${r.ageDays.toFixed(1)}d old ≤ 14d).`);
|
|
100
101
|
}
|
|
101
102
|
|
|
102
|
-
if (
|
|
103
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
103
104
|
main().catch((e) => { console.error('verify-model-catalog error:', e.message); process.exit(1); });
|
|
104
105
|
}
|
package/scripts/version.mjs
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import fs from 'node:fs';
|
|
7
7
|
import path from 'node:path';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
9
10
|
|
|
10
11
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
11
12
|
export const PLUGIN_JSON = path.join(ROOT, 'plugin', '.claude-plugin', 'plugin.json');
|
|
@@ -35,6 +36,6 @@ export function getVersionTag() {
|
|
|
35
36
|
export const stripTag = (v) => String(v).replace(/^v/, '');
|
|
36
37
|
|
|
37
38
|
// CLI: `node scripts/version.mjs` prints the version (handy for shell scripts).
|
|
38
|
-
if (
|
|
39
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
39
40
|
process.stdout.write(getVersion() + '\n');
|
|
40
41
|
}
|
package/scripts/wired-check.mjs
CHANGED
|
@@ -172,8 +172,8 @@ const STANDALONE = [
|
|
|
172
172
|
// plist's own ProgramArguments on 2026-07-23, not assumed from the header comment alone:
|
|
173
173
|
['clear-claude-tmp', 'launchd, every 3h (out-of-repo scheduler) — confirmed live: '
|
|
174
174
|
+ 'com.stuartkerr.clear-claude-tmp.plist is loaded and its ProgramArguments invoke this exact file'],
|
|
175
|
-
['nightly-gists', '
|
|
176
|
-
+ 'com.ruvnet.brain-gists
|
|
175
|
+
['nightly-gists', 'manual re-embed of the developer checkout gists store (the launchd job '
|
|
176
|
+
+ 'com.ruvnet.brain-gists was retired 2026-10-26: no installed brain reads that store)'],
|
|
177
177
|
['nightly-wrapper', 'author-run maintenance harness, deliberately unscheduled; refuses primary, nested, and dirty worktrees'],
|
|
178
178
|
['routing-flywheel', 'launchd nightly 04:45 --dry-run (out-of-repo scheduler) — confirmed live: '
|
|
179
179
|
+ 'com.ruvnet.routing-flywheel.plist is loaded and its ProgramArguments invoke this exact file'],
|
|
@@ -409,13 +409,13 @@ export const REQUIRED_OPERATIONAL_EXPORTS = [
|
|
|
409
409
|
const isTestFile = (f) => /\.(test|spec)\.(mjs|js)$/.test(path.basename(f))
|
|
410
410
|
|| f.includes(`${path.sep}tests${path.sep}`) || f.startsWith(`tests${path.sep}`);
|
|
411
411
|
|
|
412
|
-
function walk(abs, recurse, out = []) {
|
|
412
|
+
function walk(abs, recurse, out = [], prune = () => false) {
|
|
413
413
|
let entries = [];
|
|
414
414
|
try { entries = fs.readdirSync(abs, { withFileTypes: true }); } catch { return out; }
|
|
415
415
|
for (const e of entries) {
|
|
416
416
|
const full = path.join(abs, e.name);
|
|
417
417
|
if (e.isDirectory()) {
|
|
418
|
-
if (recurse && e.name !== 'node_modules' && !e.name.startsWith('.')) walk(full, recurse, out);
|
|
418
|
+
if (recurse && e.name !== 'node_modules' && !e.name.startsWith('.') && !prune(full)) walk(full, recurse, out, prune);
|
|
419
419
|
} else out.push(full);
|
|
420
420
|
}
|
|
421
421
|
return out;
|
|
@@ -451,7 +451,10 @@ function callerFiles(repo = REPO) {
|
|
|
451
451
|
// wired into pre-push and `wired-check` went on reporting it `manual`. This file's own note names
|
|
452
452
|
// the remedy: "an invoker outside the roots proves the ROOTS are incomplete — the fix is to add
|
|
453
453
|
// the root, never to" special-case the module. Same rule, applied to the extension filter.
|
|
454
|
-
|
|
454
|
+
// Pruned BEFORE descending (see the worktrees note below): 100+ agent worktrees under .claude/ are full
|
|
455
|
+
// repository copies, and walking them only to drop every file afterwards dominated this audit's run time.
|
|
456
|
+
const worktrees = path.join(repo, '.claude', 'worktrees');
|
|
457
|
+
for (const f of walk(abs, true, [], (dir) => dir === worktrees)) {
|
|
455
458
|
// `.claude/` is a caller root because `.claude/settings.json` genuinely invokes hooks. But
|
|
456
459
|
// `.claude/worktrees/<agent>/` holds FULL COPIES of this repository (Claude Code agent
|
|
457
460
|
// worktrees), and a copy of the repo is not a caller of the repo. Measured 2026-09-11: with any
|
|
@@ -634,6 +637,9 @@ export function callersOf(mod, files, repo = REPO, sourceCache = createInvocatio
|
|
|
634
637
|
const rel = path.relative(repo, f).split(path.sep).join('/');
|
|
635
638
|
if (rel === mod.rel) continue; // self
|
|
636
639
|
if (isTestFile(rel)) continue; // a test is not a caller
|
|
640
|
+
// Cheap substring pre-filter: callerPattern() only ever matches text that contains the literal file
|
|
641
|
+
// name, so skipping the regex when the name is absent cannot change the result, only its cost.
|
|
642
|
+
if (!sourceCache.read(f)?.includes(mod.file)) continue;
|
|
637
643
|
const src = sourceCache.commentFree(f);
|
|
638
644
|
if (src !== null && re.test(src)) hits.push(rel);
|
|
639
645
|
}
|
|
@@ -12,6 +12,7 @@ import path from 'node:path';
|
|
|
12
12
|
import crypto from 'node:crypto';
|
|
13
13
|
import { spawnSync } from 'node:child_process';
|
|
14
14
|
import { fileURLToPath } from 'node:url';
|
|
15
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
15
16
|
|
|
16
17
|
function git(cwd, args) {
|
|
17
18
|
const result = spawnSync('git', ['-C', cwd, ...args], { encoding: 'utf8' });
|
|
@@ -101,8 +102,7 @@ export function assertPrimaryCheckoutUnchanged(root, before) {
|
|
|
101
102
|
return after;
|
|
102
103
|
}
|
|
103
104
|
|
|
104
|
-
const invokedDirectly =
|
|
105
|
-
&& fs.realpathSync(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
105
|
+
const invokedDirectly = isDirectInvocation(import.meta.url);
|
|
106
106
|
if (invokedDirectly) {
|
|
107
107
|
try {
|
|
108
108
|
const command = process.argv[2];
|