ruvnet-brain 4.7.20 → 4.7.22
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 +618 -104
- package/console/activity.js +122 -38
- 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-process.mjs +115 -5
- package/plugin/scripts/agentdb-recall-reader.mjs +44 -2
- package/plugin/scripts/agentdb-recall.mjs +49 -17
- 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 +241 -23
- package/plugin/scripts/continuation-gate.mjs +75 -11
- 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-gate.mjs +7 -39
- package/plugin/scripts/lesson-promote.mjs +83 -22
- package/plugin/scripts/lesson-scope.mjs +51 -0
- package/plugin/scripts/lesson-store.mjs +1 -1
- 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/ruflo-bin.mjs +14 -6
- package/plugin/scripts/ruflo-memory-hooks.mjs +157 -19
- package/plugin/scripts/session-snapshot-hook.mjs +25 -5
- package/plugin/scripts/session-start-core.mjs +7 -16
- package/plugin/scripts/session-start-health.mjs +98 -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-boot-surface-proof.mjs +208 -0
- 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 +123 -23
- 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/recall-latency-probe.mjs +48 -0
- 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 +82 -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 +13 -5
- package/scripts/worktree-integrity.mjs +2 -2
package/scripts/corpus-qa.mjs
CHANGED
|
@@ -50,6 +50,7 @@ import path from 'node:path';
|
|
|
50
50
|
import readline from 'node:readline';
|
|
51
51
|
import { fileURLToPath } from 'node:url';
|
|
52
52
|
import { FULL_HINTS } from './full-hints.mjs';
|
|
53
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
53
54
|
|
|
54
55
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
55
56
|
const KB = path.join(ROOT, 'kb');
|
|
@@ -245,7 +246,7 @@ export function discoverStores(dir) {
|
|
|
245
246
|
}
|
|
246
247
|
|
|
247
248
|
// ---------------- CLI ----------------
|
|
248
|
-
if (import.meta.url
|
|
249
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
249
250
|
const arg = (f, d) => { const i = process.argv.indexOf(f); return i >= 0 && process.argv[i + 1] ? process.argv[i + 1] : d; };
|
|
250
251
|
const has = (f) => process.argv.includes(f);
|
|
251
252
|
const DIR = path.resolve(arg('--dir', KB));
|
|
@@ -26,6 +26,7 @@ import { captureGistSources } from './gist-receipts.mjs';
|
|
|
26
26
|
import { projectSourceStore, RUNTIME_LEDGER_KIND } from './rvf-generation.mjs';
|
|
27
27
|
import { compareKnowledgeInputs, fromCoverage as knowledgeFromCoverage, fromSeed as knowledgeFromSeed } from './knowledge-input-digest.mjs';
|
|
28
28
|
import { defaultBaseDelayMs } from './transient-gh.mjs';
|
|
29
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
29
30
|
|
|
30
31
|
export { rebuildCorpusAggregates };
|
|
31
32
|
|
|
@@ -1306,8 +1307,7 @@ export async function main(argv = process.argv.slice(2), {
|
|
|
1306
1307
|
// with no archive and no receipt on disk. Same defect, same fix as plugin/scripts/hook-input.mjs:518.
|
|
1307
1308
|
function isMain() {
|
|
1308
1309
|
try {
|
|
1309
|
-
|
|
1310
|
-
return fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url));
|
|
1310
|
+
return isDirectInvocation(import.meta.url);
|
|
1311
1311
|
} catch {
|
|
1312
1312
|
return false;
|
|
1313
1313
|
}
|
|
@@ -48,6 +48,7 @@ import { AGGREGATE_ASSET, SIGNING_PUBLIC_KEY_FILE } from './approved-runtime.mjs
|
|
|
48
48
|
import { COVERAGE_ASSET, COVERAGE_RECEIPT_ASSET, verifyCoverageSidecar } from './corpus-coverage-sidecar.mjs';
|
|
49
49
|
import { parseCorpusGeneration } from './corpus-promotion.mjs';
|
|
50
50
|
import { retryTransientResult } from './transient-gh.mjs';
|
|
51
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
51
52
|
|
|
52
53
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
53
54
|
export const RED = 'RED';
|
|
@@ -496,6 +497,6 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
496
497
|
return result.verdict === RED ? 1 : 0;
|
|
497
498
|
}
|
|
498
499
|
|
|
499
|
-
if (
|
|
500
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
500
501
|
main().then((code) => { process.exitCode = code; });
|
|
501
502
|
}
|
package/scripts/count-chunks.mjs
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
import path from 'node:path';
|
|
24
24
|
import { fileURLToPath } from 'node:url';
|
|
25
25
|
import { applyFix } from './claims-verify.mjs';
|
|
26
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
26
27
|
|
|
27
28
|
const CHECK = process.argv.includes('--check');
|
|
28
29
|
|
|
@@ -49,6 +50,6 @@ async function main() {
|
|
|
49
50
|
console.log(`\n[count-chunks] done — ${want} chunks is the live count; ${drifted.length} surface(s) rewritten.`);
|
|
50
51
|
}
|
|
51
52
|
|
|
52
|
-
if (
|
|
53
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
53
54
|
await main();
|
|
54
55
|
}
|
|
@@ -34,6 +34,7 @@ import { customerEnv, customerManifestUrl, installCustomer, installedModules } f
|
|
|
34
34
|
import { addPrivateStore, resolveRuntime } from './customer-seams.mjs';
|
|
35
35
|
export { resolveRuntime };
|
|
36
36
|
import { doctorSmokeArgs } from './installed-brain-health.mjs';
|
|
37
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
37
38
|
|
|
38
39
|
export const REPO = 'stuinfla/ruvnet-brain';
|
|
39
40
|
const readJson = (file) => JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
@@ -358,6 +359,6 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
358
359
|
return 0;
|
|
359
360
|
}
|
|
360
361
|
|
|
361
|
-
if (
|
|
362
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
362
363
|
main().then((code) => { process.exitCode = code; }, (error) => { console.error(error.stack || error.message); process.exitCode = 1; });
|
|
363
364
|
}
|
|
@@ -16,6 +16,7 @@ import { spawnSync } from 'node:child_process';
|
|
|
16
16
|
import { fileURLToPath } from 'node:url';
|
|
17
17
|
import { digest } from './coverage-integrity.mjs';
|
|
18
18
|
import { CONTENT_MAP_FILE, CONTENT_MAP_KIND, passageContentDigest } from './retrieval-passage-identity.mjs';
|
|
19
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
19
20
|
|
|
20
21
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
21
22
|
const sha256File = (file) => crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex');
|
|
@@ -68,4 +69,4 @@ function main(argv) {
|
|
|
68
69
|
console.log(JSON.stringify({ out, resolved: Object.keys(map.entries).length, unresolved: map.unresolved.length }));
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
if (
|
|
72
|
+
if (isDirectInvocation(import.meta.url)) main(process.argv.slice(2));
|
|
@@ -5,6 +5,7 @@ import fs from 'node:fs';
|
|
|
5
5
|
import { execFileSync } from 'node:child_process';
|
|
6
6
|
import path from 'node:path';
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
|
8
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
8
9
|
|
|
9
10
|
export function inspectPush(root, input) {
|
|
10
11
|
const checked = [];
|
|
@@ -27,7 +28,7 @@ export function inspectPush(root, input) {
|
|
|
27
28
|
return { ok: true, checked, scope: 'unpublished-commit-secret-scan' };
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
if (
|
|
31
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
31
32
|
try {
|
|
32
33
|
const root = execFileSync('git', ['rev-parse', '--show-toplevel'], { encoding: 'utf8' }).trim();
|
|
33
34
|
console.log(JSON.stringify(inspectPush(root, fs.readFileSync(0, 'utf8'))));
|
|
@@ -26,6 +26,7 @@ import fs from 'node:fs';
|
|
|
26
26
|
import path from 'node:path';
|
|
27
27
|
import { pathToFileURL } from 'node:url';
|
|
28
28
|
import { CLAUDE_MODEL_IDS, CLAUDE_TIERS, PRICING, estTokens, estimateCosts, receiptLine, receiptsPath, priceOf } from './route-cheap.mjs';
|
|
29
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
29
30
|
|
|
30
31
|
// Default input share when only a MEASURED TOTAL is known. A subagent's tokens are dominated by input
|
|
31
32
|
// (it re-reads files and tool output on every turn); its final report is small. 0.9 is an assumption,
|
|
@@ -109,4 +110,4 @@ function main() {
|
|
|
109
110
|
console.log(receiptLine(receipt.model, { cost: receipt.est_cost, frontier: receipt.est_frontier_cost, saved: receipt.saved, ref: receipt.inherited }));
|
|
110
111
|
}
|
|
111
112
|
|
|
112
|
-
if (
|
|
113
|
+
if (isDirectInvocation(import.meta.url)) main();
|
package/scripts/doc-currency.mjs
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
import fs from 'node:fs';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
5
|
import { main } from '../plugin/scripts/doc-currency.mjs';
|
|
6
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
6
7
|
export * from '../plugin/scripts/doc-currency.mjs';
|
|
7
8
|
let direct = false;
|
|
8
|
-
try { direct =
|
|
9
|
+
try { direct = isDirectInvocation(import.meta.url); } catch {}
|
|
9
10
|
if (direct) process.exit(main());
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// the caller supplies the finding and the current open issues, and receives a disposition before
|
|
6
6
|
// invoking any GitHub write operation.
|
|
7
7
|
|
|
8
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
8
9
|
const HEX_SHA = /^[0-9a-f]{7,64}$/i;
|
|
9
10
|
const ISSUE_MARKER = 'dream-fingerprint:';
|
|
10
11
|
|
|
@@ -98,7 +99,7 @@ export function buildIssueBody(finding, decision = assessFinding(finding)) {
|
|
|
98
99
|
// Adapter contract for the Dream Machine runner. Input is JSON on stdin:
|
|
99
100
|
// { "finding": { ... }, "openIssues": [{ "number", "title", "body" }] }
|
|
100
101
|
// Output is the disposition JSON. This command intentionally cannot create or mutate GitHub data.
|
|
101
|
-
if (
|
|
102
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
102
103
|
let input = '';
|
|
103
104
|
process.stdin.setEncoding('utf8');
|
|
104
105
|
process.stdin.on('data', (chunk) => { input += chunk; });
|
|
@@ -6,6 +6,7 @@ import { spawn } from 'node:child_process';
|
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { probeSubscriptionHosts, subscriptionOnlyEnv } from './subscription-hosts.mjs';
|
|
8
8
|
import { DUAL_HOST_MODEL_IDS } from './review-model-defaults.mjs';
|
|
9
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
9
10
|
|
|
10
11
|
const HOSTS = Object.freeze(['claude-code', 'codex']);
|
|
11
12
|
// Top subscription models verified on the native hosts on 2026-09-10.
|
|
@@ -322,21 +323,6 @@ export async function main(argv = process.argv.slice(2), {
|
|
|
322
323
|
}
|
|
323
324
|
}
|
|
324
325
|
|
|
325
|
-
|
|
326
|
-
// NOT follow symlinks, while import.meta.url IS symlink-resolved by Node. Through a symlink (npm bin
|
|
327
|
-
// shims, wrapper scripts, and every os.tmpdir() path on macOS) the two sides disagree, so main()
|
|
328
|
-
// never runs -- and because nothing throws, the process exits 0. A silent exit 0 is indistinguishable
|
|
329
|
-
// from "ran, found nothing", which is how prepareCorpusCandidate once reported SUCCESS with no
|
|
330
|
-
// archive on disk. Reproduced live 2026-07-27; pinned by tests/unit/entrypoint-symlink.test.mjs.
|
|
331
|
-
function isDirectInvocation() {
|
|
332
|
-
try {
|
|
333
|
-
if (!process.argv[1]) return false;
|
|
334
|
-
return fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url));
|
|
335
|
-
} catch {
|
|
336
|
-
return false;
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
if (isDirectInvocation()) {
|
|
326
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
341
327
|
process.exitCode = await main();
|
|
342
328
|
}
|
|
@@ -4,6 +4,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
4
4
|
import fs from 'node:fs';
|
|
5
5
|
import { hardProblem } from './dual-host-deliberation.mjs';
|
|
6
6
|
import { probeSubscriptionHosts } from './subscription-hosts.mjs';
|
|
7
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
7
8
|
|
|
8
9
|
const HOSTS = Object.freeze([
|
|
9
10
|
['claude', 'claude-code'],
|
|
@@ -54,21 +55,6 @@ export function main(argv = process.argv.slice(2), {
|
|
|
54
55
|
return 0;
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
// NOT follow symlinks, while import.meta.url IS symlink-resolved by Node. Through a symlink (npm bin
|
|
59
|
-
// shims, wrapper scripts, and every os.tmpdir() path on macOS) the two sides disagree, so main()
|
|
60
|
-
// never runs -- and because nothing throws, the process exits 0. A silent exit 0 is indistinguishable
|
|
61
|
-
// from "ran, found nothing", which is how prepareCorpusCandidate once reported SUCCESS with no
|
|
62
|
-
// archive on disk. Reproduced live 2026-07-27; pinned by tests/unit/entrypoint-symlink.test.mjs.
|
|
63
|
-
function isDirectInvocation() {
|
|
64
|
-
try {
|
|
65
|
-
if (!process.argv[1]) return false;
|
|
66
|
-
return fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url));
|
|
67
|
-
} catch {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (isDirectInvocation()) {
|
|
58
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
73
59
|
process.exitCode = main();
|
|
74
60
|
}
|
package/scripts/eval-brain.mjs
CHANGED
|
@@ -32,6 +32,7 @@ import os from 'node:os';
|
|
|
32
32
|
import path from 'node:path';
|
|
33
33
|
import { spawnSync } from 'node:child_process';
|
|
34
34
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
35
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
35
36
|
|
|
36
37
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
37
38
|
const KB = process.env.RUVNET_BRAIN_KB || path.join(os.homedir(), '.cache', 'ruvnet-brain', 'kb');
|
|
@@ -91,8 +92,11 @@ export function gradeQuestion(q, { grounded, citations, bannerPresent, receipt,
|
|
|
91
92
|
return { grounded, routed: null, abstained, pass: abstained };
|
|
92
93
|
case 'provenance':
|
|
93
94
|
// The mechanism under test: IF a gist chunk wins, it must carry its own status banner.
|
|
94
|
-
// A better hit from the real repo is not a failure — it is better grounding.
|
|
95
|
-
|
|
95
|
+
// A better hit from the real repo is not a failure — it is better grounding. "Wins" means
|
|
96
|
+
// the citation verify-citation.mjs actually resolved (`routedRepo`, the same signal `routed`
|
|
97
|
+
// uses below) — not merely the raw top-ranked citation, which citationResolves() can walk
|
|
98
|
+
// past when it is unverified/fabricated (the sibling gap already closed for `routed`).
|
|
99
|
+
return { grounded, routed: null, abstained, pass: !!grounded && !abstained && (routedRepo !== 'ruv-gists' || bannerPresent) };
|
|
96
100
|
default:
|
|
97
101
|
// Abstention is correct only for the adversarial stratum. A negative cross-encoder score on
|
|
98
102
|
// an answerable question is an answer miss, even when an unrelated existing path resolves.
|
|
@@ -279,6 +283,6 @@ async function main() {
|
|
|
279
283
|
}
|
|
280
284
|
}
|
|
281
285
|
|
|
282
|
-
if (
|
|
286
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
283
287
|
await main();
|
|
284
288
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// One deterministic boundary between Brain knowledge and consequential execution.
|
|
3
3
|
// This module is deliberately pure: it never loads credentials, calls a provider, or mutates state.
|
|
4
4
|
|
|
5
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
5
6
|
const NATIVE_HOSTS = new Set(['claude', 'codex']);
|
|
6
7
|
const API_EXECUTORS = new Set(['agent_execute', 'sdk', 'openrouter', 'api']);
|
|
7
8
|
const ACTIONS = new Set(['read', 'write', 'delegate', 'release', 'external']);
|
|
@@ -111,7 +112,7 @@ export function classifyExecutionPolicy(input = {}) {
|
|
|
111
112
|
};
|
|
112
113
|
}
|
|
113
114
|
|
|
114
|
-
if (import.meta.url
|
|
115
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
115
116
|
const raw = process.argv[2] || '{}';
|
|
116
117
|
let input;
|
|
117
118
|
try { input = JSON.parse(raw); } catch { process.stderr.write('execution-policy: input must be JSON\n'); process.exit(2); }
|
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
// live Brain search and exact project AgentDB retrieval; prose, memory, and guessed host state do
|
|
4
4
|
// not satisfy this command.
|
|
5
5
|
import { classifyExecutionPolicy } from './execution-policy.mjs';
|
|
6
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
6
7
|
|
|
7
8
|
export function runExecutionPreflight(input = {}) {
|
|
8
9
|
return classifyExecutionPolicy({ ...input, enforceEvidence: true });
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
if (import.meta.url
|
|
12
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
12
13
|
let input;
|
|
13
14
|
try { input = JSON.parse(process.argv[2] || '{}'); }
|
|
14
15
|
catch { process.stderr.write('execution-preflight: input must be JSON\n'); process.exit(2); }
|
package/scripts/falsify.mjs
CHANGED
|
@@ -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 { resolveRuflo, RUFLO_MISSING } from '../plugin/scripts/ruflo-bin.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
|
const sh = (cmd, args) => spawnSync(cmd, args, { cwd: ROOT, encoding: 'utf8' });
|
|
@@ -238,4 +239,4 @@ function main() {
|
|
|
238
239
|
process.exit(0);
|
|
239
240
|
}
|
|
240
241
|
|
|
241
|
-
if (
|
|
242
|
+
if (isDirectInvocation(import.meta.url)) main();
|
|
@@ -28,6 +28,7 @@ import fs from 'node:fs';
|
|
|
28
28
|
import path from 'node:path';
|
|
29
29
|
import os from 'node:os';
|
|
30
30
|
import { pathToFileURL } from 'node:url';
|
|
31
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
31
32
|
|
|
32
33
|
const TARGET_DIR =
|
|
33
34
|
process.env.METAHARNESS_SCRIPTS_DIR ||
|
|
@@ -113,7 +114,7 @@ export function check(dir = TARGET_DIR, log = console.log) {
|
|
|
113
114
|
// Only act when run directly, so tests can import the pure functions above.
|
|
114
115
|
// Compare in URL space (pathToFileURL), not by decoding a URL into a path: `new URL(...).pathname`
|
|
115
116
|
// yields "/D:/..." on Windows and never matches, so `--apply` would silently no-op there.
|
|
116
|
-
const invokedDirectly =
|
|
117
|
+
const invokedDirectly = isDirectInvocation(import.meta.url);
|
|
117
118
|
if (invokedDirectly) {
|
|
118
119
|
const mode = process.argv.includes('--check') ? 'check' : 'apply';
|
|
119
120
|
console.log(`metaharness memRetrieve ${mode} — ${TARGET_DIR}\n`);
|
|
@@ -7,6 +7,7 @@ import { spawnSync } from 'node:child_process';
|
|
|
7
7
|
import fs from 'node:fs';
|
|
8
8
|
import path from 'node:path';
|
|
9
9
|
import { pathToFileURL } from 'node:url';
|
|
10
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
10
11
|
|
|
11
12
|
const FULL_SHA = /^[a-f0-9]{40}$/i;
|
|
12
13
|
const SCOPED_BRANCH = /^(fix|bugfix|hotfix|issue|codex)\/[A-Za-z0-9][A-Za-z0-9._/-]*$/;
|
|
@@ -288,4 +289,4 @@ export function main(args = process.argv.slice(2)) {
|
|
|
288
289
|
}
|
|
289
290
|
}
|
|
290
291
|
|
|
291
|
-
if (
|
|
292
|
+
if (isDirectInvocation(import.meta.url)) process.exitCode = main();
|
package/scripts/full-hints.mjs
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
// v2/crates — without --keep v2 those repos index almost nothing (open-claude-code: 68 passages
|
|
17
17
|
// total) and their FULL_HINTS can never match.
|
|
18
18
|
|
|
19
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
19
20
|
export const FULL_HINTS = {
|
|
20
21
|
'ruflo': 'v3/@claude-flow,v3/mcp,ruflo/src',
|
|
21
22
|
'synthlang': 'proxy/src/cli/synthlang,proxy/src/app/synthlang',
|
|
@@ -81,7 +82,7 @@ export const KEEP_DIRS = {
|
|
|
81
82
|
};
|
|
82
83
|
|
|
83
84
|
// CLI helper so shell drivers can read the config: node scripts/full-hints.mjs <kb-name>
|
|
84
|
-
if (import.meta.url
|
|
85
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
85
86
|
const kb = (process.argv[2] || '').toLowerCase();
|
|
86
87
|
console.log(JSON.stringify({ full: FULL_HINTS[kb] || null, keep: KEEP_DIRS[kb] || null }));
|
|
87
88
|
}
|
|
@@ -17,6 +17,7 @@ import os from 'node:os';
|
|
|
17
17
|
import path from 'node:path';
|
|
18
18
|
import { spawnSync } from 'node:child_process';
|
|
19
19
|
import { fileURLToPath } from 'node:url';
|
|
20
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
20
21
|
|
|
21
22
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
22
23
|
const key = (file, name) => `${file} :: ${name}`;
|
|
@@ -132,7 +133,7 @@ export function summaryMarkdown(result) {
|
|
|
132
133
|
].join('\n');
|
|
133
134
|
}
|
|
134
135
|
|
|
135
|
-
if (
|
|
136
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
136
137
|
const args = process.argv.slice(2);
|
|
137
138
|
const value = (flag) => { const i = args.indexOf(flag); return i < 0 ? null : args[i + 1]; };
|
|
138
139
|
const out = value('--report') || path.join(os.tmpdir(), `full-suite-${process.pid}.json`);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grok CLI status for the installer summary and `--doctor` (#301).
|
|
3
|
+
*
|
|
4
|
+
* Grok has no install step of its own: it discovers the Claude Code plugin (measured with
|
|
5
|
+
* `grok inspect --json` on grok 1.0.58: plugin ruvnet-brain, 10 skills, its MCP server, and the
|
|
6
|
+
* hook file plugin/hooks/grok-hooks.json selected by plugin/.grok-plugin/plugin.json). Grok
|
|
7
|
+
* discards an allowing UserPromptSubmit hook's context (~/.grok/docs/user-guide/10-hooks.md), so the
|
|
8
|
+
* prompt-time "search first" directive never reaches its model; a line in ~/.grok/AGENTS.md (loaded
|
|
9
|
+
* as a global rule — same inspect run) is what makes Grok ground itself. That line is OPT-IN only.
|
|
10
|
+
*/
|
|
11
|
+
import fs from 'node:fs';
|
|
12
|
+
import os from 'node:os';
|
|
13
|
+
import path from 'node:path';
|
|
14
|
+
|
|
15
|
+
export const GROK_MD_START = '<!-- ruvnet-brain:start -->';
|
|
16
|
+
export const GROK_MD_END = '<!-- ruvnet-brain:end -->';
|
|
17
|
+
export const GROK_AGENTS_LINE = 'For anything about the RuvNet / rUv stack (Ruflo, RuVector/RVF, AgentDB, agentic-flow, and the rest), '
|
|
18
|
+
+ 'call the `search_ruvnet` MCP tool first and cite the source paths it returns. Do not answer from memory. '
|
|
19
|
+
+ 'If it fails, say so and run `npx ruvnet-brain --doctor`.';
|
|
20
|
+
export const GROK_AGENTS_BLOCK = `${GROK_MD_START}\n${GROK_AGENTS_LINE}\n${GROK_MD_END}`;
|
|
21
|
+
|
|
22
|
+
export function grokPaths(home = os.homedir()) {
|
|
23
|
+
const bin = path.join(home, '.grok', 'bin');
|
|
24
|
+
return { bin: [path.join(bin, 'grok'), path.join(bin, 'grok.exe')], agents: path.join(home, '.grok', 'AGENTS.md') };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** What is true about Grok on this machine. Never runs grok; reads files only. */
|
|
28
|
+
export function grokStatus({ home = os.homedir(), pluginInstalled = false, hookCount = null } = {}) {
|
|
29
|
+
const p = grokPaths(home);
|
|
30
|
+
const present = p.bin.some((file) => fs.existsSync(file));
|
|
31
|
+
let agentsText = '';
|
|
32
|
+
try { agentsText = fs.readFileSync(p.agents, 'utf8'); } catch { /* absent */ }
|
|
33
|
+
return { present, pluginInstalled: Boolean(pluginInstalled), hookCount, agentsFile: p.agents,
|
|
34
|
+
groundingLine: /search_ruvnet/.test(agentsText) };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** One honest line: what reaches Grok, and whether the grounding line is there. null when no Grok. */
|
|
38
|
+
export function grokStatusLine(s) {
|
|
39
|
+
if (!s.present) return null;
|
|
40
|
+
if (!s.pluginInstalled) {
|
|
41
|
+
return 'Grok CLI detected — the Brain reaches Grok only through the Claude Code plugin, which is not installed here (run npx ruvnet-brain).';
|
|
42
|
+
}
|
|
43
|
+
const hooks = Number.isInteger(s.hookCount) ? `${s.hookCount} lifecycle hooks` : 'its lifecycle hooks';
|
|
44
|
+
return `Grok CLI detected — search_ruvnet, the Brain skills and ${hooks} (grok-hooks.json) load from the Claude Code plugin. `
|
|
45
|
+
+ 'Grok drops prompt-time context, so grounding relies on a search-first line in ~/.grok/AGENTS.md: '
|
|
46
|
+
+ (s.groundingLine ? 'present.' : 'absent (opt in: npx ruvnet-brain --grok-agents-md).');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Add the search-first line to ~/.grok/AGENTS.md ONLY if no search_ruvnet line is there already.
|
|
51
|
+
* Marker-wrapped (removed by --uninstall), backed up, written atomically. Returns
|
|
52
|
+
* 'added' | 'present' | 'no-grok' | 'failed'.
|
|
53
|
+
*/
|
|
54
|
+
export function addGrokAgentsLine({ home = os.homedir(), now = new Date() } = {}) {
|
|
55
|
+
const s = grokStatus({ home });
|
|
56
|
+
if (!s.present) return 'no-grok';
|
|
57
|
+
if (s.groundingLine) return 'present';
|
|
58
|
+
const file = s.agentsFile;
|
|
59
|
+
try {
|
|
60
|
+
const existing = fs.existsSync(file) ? fs.readFileSync(file, 'utf8') : '';
|
|
61
|
+
if (existing) fs.copyFileSync(file, `${file}.bak-${now.toISOString().replace(/[:.]/g, '-')}`);
|
|
62
|
+
const next = existing ? `${existing.replace(/\s*$/, '')}\n\n${GROK_AGENTS_BLOCK}\n` : `${GROK_AGENTS_BLOCK}\n`;
|
|
63
|
+
const tmp = `${file}.ruvnet-tmp`;
|
|
64
|
+
fs.writeFileSync(tmp, next);
|
|
65
|
+
fs.renameSync(tmp, file);
|
|
66
|
+
return 'added';
|
|
67
|
+
} catch { return 'failed'; }
|
|
68
|
+
}
|
|
@@ -127,7 +127,9 @@ export function makeWorld(host, { root = REPO, label = 'qual' } = {}) {
|
|
|
127
127
|
}
|
|
128
128
|
export function worldEnv(w, extra = {}) {
|
|
129
129
|
const env = {};
|
|
130
|
-
|
|
130
|
+
// RUVNET_STOP_NUDGES is forwarded: with it stripped, a qualification run under `full` never executed the
|
|
131
|
+
// hooks that hook-shim.mjs runs only in that mode (grounding-turn-gate exited 0 unrun and "qualified").
|
|
132
|
+
for (const k of ['PATH', 'LANG', 'LC_ALL', 'SHELL', 'USER', 'RUVNET_STOP_NUDGES']) if (process.env[k] !== undefined) env[k] = process.env[k];
|
|
131
133
|
env.PATH = `${path.dirname(process.execPath)}${path.delimiter}${env.PATH || '/usr/bin:/bin'}`;
|
|
132
134
|
Object.assign(env, { HOME: w.home, USERPROFILE: w.home, TMPDIR: w.tmp, CLAUDE_PROJECT_DIR: w.cwd, RUVNET_BRAIN_HOME: path.join(w.home, '.cache', 'ruvnet-brain') });
|
|
133
135
|
if (w.host === 'codex') env.CODEX_HOME = path.join(w.home, '.codex');
|
package/scripts/hook-qualify.mjs
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
CASES, HOSTS, auditWrites, fixturesFor, measureInjection, registrations, runCase, runConcurrent, runRepeat,
|
|
18
18
|
sandboxAvailable, staticFindings,
|
|
19
19
|
} from './hook-qualify-core.mjs';
|
|
20
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
20
21
|
|
|
21
22
|
function arg(name, dflt = null) {
|
|
22
23
|
const i = process.argv.indexOf(`--${name}`);
|
|
@@ -98,4 +99,4 @@ async function main() {
|
|
|
98
99
|
return rows.every((r) => r.pass) ? 0 : 1;
|
|
99
100
|
}
|
|
100
101
|
|
|
101
|
-
if (
|
|
102
|
+
if (isDirectInvocation(import.meta.url)) main().then((c) => process.exit(c), (e) => { console.error(e); process.exit(2); });
|
|
@@ -3,6 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { automaticHookRetirementStatus } from '../bin/install.mjs';
|
|
5
5
|
import { continuityRegistrations } from '../plugin/scripts/continuity-hook-policy.mjs';
|
|
6
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
6
7
|
|
|
7
8
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
8
9
|
|
|
@@ -24,6 +25,6 @@ export function main() {
|
|
|
24
25
|
return 0;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
if (
|
|
28
|
+
if (isDirectInvocation(import.meta.url)) {
|
|
28
29
|
process.exitCode = main();
|
|
29
30
|
}
|
|
@@ -5,6 +5,7 @@ import path from 'node:path';
|
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
6
|
import { canonicalJson, digest } from './coverage-integrity.mjs';
|
|
7
7
|
import { HOST_MODES, MODE_HOSTS } from './host-install-matrix.mjs';
|
|
8
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
8
9
|
|
|
9
10
|
export const HOST_ADAPTER_FILES = Object.freeze([
|
|
10
11
|
'plugin/host-adapters/claude.json',
|
|
@@ -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();
|
|
@@ -6,6 +6,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
6
6
|
import { canonicalJson, digest } from './coverage-integrity.mjs';
|
|
7
7
|
import { transactionIdFor } from './release-transaction.mjs';
|
|
8
8
|
import { CLAUDE_FABLE_5_ID, GPT_5_6_SOL_ID, LEGACY_REVIEWER_IDENTITIES } from './review-model-defaults.mjs';
|
|
9
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
9
10
|
const HEX40 = /^[a-f0-9]{40}$/;
|
|
10
11
|
const HEX64 = /^[a-f0-9]{64}$/;
|
|
11
12
|
const BASE64 = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
|
@@ -495,4 +496,4 @@ export function main(args = process.argv.slice(2), runtime = {}) {
|
|
|
495
496
|
}
|
|
496
497
|
}
|
|
497
498
|
|
|
498
|
-
if (
|
|
499
|
+
if (isDirectInvocation(import.meta.url)) process.exitCode = main();
|
|
@@ -35,6 +35,7 @@ import path from 'node:path';
|
|
|
35
35
|
import { fileURLToPath } from 'node:url';
|
|
36
36
|
import { storeRoot, storesAt, darkStores } from '../kb/store-root.mjs';
|
|
37
37
|
import { assertIsolatedMutationWorktree } from './worktree-integrity.mjs';
|
|
38
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
38
39
|
|
|
39
40
|
const ROOT = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
|
|
40
41
|
const OWNER = process.env.RUVNET_ORG_OWNER || 'ruvnet';
|
|
@@ -77,7 +78,7 @@ export function pendingRepos(orgRepos, root = storeRoot()) {
|
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
const isMain = (() => {
|
|
80
|
-
try { return
|
|
81
|
+
try { return isDirectInvocation(import.meta.url); }
|
|
81
82
|
catch { return false; }
|
|
82
83
|
})();
|
|
83
84
|
|
package/scripts/ingest-repo.mjs
CHANGED
|
@@ -21,6 +21,7 @@ import { execFileSync } from 'node:child_process';
|
|
|
21
21
|
import { fileURLToPath } from 'node:url';
|
|
22
22
|
import { FULL_HINTS, KEEP_DIRS } from './full-hints.mjs';
|
|
23
23
|
import { storeRoot } from '../kb/store-root.mjs';
|
|
24
|
+
import { repositoryNames } from '../kb/card-lane.mjs';
|
|
24
25
|
import { applyPrivateOverlay } from './private-overlay.mjs';
|
|
25
26
|
|
|
26
27
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
@@ -103,11 +104,20 @@ const ok = fs.existsSync(path.join(KB, `${kb}.big.rvf`))
|
|
|
103
104
|
// cannot reach it. 26 of 66 stores are in exactly that state. The 2026-08-12 incident (three repos
|
|
104
105
|
// ingested, all reporting success, none findable) was read as a path bug; the path was only half of
|
|
105
106
|
// it. A store with no card is BUILT AND DARK, and saying "searchable" of it is the product lying.
|
|
107
|
+
// ALIAS-AWARE, BECAUSE THE ROUTER IS (kb/store-root.mjs's darkStores(), same fix). A raw heading
|
|
108
|
+
// match against `kb` alone reports DARK for a store only reachable through an alias card — e.g.
|
|
109
|
+
// `metaharness` is built as `metaharness.big.rvf` but described under `## agent-harness-generator`.
|
|
110
|
+
// That exact false positive once caused a DUPLICATE `## metaharness` card to be hand-added, which
|
|
111
|
+
// collided with the alias card and broke routing outright (see kb/store-root.mjs's own account).
|
|
112
|
+
// This CLI is where a user/agent decides whether to write a new card off this message, so it is
|
|
113
|
+
// the highest-leverage place to get alias resolution right.
|
|
106
114
|
const carded = (() => {
|
|
115
|
+
let headings;
|
|
107
116
|
try {
|
|
108
|
-
|
|
109
|
-
|
|
117
|
+
const raw = fs.readFileSync(path.join(KB, 'capability-cards.md'), 'utf8');
|
|
118
|
+
headings = [...raw.matchAll(/^##\s+(\S+)\s*$/gm)].map((m) => m[1].toLowerCase());
|
|
110
119
|
} catch { return false; }
|
|
120
|
+
return repositoryNames(kb, KB).some((name) => headings.includes(String(name).toLowerCase()));
|
|
111
121
|
})();
|
|
112
122
|
// AN ARTIFACT WITH NO COMMITTED RECIPE IS NOT DURABLE WORK — it is a local side effect with a
|
|
113
123
|
// countdown on it. Proven overnight 2026-08-13 -> 08-14: a scheduled bundle apply extracted an
|
|
@@ -4,6 +4,7 @@ import { validateQualificationReceipt } from './release-qualification.mjs';
|
|
|
4
4
|
import fs from 'node:fs';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import { isDirectInvocation } from '../plugin/scripts/entrypoint.mjs';
|
|
7
8
|
|
|
8
9
|
export const EXCLUSION_POLICY = 'release-linux-v1';
|
|
9
10
|
|
|
@@ -67,7 +68,7 @@ export function buildQualifiedIntegrationEvidence(report, identity) {
|
|
|
67
68
|
qualificationReceiptSha256: report.receiptSha256, requirements: report.requirements };
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
const isCli =
|
|
71
|
+
const isCli = isDirectInvocation(import.meta.url);
|
|
71
72
|
if (isCli) {
|
|
72
73
|
const value = (name) => process.argv[process.argv.indexOf(name) + 1];
|
|
73
74
|
const build = process.argv.includes('--qualified') ? buildQualifiedIntegrationEvidence : buildIntegrationEvidence;
|