diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad8ac6da8..e312571e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,6 +17,22 @@ env: CARGO_INCREMENTAL: 0 jobs: + workspace-membership: + name: Workspace membership guard + runs-on: ubuntu-22.04 + timeout-minutes: 10 + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + with: + submodules: recursive + + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: '20' + + - name: Check crates/ for orphan crates (PIR #859) + run: node scripts/workspace-check.mjs + fmt: name: Rustfmt runs-on: ubuntu-22.04 diff --git a/Cargo.lock b/Cargo.lock index e236a6244..51b1fb884 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8935,6 +8935,14 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "ruvector-bet4-ivf-bench" +version = "0.1.0" +dependencies = [ + "rand 0.8.6", + "ruvector-rairs", +] + [[package]] name = "ruvector-bounded-rag" version = "2.3.0" @@ -10729,6 +10737,13 @@ dependencies = [ name = "ruvector-temporal-tensor" version = "2.3.0" +[[package]] +name = "ruvector-temporal-tensor-wasm" +version = "2.3.0" +dependencies = [ + "ruvector-temporal-tensor", +] + [[package]] name = "ruvector-timesfm" version = "2.2.4" diff --git a/Cargo.toml b/Cargo.toml index e6b63ed17..8ec3937c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,28 @@ exclude = ["external/ruqu", "external/rvdna", "examples/OSpipe", "examples/rvf", # rvforge-reader: Tauri v2 desktop app (ADR-289). Standalone workspace — # the webview/bundler dependency graph and its feature unification are # app-specific and would be paid for by every `cargo build --workspace`. - "crates/rvforge-reader"] + "crates/rvforge-reader", + # agentic-robotics family: excluded: does not build — see #859. The six + # crates were authored against a different workspace root: they inherit + # workspace.package keys this root does not define (description, homepage, + # documentation, keywords, categories), reference workspace deps this root + # does not declare (zenoh, rustdds, cdr, hdrhistogram), and pin internal + # path deps at 0.1.x while version.workspace would make them 2.3.0 — + # cargo metadata fails at manifest parse before any code is compiled. + "crates/agentic-robotics-core", + "crates/agentic-robotics-rt", + "crates/agentic-robotics-embedded", + "crates/agentic-robotics-mcp", + "crates/agentic-robotics-node", + "crates/agentic-robotics-benchmarks", + # excluded: does not build — see #859. 51 compile errors: API drift + # against ruvector-attention 2.x plus a missing bincode dependency. + "crates/ruvector-attention-cli", + # excluded: does not build — see #859. 11 compile errors: API drift + # against ruvector-sparse-inference (SparseModel is now an enum without + # forward_embedding/sparsity_statistics/encode; serde derives were + # dropped from InferenceConfig/ModelMetadata). + "crates/ruvector-sparse-inference-wasm"] members = [ "crates/ruvector-bounded-rag", "crates/ruvector-temporal-coherence", @@ -307,6 +328,15 @@ members = [ "crates/ruvector-streaming-qng", # Entropy-adaptive ANN beam search: live Shannon entropy gates beam width (ADR-303) "crates/ruvector-entropy-ann", + # PIR #859 workspace-membership sweep: these crates were dangling — + # present under crates/ but neither in members nor exclude, so their + # tests and lints never ran in CI. + "crates/ruvector-bet4-ivf-bench", + "crates/ruvector-hnsw-repair", + "crates/ruvector-temporal-tensor-wasm", + # NOTE: ruvector-agent-memory is listed once, mid-list next to + # ruvector-proof-gate (TARL ledger, PR #858); the duplicate entry the + # #859 sweep added here as a merge hedge was dropped on merge. ] resolver = "2" diff --git a/crates/ruvector-sota-bench/harness/package-lock.json b/crates/ruvector-sota-bench/harness/package-lock.json index fd185e56b..2ba4fe773 100644 --- a/crates/ruvector-sota-bench/harness/package-lock.json +++ b/crates/ruvector-sota-bench/harness/package-lock.json @@ -8,15 +8,16 @@ "name": "@ruvector/sota-metaharness", "version": "0.1.0", "dependencies": { - "@metaharness/darwin": "0.8.0", - "@metaharness/flywheel": "0.1.7", - "@metaharness/harness": "0.1.0", - "@metaharness/redblue": "0.1.4", - "@metaharness/router": "0.3.2", - "@metaharness/weight-eft": "0.1.1", - "@metaharness/workspace-lens": "0.1.1", - "@metaharness/workspace-probe": "0.1.1", - "metaharness": "0.4.2" + "@metaharness/darwin": "^0.9.1", + "@metaharness/flywheel": "^0.1.10", + "@metaharness/harness": "^0.2.0", + "@metaharness/redblue": "^0.1.6", + "@metaharness/router": "^0.4.0", + "@metaharness/weight-eft": "^0.1.1", + "@metaharness/workspace-lens": "^0.1.2", + "@metaharness/workspace-probe": "^0.1.1", + "dream-machine": "0.1.1", + "metaharness": "^0.4.7" }, "bin": { "ruvector-metaharness": "dist/src/cli.js" @@ -30,9 +31,9 @@ } }, "node_modules/@metaharness/darwin": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@metaharness/darwin/-/darwin-0.8.0.tgz", - "integrity": "sha512-Pgefr/es0Btofh7GxQrOAg/i43ZKcLUfeD9rndOAkpA8s3ZYohSmfLerJLNsGOOKc2eTvmmauljl8QEVmKC2dw==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@metaharness/darwin/-/darwin-0.9.2.tgz", + "integrity": "sha512-UaAikvfaowvXO97ivNubXRdXEDbvBl28XCDbyTv979vbzPiOoHWdPpS3XPHq/D9VG+wCtK9BpS3PXm340EkYSQ==", "license": "MIT", "bin": { "metaharness-darwin": "dist/cli.js" @@ -42,24 +43,24 @@ } }, "node_modules/@metaharness/flywheel": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@metaharness/flywheel/-/flywheel-0.1.7.tgz", - "integrity": "sha512-am7dROkjyS1Zkms3TOcn2LVHjwMLQXPJ6Pu1aP55q40vWJLRONGdGvnrcBL/VhMFqjQrVB57lmSn2E+s5CSZwA==", + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/@metaharness/flywheel/-/flywheel-0.1.10.tgz", + "integrity": "sha512-yrLXDXNdf4jKqHlW6QZw3Cy5T0eMMjjaPqn1XB717/Xx/y0Iv9R03W0OhMEiR/kfqMNebRBW1fi6D7inStEyqA==", "license": "MIT" }, "node_modules/@metaharness/harness": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@metaharness/harness/-/harness-0.1.0.tgz", - "integrity": "sha512-KegYx/q8qXlnaSYP0l5hgNPn8iNMl6a2eONqPi68FXd1w1jt7NswJJlt2/Ftl3Sum8qAEchxH1ZJOYFWTvJxTA==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@metaharness/harness/-/harness-0.2.0.tgz", + "integrity": "sha512-j/NLHqgPNre4qTTExvjCjh4/HgmhnVZPSQUfj06dyrlkpXCMFJ2abdPrl5yuFfzBMU0wnfFnFY2qQHQnBlAreg==", "license": "MIT", "engines": { "node": ">=20.0.0" } }, "node_modules/@metaharness/redblue": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@metaharness/redblue/-/redblue-0.1.4.tgz", - "integrity": "sha512-JaAk6bs3xA7Ks5RnAcZoxI3WfzpYL+Bk262SCI07w82BDOA7C6VxwGM63F7b86lRTKUVjTEnSqf7QZ3uyElT/g==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@metaharness/redblue/-/redblue-0.1.6.tgz", + "integrity": "sha512-cnQTOcPVetgz/XoYBdW5carkl48wBJsvBbJ7ntmelFtRu/8N5ARhSXnebEY+05SWaNm8lqij/gxZx2FqNCQWJg==", "license": "MIT", "bin": { "metaharness-redblue": "dist/cli/index.js", @@ -70,9 +71,9 @@ } }, "node_modules/@metaharness/router": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@metaharness/router/-/router-0.3.2.tgz", - "integrity": "sha512-LQElU6mUrWd3ffJ5bwoonEIgw7oFQZpwZaehffyl/Pg+iozpRjIBPEXdb4uTOBnKH+yPiTEWKc+h9AiZr9Os9w==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@metaharness/router/-/router-0.4.0.tgz", + "integrity": "sha512-VOfjHM7AMWwDH41AAMHOHFbH1r898xJqhqyE3G/r8OAxxrMgujX2SZsYkj/eXfBEmoPMhDVRkuO2abxvzCgEUA==", "license": "MIT", "engines": { "node": ">=20.0.0" @@ -86,6 +87,15 @@ } } }, + "node_modules/@metaharness/turn-credit": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@metaharness/turn-credit/-/turn-credit-0.1.0.tgz", + "integrity": "sha512-A752c0eEYEVodBB8HLOaSvcUMA65TX6/Cru2apZ7EE7aL2FSO74GFbgFWPo85bgqgNuMjhHkl/kG+lkC0TunNA==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@metaharness/weight-eft": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@metaharness/weight-eft/-/weight-eft-0.1.1.tgz", @@ -99,9 +109,9 @@ } }, "node_modules/@metaharness/workspace-lens": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@metaharness/workspace-lens/-/workspace-lens-0.1.1.tgz", - "integrity": "sha512-BkEdTvjD2PEhkGTCmtTIPnoeaOsxvzFtsFEAurwVKlVOu4hQetHeXDfiyAYheWg8Cp4fcGcr7E5MO1ptQveQ2g==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@metaharness/workspace-lens/-/workspace-lens-0.1.2.tgz", + "integrity": "sha512-Bfkj40rGZeBch4sQH/ma6zlY6dI+2AQfpTS/6AmPUE6/54H8Y04aBH5HPYfL0yBZ0lD/CeLViwFphT0PaiJ1mQ==", "license": "MIT" }, "node_modules/@metaharness/workspace-probe": { @@ -411,6 +421,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/dream-machine": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dream-machine/-/dream-machine-0.1.1.tgz", + "integrity": "sha512-ChagmBIuBHesdqW3nENh+heJgjHiIsSu4pLEX5Mp9X4orXDiUIb5xdsX4g3C8xSrMwzhyK+QO5jxENSMbgTcDg==", + "license": "MIT", + "bin": { + "dream-machine": "dist/bin.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -505,14 +527,15 @@ } }, "node_modules/metaharness": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/metaharness/-/metaharness-0.4.2.tgz", - "integrity": "sha512-h94B47zBEuNEfKLFMZMV/fRnXBrkwV6L8kMukgioB/9621k6Lm6s2lR2gBKl3BAT1sfN/DYqhsqAJc+6H5PTGQ==", + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/metaharness/-/metaharness-0.4.7.tgz", + "integrity": "sha512-oRbzFPry3bu2gC6+QoLsTbZmzAeNKjjl0gDhxO5p4++azuop9HKWUmw3Urb+uPfCX1IhVsVvjABGQ1VIB3Fbkg==", "license": "MIT", "dependencies": { - "@metaharness/darwin": "^0.2.2", + "@metaharness/darwin": "^0.9.1", "@metaharness/flywheel": "^0.1.1", - "@metaharness/redblue": "^0.1.1", + "@metaharness/redblue": "^0.1.6", + "@metaharness/turn-credit": "^0.1.0", "@metaharness/weight-eft": "^0.1.0", "kolorist": "^1.8.0", "prompts": "^2.4.2" @@ -536,18 +559,6 @@ } } }, - "node_modules/metaharness/node_modules/@metaharness/darwin": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@metaharness/darwin/-/darwin-0.2.8.tgz", - "integrity": "sha512-B8tF7IrrSxwKS6fEPEL6N2Juth9WWn+hppLUtUYPTJ2vcHzzZPIg2cS5T9qTyNNuANlTSWnQHnvzlfvYdGNfeQ==", - "license": "MIT", - "bin": { - "metaharness-darwin": "dist/cli.js" - }, - "engines": { - "node": ">=20.0.0" - } - }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", diff --git a/crates/ruvector-sota-bench/harness/package.json b/crates/ruvector-sota-bench/harness/package.json index bf807c1ab..8931174a1 100644 --- a/crates/ruvector-sota-bench/harness/package.json +++ b/crates/ruvector-sota-bench/harness/package.json @@ -16,15 +16,16 @@ "doctor": "npm run build && node dist/src/cli.js doctor" }, "dependencies": { - "@metaharness/darwin": "0.8.0", - "@metaharness/flywheel": "0.1.7", - "@metaharness/harness": "0.1.0", - "@metaharness/redblue": "0.1.4", - "@metaharness/router": "0.3.2", - "@metaharness/weight-eft": "0.1.1", - "@metaharness/workspace-lens": "0.1.1", - "@metaharness/workspace-probe": "0.1.1", - "metaharness": "0.4.2" + "@metaharness/darwin": "^0.9.1", + "@metaharness/flywheel": "^0.1.10", + "@metaharness/harness": "^0.2.0", + "@metaharness/redblue": "^0.1.6", + "@metaharness/router": "^0.4.0", + "@metaharness/weight-eft": "^0.1.1", + "@metaharness/workspace-lens": "^0.1.2", + "@metaharness/workspace-probe": "^0.1.1", + "dream-machine": "0.1.1", + "metaharness": "^0.4.7" }, "devDependencies": { "@types/node": "22.15.30", diff --git a/crates/ruvector-sota-bench/harness/src/dreamMachine.ts b/crates/ruvector-sota-bench/harness/src/dreamMachine.ts new file mode 100644 index 000000000..48193c371 --- /dev/null +++ b/crates/ruvector-sota-bench/harness/src/dreamMachine.ts @@ -0,0 +1,193 @@ +/** + * Dream Machine adapter (PIR WP2, ADR-306, issue #838). + * + * Adapts the `dream-machine` npm engine (ruvnet/dream-machine, ADR-0001) as an + * EVALUATION stage feeding this harness's EXISTING promotion path: + * + * dream-machine verdict ──► vetoes.ts PromotionVetoProvider input + * ──► flywheel.ts ruvectorPromotionRule (via vetoReasons) + * + * Authority split (the integration contract, no duplicated authority): + * - statistics.ts owns the paired-bootstrap significance decision; + * - the dream-machine engine owns the verdict vocabulary + * (ACCEPT | REJECT | INCONCLUSIVE), the ledger record, and the witness + * stamp binding a report to a commit; + * - vetoes.ts / flywheel.ts own the promotion RECOMMENDATION; + * - a human owns promotion itself. + * + * CONSTITUTIONAL BOUNDARY (ADR-0001, adopted verbatim by ADR-306): + * "Evaluation is not promotion — the machine never merges; a human does." + * This module can only emit evaluation verdicts and veto reasons. It exports + * no promote/merge/approve function, and the verdict object is frozen data + * with no callable members. test/dreamMachine.test.ts asserts both. + */ +import { run, VERSION as DREAM_MACHINE_VERSION, type IO, type RunResult } from "dream-machine"; +import type { PairedDecision } from "./statistics.js"; +import type { PromotionVetoProvider } from "./vetoes.js"; + +export { DREAM_MACHINE_VERSION }; + +/** The dream-machine ledger verdict vocabulary (engine-owned). */ +export type DreamVerdict = "ACCEPT" | "REJECT" | "INCONCLUSIVE"; + +/** Whether the candidate's evaluator actually ran (engine-owned vocabulary). */ +export type DreamEvaluated = "yes" | "no" | "blocked"; + +/** A candidate submitted to the dream-machine evaluation stage. */ +export interface DreamCandidate { + /** One-line description of the finding / mutation under evaluation. */ + finding: string; + /** Full evaluation report (markdown/JSON) to be witness-stamped. */ + report: string; + /** Git commit sha (7-40 hex) the evaluation ran against. */ + commit: string; + /** Paired-bootstrap decision from statistics.ts — the statistical authority. */ + decision: PairedDecision; + /** Did the evaluator run? Defaults to "yes". */ + evaluated?: DreamEvaluated; + /** Evaluation date, YYYY-MM-DD. Defaults to today (UTC). */ + date?: string; +} + +/** + * The evaluation verdict. Deliberately pure, frozen data: there is no + * promote(), no merge(), and no side-effect handle here — a verdict is an + * INPUT to the promotion rule and to ruvector-proof-gate, never a bypass. + */ +export interface DreamMachineVerdict { + readonly verdict: DreamVerdict; + readonly evaluated: DreamEvaluated; + /** Why the verdict is what it is (human-auditable). */ + readonly reasons: readonly string[]; + /** sha256(sha256(report) + commit) — the engine's witness stamp. */ + readonly witness: string; + /** The exact LEDGER.md markdown produced by the engine for this evaluation. */ + readonly ledger: string; + /** Engine version that produced this verdict. */ + readonly engineVersion: string; +} + +/** In-memory IO surface for the engine — no real filesystem is touched. */ +function memoryIO(seed: Record, date: string): IO & { files: Map } { + const files = new Map(Object.entries(seed)); + return { + files, + async readFile(path: string) { + const content = files.get(path); + if (content === undefined) throw new Error(`ENOENT: ${path}`); + return content; + }, + async writeFile(path: string, content: string) { + files.set(path, content); + }, + now: () => date, + env: {}, + }; +} + +function expectOk(step: string, result: RunResult): void { + if (result.code !== 0) { + throw new Error(`dream-machine ${step} failed (exit ${result.code}): ${result.err.trim() || result.out.trim()}`); + } +} + +/** + * Map the harness's statistical decision into the engine's verdict vocabulary. + * Pure. Conservative by construction: only a statistically confirmed + * improvement maps to ACCEPT; "inconclusive" is never rounded up. + */ +export function verdictFromDecision( + decision: PairedDecision, + evaluated: DreamEvaluated = "yes", +): DreamVerdict { + if (evaluated !== "yes") return "INCONCLUSIVE"; + if (decision.outcome === "pass") return "ACCEPT"; + if (decision.outcome === "fail") return "REJECT"; + return "INCONCLUSIVE"; +} + +const LEDGER_PATH = "docs/dream-cycle/LEDGER.md"; +const REPORT_PATH = "evaluation-report.md"; + +/** + * Run one candidate through the dream-machine engine: record the evaluation + * in an engine-verified ledger row and witness-stamp the report against the + * commit. Returns a frozen verdict — data only, no promotion capability. + */ +export async function evaluateCandidate(candidate: DreamCandidate): Promise { + const evaluated = candidate.evaluated ?? "yes"; + const date = candidate.date ?? new Date().toISOString().slice(0, 10); + const verdict = verdictFromDecision(candidate.decision, evaluated); + const reasons: string[] = [ + `statistics_outcome_${candidate.decision.outcome}`, + `evaluated_${evaluated}`, + ]; + + const io = memoryIO({ [REPORT_PATH]: candidate.report }, date); + + // 1. Engine computes the witness stamp binding report to commit. + const stamped = await run(["witness", "stamp", REPORT_PATH, candidate.commit], io); + expectOk("witness stamp", stamped); + const witnessMatch = stamped.out.match(/witness\s*:\s*([0-9a-f]{64})/); + if (!witnessMatch) throw new Error(`could not parse witness from engine output: ${stamped.out}`); + const witness = witnessMatch[1]!; + + // 2. Engine appends the evaluation row to the ledger. + const appended = await run([ + "ledger", "append", + "--path", LEDGER_PATH, + "--date", date, + "--deep", "sota-harness", + "--finding", candidate.finding, + "--evaluated", evaluated, + "--verdict", verdict, + "--effect", `meanDelta=${candidate.decision.meanDelta}`, + "--witness", witness.slice(0, 8), + ], io); + expectOk("ledger append", appended); + + // 3. Engine structurally verifies its own ledger (verdict vocabulary check). + const verified = await run(["ledger", "verify", "--path", LEDGER_PATH], io); + expectOk("ledger verify", verified); + + // 4. Engine re-verifies the witness stamp round-trips. + const witnessed = await run(["witness", "verify", REPORT_PATH, candidate.commit, witness], io); + expectOk("witness verify", witnessed); + + return Object.freeze({ + verdict, + evaluated, + reasons: Object.freeze(reasons), + witness, + ledger: io.files.get(LEDGER_PATH) ?? "", + engineVersion: DREAM_MACHINE_VERSION, + }); +} + +/** + * Map a verdict into vetoes.ts veto reasons. Pure. Conjunctive with all other + * vetoes: a dream-machine ACCEPT adds no credit and rescues nothing; anything + * other than ACCEPT blocks promotion ("no mutation reaches the proof gate + * without passing a verdict"). + */ +export function vetoesFromVerdict(verdict: DreamMachineVerdict): string[] { + if (verdict.verdict === "ACCEPT") return []; + if (verdict.verdict === "REJECT") return ["dream_machine_reject"]; + return ["dream_machine_inconclusive"]; +} + +/** + * A PromotionVetoProvider for flywheel.ts: runs the candidate through the + * dream-machine evaluation stage and feeds the verdict into the existing + * promotion rule as veto reasons. This is the ONLY wiring between the engine + * and promotion, and it can only ever say "no" or "no objection". + */ +export function dreamMachineVetoProvider( + candidateFor: (context: Parameters[0]) => DreamCandidate | Promise, +): PromotionVetoProvider { + return async (context) => { + const candidate = await candidateFor(context); + const verdict = await evaluateCandidate(candidate); + return vetoesFromVerdict(verdict); + }; +} diff --git a/crates/ruvector-sota-bench/harness/test/dreamMachine.test.ts b/crates/ruvector-sota-bench/harness/test/dreamMachine.test.ts new file mode 100644 index 000000000..007f91851 --- /dev/null +++ b/crates/ruvector-sota-bench/harness/test/dreamMachine.test.ts @@ -0,0 +1,103 @@ +import assert from "node:assert/strict"; +import test from "node:test"; +import * as adapter from "../src/dreamMachine.js"; +import { + evaluateCandidate, + verdictFromDecision, + vetoesFromVerdict, + dreamMachineVetoProvider, + DREAM_MACHINE_VERSION, +} from "../src/dreamMachine.js"; +import type { PairedDecision } from "../src/statistics.js"; + +const decision = (outcome: PairedDecision["outcome"]): PairedDecision => ({ + meanDelta: outcome === "pass" ? 12.5 : 0, + lower95: outcome === "pass" ? 1 : -1, + upper95: outcome === "fail" ? -0.5 : 2, + outcome, + samples: 2000, +}); + +const COMMIT = "0123456789abcdef0123456789abcdef01234567"; + +test("verdict mapping: statistical outcome → engine verdict vocabulary", () => { + assert.equal(verdictFromDecision(decision("pass")), "ACCEPT"); + assert.equal(verdictFromDecision(decision("fail")), "REJECT"); + assert.equal(verdictFromDecision(decision("inconclusive")), "INCONCLUSIVE"); + // A blocked/never-run evaluator can never be rounded up to ACCEPT. + assert.equal(verdictFromDecision(decision("pass"), "blocked"), "INCONCLUSIVE"); + assert.equal(verdictFromDecision(decision("pass"), "no"), "INCONCLUSIVE"); +}); + +test("verdict → veto reasons: ACCEPT adds no credit, everything else blocks", async () => { + const accept = await evaluateCandidate({ + finding: "smoke", report: "# r", commit: COMMIT, decision: decision("pass"), + }); + const reject = await evaluateCandidate({ + finding: "smoke", report: "# r", commit: COMMIT, decision: decision("fail"), + }); + const inconclusive = await evaluateCandidate({ + finding: "smoke", report: "# r", commit: COMMIT, decision: decision("inconclusive"), + }); + assert.deepEqual(vetoesFromVerdict(accept), []); + assert.deepEqual(vetoesFromVerdict(reject), ["dream_machine_reject"]); + assert.deepEqual(vetoesFromVerdict(inconclusive), ["dream_machine_inconclusive"]); +}); + +test("smoke: the dream-machine engine loads and evaluates a trivial candidate", async () => { + const verdict = await evaluateCandidate({ + finding: "trivial candidate", + report: "# evaluation report\nrecall@10 improved.\n", + commit: COMMIT, + decision: decision("pass"), + date: "2026-08-19", + }); + assert.equal(verdict.verdict, "ACCEPT"); + assert.equal(verdict.evaluated, "yes"); + assert.equal(verdict.engineVersion, DREAM_MACHINE_VERSION); + // Engine-produced witness stamp: sha256(sha256(report) + commit). + assert.match(verdict.witness, /^[0-9a-f]{64}$/); + // Engine-produced, engine-verified ledger row. + assert.ok(verdict.ledger.includes("| Date |")); + assert.ok(verdict.ledger.includes("trivial candidate")); + assert.ok(verdict.ledger.includes("ACCEPT")); + assert.ok(verdict.ledger.includes(verdict.witness.slice(0, 8))); +}); + +test("adapter plugs into the existing vetoes.ts provider contract", async () => { + const provider = dreamMachineVetoProvider(() => ({ + finding: "provider smoke", + report: "# r", + commit: COMMIT, + decision: decision("fail"), + })); + const reasons = await provider({ + policy: { ef_search: "100" }, + suite: { id: "fixture", items: [] }, + observations: [], + }); + assert.deepEqual(reasons, ["dream_machine_reject"]); +}); + +test("constitutional boundary: no promotion capability is exported or reachable", async () => { + // 1. The module exports no promote/merge/approve/apply function. + const forbidden = /promote|merge|approve|apply|commit|push/i; + for (const [name, value] of Object.entries(adapter)) { + assert.ok( + !forbidden.test(name), + `export "${name}" looks like a promotion capability — the adapter must only emit verdicts/vetoes`, + ); + void value; + } + + // 2. The verdict object is frozen data with no callable members. + const verdict = await evaluateCandidate({ + finding: "boundary", report: "# r", commit: COMMIT, decision: decision("pass"), + }); + assert.ok(Object.isFrozen(verdict)); + for (const [key, value] of Object.entries(verdict)) { + assert.notEqual(typeof value, "function", `verdict.${key} must be data, not a capability`); + } + // @ts-expect-error — DreamMachineVerdict has no promote() by construction. + assert.equal(verdict.promote, undefined); +}); diff --git a/crates/ruvllm-cli/src/commands/chat.rs b/crates/ruvllm-cli/src/commands/chat.rs index ca2c7a88d..4a2ad66c1 100644 --- a/crates/ruvllm-cli/src/commands/chat.rs +++ b/crates/ruvllm-cli/src/commands/chat.rs @@ -49,9 +49,11 @@ pub async fn run( draft_model: Option<&str>, speculative_lookahead: usize, ) -> Result<()> { - let model_id = resolve_model_id(model); let quant = QuantPreset::from_str(quantization) .ok_or_else(|| anyhow::anyhow!("Invalid quantization format: {}", quantization))?; + // Resolve to the repo that hosts the weights for this quantization + // (GGUF twin for safetensors-only aliases) — must match `download`'s cache key. + let model_id = crate::models::resolve_weights_repo(model, quant); // Print header print_header(&model_id, system_prompt, max_tokens, temperature); @@ -80,7 +82,11 @@ pub async fn run( "{}", "Loading draft model for speculative decoding...".yellow() ); - let draft = load_model(&resolve_model_id(draft_id), quant, cache_dir)?; + let draft = load_model( + &crate::models::resolve_weights_repo(draft_id, quant), + quant, + cache_dir, + )?; if let Some(info) = draft.model_info() { println!( diff --git a/crates/ruvllm-cli/src/commands/download.rs b/crates/ruvllm-cli/src/commands/download.rs index 30d1df383..bccc472c5 100644 --- a/crates/ruvllm-cli/src/commands/download.rs +++ b/crates/ruvllm-cli/src/commands/download.rs @@ -12,7 +12,7 @@ use hf_hub::{Repo, RepoType}; use indicatif::{ProgressBar, ProgressStyle}; use std::path::{Path, PathBuf}; -use crate::models::{get_model, resolve_model_id, QuantPreset}; +use crate::models::{get_model, resolve_model_id, resolve_weights_repo, QuantPreset}; /// Run the download command pub async fn run( @@ -22,10 +22,14 @@ pub async fn run( revision: Option<&str>, cache_dir: &str, ) -> Result<()> { - let model_id = resolve_model_id(model); let quant = QuantPreset::from_str(quantization) .ok_or_else(|| anyhow::anyhow!("Invalid quantization format: {}", quantization))?; + // Route quantized (GGUF) requests to the repo that actually hosts GGUF + // weights (registry `gguf_repo` twin for safetensors-only aliases). + let base_id = resolve_model_id(model); + let model_id = resolve_weights_repo(model, quant); + println!(); println!( "{} {} ({})", @@ -33,6 +37,13 @@ pub async fn run( model_id, quant ); + if model_id != base_id { + println!( + " {} {} hosts safetensors only; using GGUF twin repo", + "Note:".dimmed(), + base_id + ); + } println!(); // Get model info if available @@ -62,8 +73,12 @@ pub async fn run( api.repo(Repo::new(model_id.clone(), RepoType::Model)) }; - // Determine files to download - let files_to_download = get_files_to_download(&model_id, quant); + // List the repo's actual files and expand the quant pattern against them + // (previously an unexpanded glob like "*Q4_K_M.gguf" was sent literally -> 404). + let remote_files = list_repo_files(&repo, &model_id, revision) + .await + .with_context(|| format!("Failed to list files for {model_id} on HuggingFace"))?; + let files_to_download = get_files_to_download(&model_id, quant, &remote_files)?; // Create cache directory let model_cache_dir = PathBuf::from(cache_dir).join("models").join(&model_id); @@ -73,7 +88,20 @@ pub async fn run( // Download each file for file_name in &files_to_download { + // Defense-in-depth: `file_name` originates from the repo's own file + // listing (HF tree API / siblings) and is attacker-controlled for a + // malicious repo — reject traversal before joining into the cache. + validate_remote_file_name(file_name) + .with_context(|| format!("Unsafe file path in {model_id} listing"))?; let target_path = model_cache_dir.join(file_name); + if let Some(parent) = target_path.parent() { + tokio::fs::create_dir_all(parent) + .await + .context("Failed to create cache subdirectory")?; + ensure_under_cache_dir(&model_cache_dir, parent).with_context(|| { + format!("Refusing to write {file_name} outside the model cache directory") + })?; + } // Check if file exists if target_path.exists() && !force { @@ -174,43 +202,280 @@ fn download_via_curl(model_id: &str, revision: Option<&str>, file_name: &str) -> "-o".to_string(), out.to_string_lossy().to_string(), ]; - if let Ok(token) = std::env::var("HF_TOKEN") { - args.push("-H".to_string()); - args.push(format!("Authorization: Bearer {token}")); + let auth_config = hf_token_curl_config(); + if auth_config.is_some() { + args.push("--config".to_string()); + args.push("-".to_string()); } args.push(url.clone()); - let status = std::process::Command::new("curl") - .args(&args) - .status() + let output = run_curl(&args, auth_config.as_deref()) .with_context(|| format!("curl not available to fetch {url}"))?; - if !status.success() { - anyhow::bail!("curl fallback failed ({status}) for {url}"); + if !output.status.success() { + anyhow::bail!("curl fallback failed ({}) for {url}", output.status); } Ok(out) } -/// Get list of files to download for a model and quantization -fn get_files_to_download(model_id: &str, quant: QuantPreset) -> Vec { - let mut files = vec![ - "tokenizer.json".to_string(), - "tokenizer_config.json".to_string(), - "config.json".to_string(), - ]; +/// List a repo's files via the hf-hub API, falling back to a `curl` of the +/// HF tree endpoint (`GET /api/models//tree/`) — the same fallback +/// idiom as `download_via_curl`, honoring `HF_TOKEN`. +async fn list_repo_files( + repo: &hf_hub::api::tokio::ApiRepo, + model_id: &str, + revision: Option<&str>, +) -> Result> { + match repo.info().await { + Ok(info) => Ok(info.siblings.into_iter().map(|s| s.rfilename).collect()), + Err(e) => list_files_via_curl(model_id, revision) + .with_context(|| format!("hf-hub file listing also failed: {e}")), + } +} - // Add model weights based on quantization - if model_id.contains("GGUF") || quant != QuantPreset::None { - // Look for GGUF files - files.push(format!("*{}", quant.gguf_suffix())); - } else { - // SafeTensors format +/// Fallback file listing via `curl` against the HF tree API. +fn list_files_via_curl(model_id: &str, revision: Option<&str>) -> Result> { + let rev = revision.unwrap_or("main"); + let url = format!("https://huggingface.co/api/models/{model_id}/tree/{rev}?recursive=true"); + let mut args = vec!["-L".to_string(), "--fail".to_string(), "-sS".to_string()]; + let auth_config = hf_token_curl_config(); + if auth_config.is_some() { + args.push("--config".to_string()); + args.push("-".to_string()); + } + args.push(url.clone()); + let output = run_curl(&args, auth_config.as_deref()) + .with_context(|| format!("curl not available to list {url}"))?; + if !output.status.success() { + anyhow::bail!("curl file listing failed ({}) for {url}", output.status); + } + parse_tree_file_paths(&String::from_utf8_lossy(&output.stdout)) +} + +/// Build the curl-config fragment carrying the `HF_TOKEN` Authorization +/// header, or `None` when the token is unset. Passing the header through a +/// config read from stdin (`--config -`) keeps the token off curl's argv, +/// which is world-readable via `ps`/`/proc//cmdline` (CWE-214). +fn hf_token_curl_config() -> Option { + std::env::var("HF_TOKEN") + .ok() + .filter(|t| !t.is_empty()) + .map(|t| curl_auth_config(&t)) +} + +/// Render an Authorization header as a curl config line, escaping the +/// characters curl's double-quoted config strings treat specially so a +/// hostile/odd token value cannot inject additional config directives. +fn curl_auth_config(token: &str) -> String { + let escaped = token + .replace('\\', "\\\\") + .replace('"', "\\\"") + .replace('\n', "\\n") + .replace('\r', "\\r"); + format!("header = \"Authorization: Bearer {escaped}\"\n") +} + +/// Run `curl` with `args`, feeding `stdin_config` (a curl config carrying the +/// auth header) on stdin when present. Stderr is inherited so `-sS` errors +/// stay visible; stdout is captured for callers that parse it. +fn run_curl(args: &[String], stdin_config: Option<&str>) -> Result { + use std::io::Write as _; + use std::process::{Command, Stdio}; + + let mut cmd = Command::new("curl"); + cmd.args(args) + .stdin(if stdin_config.is_some() { + Stdio::piped() + } else { + Stdio::null() + }) + .stdout(Stdio::piped()) + .stderr(Stdio::inherit()); + let mut child = cmd.spawn().context("failed to spawn curl")?; + if let Some(config) = stdin_config { + child + .stdin + .take() + .expect("stdin is piped when a config is supplied") + .write_all(config.as_bytes()) + .context("failed to write curl config to stdin")?; + // stdin handle dropped here -> EOF for `--config -` + } + child.wait_with_output().context("failed to wait for curl") +} + +/// Defense-in-depth guard for file names taken from a repo's own listing +/// (HF tree API `path` / `siblings[].rfilename`): reject empty names and any +/// component that is not a plain path segment (absolute paths, `..`, `.`, +/// Windows prefixes) before the name is joined into the cache directory. +fn validate_remote_file_name(file_name: &str) -> Result<()> { + use std::path::Component; + + if file_name.is_empty() { + anyhow::bail!("empty file name in repo listing"); + } + if Path::new(file_name) + .components() + .any(|c| !matches!(c, Component::Normal(_))) + { + anyhow::bail!("suspicious file path in repo listing: {file_name:?}"); + } + Ok(()) +} + +/// Verify that `target_parent` (already created) canonicalizes to a location +/// under the canonicalized model cache dir — catches anything the component +/// check missed (e.g. symlinked subdirectories escaping the cache). +fn ensure_under_cache_dir(cache_root: &Path, target_parent: &Path) -> Result<()> { + let root = cache_root + .canonicalize() + .context("failed to canonicalize model cache directory")?; + let parent = target_parent + .canonicalize() + .context("failed to canonicalize download target directory")?; + if !parent.starts_with(&root) { + anyhow::bail!( + "download target {} escapes model cache directory {}", + parent.display(), + root.display() + ); + } + Ok(()) +} + +/// Parse file paths out of the HF tree API JSON (`[{"type":"file","path":...},...]`). +fn parse_tree_file_paths(json: &str) -> Result> { + let entries: serde_json::Value = + serde_json::from_str(json).context("Invalid JSON from HF tree API")?; + let entries = entries + .as_array() + .ok_or_else(|| anyhow::anyhow!("HF tree API did not return an array"))?; + Ok(entries + .iter() + .filter(|e| e.get("type").and_then(|t| t.as_str()) == Some("file")) + .filter_map(|e| e.get("path").and_then(|p| p.as_str()).map(String::from)) + .collect()) +} + +/// Get list of files to download for a model and quantization, resolved +/// against the repo's actual file listing. +fn get_files_to_download( + model_id: &str, + quant: QuantPreset, + remote_files: &[String], +) -> Result> { + // Aux files: only the ones the repo actually has (GGUF repos typically + // ship none — tokenizer/config are embedded in the GGUF itself). + let mut files: Vec = [ + "tokenizer.json", + "tokenizer_config.json", + "config.json", + "special_tokens_map.json", + "generation_config.json", + ] + .iter() + .filter(|f| remote_files.iter().any(|r| r == *f)) + .map(|f| f.to_string()) + .collect(); + + // Model weights + if model_id.to_ascii_uppercase().contains("GGUF") || quant != QuantPreset::None { + files.extend(select_gguf_files(model_id, quant, remote_files)?); + } else if remote_files.iter().any(|f| f == "model.safetensors") { files.push("model.safetensors".to_string()); + } else { + // Sharded safetensors (model-00001-of-000NN.safetensors) + let mut shards: Vec = remote_files + .iter() + .filter(|f| f.starts_with("model-") && f.ends_with(".safetensors")) + .cloned() + .collect(); + if shards.is_empty() { + anyhow::bail!( + "No safetensors weights found in {model_id}.\nAvailable files:\n {}", + remote_files.join("\n ") + ); + } + shards.sort(); + files.extend(shards); } - // Add special tokens and chat template if available - files.push("special_tokens_map.json".to_string()); - files.push("generation_config.json".to_string()); + Ok(files) +} - files +/// Select the GGUF weight file(s) matching `quant` from the repo listing. +/// +/// Handles both single-file (`...-Q4_K_M.gguf`) and multi-part +/// (`...-q4_k_m-00001-of-00003.gguf`) layouts — multi-part is the norm for +/// larger models (e.g. Qwen2.5-14B), so all parts are downloaded in order. +/// Fails with the repo's actual GGUF inventory (or full file list) when +/// nothing matches, instead of 404ing on a glob. +fn select_gguf_files( + model_id: &str, + quant: QuantPreset, + remote_files: &[String], +) -> Result> { + let mut matches: Vec = remote_files + .iter() + .filter(|f| { + quant + .gguf_tags() + .iter() + .any(|tag| matches_gguf_quant(f, tag)) + }) + .cloned() + .collect(); + + if matches.is_empty() { + let ggufs: Vec<&String> = remote_files + .iter() + .filter(|f| f.to_ascii_lowercase().ends_with(".gguf")) + .collect(); + if ggufs.is_empty() { + anyhow::bail!( + "No GGUF files found in {model_id} (requested quantization: {quant}).\n\ + This repo appears to host non-GGUF weights only. Available files:\n {}\n\ + Hint: pass a GGUF repo, or use --quantization none for safetensors.", + remote_files.join("\n ") + ); + } + anyhow::bail!( + "No GGUF file matching quantization {quant} in {model_id}.\n\ + Available GGUF files:\n {}", + ggufs + .iter() + .map(|s| s.as_str()) + .collect::>() + .join("\n ") + ); + } + + // Zero-padded part numbers sort lexically (…-00001-of-00003 first). + matches.sort(); + Ok(matches) +} + +/// True if `file` is a GGUF weight file for the given lowercase quant tag, +/// either single-file (`-.gguf`) or a multi-part shard +/// (`--NNNNN-of-NNNNN.gguf`). Matching is case-insensitive. +fn matches_gguf_quant(file: &str, tag: &str) -> bool { + let f = file.to_ascii_lowercase(); + let Some(stem) = f.strip_suffix(".gguf") else { + return false; + }; + // Single-file: ends with the tag (allow "-tag", ".tag", or bare tag) + if stem == tag || stem.ends_with(&format!("-{tag}")) || stem.ends_with(&format!(".{tag}")) { + return true; + } + // Multi-part: ...--NNNNN-of-NNNNN + if let Some(idx) = stem.rfind(&format!("-{tag}-")) { + let rest = &stem[idx + tag.len() + 2..]; + if let Some((part, total)) = rest.split_once("-of-") { + return !part.is_empty() + && !total.is_empty() + && part.chars().all(|c| c.is_ascii_digit()) + && total.chars().all(|c| c.is_ascii_digit()); + } + } + false } /// Check if a model is already downloaded @@ -243,10 +508,220 @@ pub fn get_model_path(model: &str, cache_dir: &str) -> PathBuf { mod tests { use super::*; + /// HF tree API fixture: Qwen-style GGUF repo (lowercase, multi-part). + const QWEN_TREE_JSON: &str = r#"[ + {"type":"file","oid":"a","size":100,"path":".gitattributes"}, + {"type":"file","oid":"b","size":100,"path":"README.md"}, + {"type":"directory","oid":"c","path":"assets"}, + {"type":"file","oid":"d","size":1,"path":"qwen2.5-14b-instruct-q4_k_m-00002-of-00003.gguf"}, + {"type":"file","oid":"e","size":1,"path":"qwen2.5-14b-instruct-q4_k_m-00001-of-00003.gguf"}, + {"type":"file","oid":"f","size":1,"path":"qwen2.5-14b-instruct-q4_k_m-00003-of-00003.gguf"}, + {"type":"file","oid":"g","size":1,"path":"qwen2.5-14b-instruct-q8_0-00001-of-00004.gguf"}, + {"type":"file","oid":"h","size":1,"path":"qwen2.5-14b-instruct-fp16-00001-of-00008.gguf"} + ]"#; + + fn qwen_files() -> Vec { + parse_tree_file_paths(QWEN_TREE_JSON).unwrap() + } + #[test] - fn test_files_to_download() { - let files = get_files_to_download("test/model", QuantPreset::Q4K); + fn test_parse_tree_file_paths_skips_directories() { + let files = qwen_files(); + assert_eq!(files.len(), 7); + assert!(!files.iter().any(|f| f == "assets")); + assert!(files.contains(&"README.md".to_string())); + } + + #[test] + fn test_parse_tree_rejects_bad_json() { + assert!(parse_tree_file_paths("not json").is_err()); + assert!(parse_tree_file_paths(r#"{"error":"Repo not found"}"#).is_err()); + } + + #[test] + fn test_glob_expansion_multi_part_sorted() { + // The old code pushed the literal "*Q4_K_M.gguf" -> 404. The matcher + // must instead select the real (multi-part, lowercase) filenames. + let files = select_gguf_files( + "Qwen/Qwen2.5-14B-Instruct-GGUF", + QuantPreset::Q4K, + &qwen_files(), + ) + .unwrap(); + assert_eq!( + files, + vec![ + "qwen2.5-14b-instruct-q4_k_m-00001-of-00003.gguf", + "qwen2.5-14b-instruct-q4_k_m-00002-of-00003.gguf", + "qwen2.5-14b-instruct-q4_k_m-00003-of-00003.gguf", + ] + ); + } + + #[test] + fn test_glob_expansion_single_file_uppercase() { + // bartowski-style single-file uppercase naming + let files = vec![ + "README.md".to_string(), + "microsoft_Phi-4-mini-instruct-Q4_K_M.gguf".to_string(), + "microsoft_Phi-4-mini-instruct-Q8_0.gguf".to_string(), + ]; + let selected = select_gguf_files( + "bartowski/microsoft_Phi-4-mini-instruct-GGUF", + QuantPreset::Q4K, + &files, + ) + .unwrap(); + assert_eq!(selected, vec!["microsoft_Phi-4-mini-instruct-Q4_K_M.gguf"]); + } + + #[test] + fn test_f16_matches_fp16_spelling() { + let selected = select_gguf_files( + "Qwen/Qwen2.5-14B-Instruct-GGUF", + QuantPreset::F16, + &qwen_files(), + ) + .unwrap(); + assert_eq!( + selected, + vec!["qwen2.5-14b-instruct-fp16-00001-of-00008.gguf"] + ); + } + + #[test] + fn test_no_gguf_in_repo_fails_with_available_files() { + // Safetensors-only repo (the phi/microsoft case) must fail early with + // an actionable listing, not a 404 on a glob. + let files = vec![ + "config.json".to_string(), + "model-00001-of-00002.safetensors".to_string(), + "model-00002-of-00002.safetensors".to_string(), + ]; + let err = select_gguf_files("microsoft/Phi-4-mini-instruct", QuantPreset::Q4K, &files) + .unwrap_err() + .to_string(); + assert!(err.contains("No GGUF files found")); + assert!(err.contains("model-00001-of-00002.safetensors")); + assert!(err.contains("--quantization none")); + } + + #[test] + fn test_missing_quant_lists_available_ggufs() { + let files = vec!["m-q8_0.gguf".to_string()]; + let err = select_gguf_files("x/y-GGUF", QuantPreset::Q4K, &files) + .unwrap_err() + .to_string(); + assert!(err.contains("Q4_K_M")); + assert!(err.contains("m-q8_0.gguf")); + } + + #[test] + fn test_matches_gguf_quant_shapes() { + assert!(matches_gguf_quant("model-Q4_K_M.gguf", "q4_k_m")); + assert!(matches_gguf_quant("model.q4_k_m.gguf", "q4_k_m")); + assert!(matches_gguf_quant("m-q4_k_m-00001-of-00003.gguf", "q4_k_m")); + // No false positives on other quants or non-gguf files + assert!(!matches_gguf_quant("model-Q4_K_S.gguf", "q4_k_m")); + assert!(!matches_gguf_quant("model-q4_k_m.safetensors", "q4_k_m")); + assert!(!matches_gguf_quant("m-q4_k_m-partial-of-x.gguf", "q4_k_m")); + } + + #[test] + fn test_files_to_download_filters_aux_by_listing() { + // GGUF repos ship no tokenizer.json/config.json — must not request them. + let files = get_files_to_download( + "Qwen/Qwen2.5-14B-Instruct-GGUF", + QuantPreset::Q4K, + &qwen_files(), + ) + .unwrap(); + assert!(!files.contains(&"tokenizer.json".to_string())); + assert!( + files.iter().all(|f| !f.contains('*')), + "no unexpanded globs" + ); + assert_eq!(files.iter().filter(|f| f.ends_with(".gguf")).count(), 3); + } + + #[test] + fn test_validate_remote_file_name_rejects_hostile_names() { + for hostile in [ + "../x", + "/abs", + "a/../../x", + "", + "..", + "./x/../y", + "/etc/passwd", + ] { + assert!( + validate_remote_file_name(hostile).is_err(), + "should reject {hostile:?}" + ); + } + } + + #[test] + fn test_validate_remote_file_name_accepts_normal_names() { + for ok in [ + "model-Q4_K_M.gguf", + "tokenizer.json", + "subdir/model-00001-of-00003.gguf", + "a/b/c.txt", + ] { + assert!( + validate_remote_file_name(ok).is_ok(), + "should accept {ok:?}" + ); + } + } + + #[test] + fn test_ensure_under_cache_dir_containment() { + let base = std::env::temp_dir().join(format!("ruvllm-guard-test-{}", std::process::id())); + let root = base.join("cache"); + let inside = root.join("sub"); + let outside = base.join("outside"); + std::fs::create_dir_all(&inside).unwrap(); + std::fs::create_dir_all(&outside).unwrap(); + + assert!(ensure_under_cache_dir(&root, &inside).is_ok()); + assert!(ensure_under_cache_dir(&root, &root).is_ok()); + assert!(ensure_under_cache_dir(&root, &outside).is_err()); + + std::fs::remove_dir_all(&base).ok(); + } + + #[test] + fn test_curl_auth_config_keeps_token_in_header_line() { + let cfg = curl_auth_config("hf_abc123"); + assert_eq!(cfg, "header = \"Authorization: Bearer hf_abc123\"\n"); + } + + #[test] + fn test_curl_auth_config_escapes_special_characters() { + // Quotes, backslashes, and newlines must not break out of the quoted + // config string (which would allow injecting extra curl directives). + let cfg = curl_auth_config("a\"b\\c\nd\re"); + assert_eq!( + cfg, + "header = \"Authorization: Bearer a\\\"b\\\\c\\nd\\re\"\n" + ); + // Exactly one config line regardless of token content. + assert_eq!(cfg.matches('\n').count(), 1); + assert!(cfg.ends_with('\n')); + } + + #[test] + fn test_files_to_download_safetensors_path() { + let remote = vec![ + "tokenizer.json".to_string(), + "config.json".to_string(), + "model.safetensors".to_string(), + ]; + let files = get_files_to_download("test/model", QuantPreset::None, &remote).unwrap(); assert!(files.contains(&"tokenizer.json".to_string())); - assert!(files.iter().any(|f| f.contains("Q4_K_M"))); + assert!(files.contains(&"model.safetensors".to_string())); } } diff --git a/crates/ruvllm-cli/src/commands/serve.rs b/crates/ruvllm-cli/src/commands/serve.rs index e4b310025..0a638b6d4 100644 --- a/crates/ruvllm-cli/src/commands/serve.rs +++ b/crates/ruvllm-cli/src/commands/serve.rs @@ -51,9 +51,11 @@ pub async fn run( quantization: &str, cache_dir: &str, ) -> Result<()> { - let model_id = resolve_model_id(model); let quant = QuantPreset::from_str(quantization) .ok_or_else(|| anyhow::anyhow!("Invalid quantization format: {}", quantization))?; + // Resolve to the repo that hosts the weights for this quantization + // (GGUF twin for safetensors-only aliases) — must match `download`'s cache key. + let model_id = crate::models::resolve_weights_repo(model, quant); println!(); println!("{}", style("RuvLLM Inference Server").bold().cyan()); diff --git a/crates/ruvllm-cli/src/models.rs b/crates/ruvllm-cli/src/models.rs index cc0121a58..15b397857 100644 --- a/crates/ruvllm-cli/src/models.rs +++ b/crates/ruvllm-cli/src/models.rs @@ -29,6 +29,12 @@ pub struct ModelDefinition { pub context_length: usize, /// Notes about the model pub notes: String, + /// GGUF "twin" repo for models whose `hf_id` only hosts safetensors. + /// When a quantized (GGUF) download is requested, weights are resolved + /// from this repo instead of `hf_id`. `None` means `hf_id` itself hosts + /// the GGUF files (or no GGUF twin is known). + #[serde(default)] + pub gguf_repo: Option, } /// Get all recommended models @@ -46,6 +52,7 @@ pub fn get_recommended_models() -> Vec { memory_gb: 9.5, context_length: 32768, notes: "Best overall performance for reasoning tasks on M4 Pro".to_string(), + gguf_repo: None, }, // Fast instruction following ModelDefinition { @@ -59,6 +66,7 @@ pub fn get_recommended_models() -> Vec { memory_gb: 4.5, context_length: 32768, notes: "Excellent speed/quality tradeoff with sliding window attention".to_string(), + gguf_repo: Some("bartowski/Mistral-7B-Instruct-v0.3-GGUF".to_string()), }, // Tiny/testing model ModelDefinition { @@ -72,6 +80,7 @@ pub fn get_recommended_models() -> Vec { memory_gb: 2.5, context_length: 16384, notes: "Surprisingly capable for its size, fast inference".to_string(), + gguf_repo: Some("bartowski/microsoft_Phi-4-mini-instruct-GGUF".to_string()), }, // Tool use model ModelDefinition { @@ -85,6 +94,7 @@ pub fn get_recommended_models() -> Vec { memory_gb: 2.2, context_length: 131072, notes: "Optimized for tool use and function calling".to_string(), + gguf_repo: Some("bartowski/Llama-3.2-3B-Instruct-GGUF".to_string()), }, // Code-specific model ModelDefinition { @@ -98,6 +108,7 @@ pub fn get_recommended_models() -> Vec { memory_gb: 4.8, context_length: 32768, notes: "Specialized for coding tasks, excellent at code completion".to_string(), + gguf_repo: None, }, // Large reasoning model (for when you have the memory) ModelDefinition { @@ -111,6 +122,7 @@ pub fn get_recommended_models() -> Vec { memory_gb: 20.0, context_length: 32768, notes: "Requires significant memory, but provides best quality".to_string(), + gguf_repo: None, }, ] } @@ -147,6 +159,27 @@ pub fn resolve_model_id(identifier: &str) -> String { } } +/// Resolve the repo that hosts the *weights* for `identifier` at `quant`. +/// +/// A quantized (GGUF) request against an alias whose `hf_id` is a +/// safetensors-only repo is routed to the registry's `gguf_repo` twin when one +/// is defined. Repos that already host GGUF files (id contains "GGUF") and +/// unquantized requests resolve as before. Unknown identifiers pass through +/// unchanged — the download command then validates against the actual HF file +/// listing and fails with the available files rather than a 404 on a glob. +pub fn resolve_weights_repo(identifier: &str, quant: QuantPreset) -> String { + let base = resolve_model_id(identifier); + if quant == QuantPreset::None || base.to_ascii_uppercase().contains("GGUF") { + return base; + } + if let Some(model) = get_model(identifier) { + if let Some(gguf_repo) = model.gguf_repo { + return gguf_repo; + } + } + base +} + /// Get model aliases map pub fn get_aliases() -> HashMap { get_recommended_models() @@ -190,6 +223,18 @@ impl QuantPreset { } } + /// Quant tags to match against actual GGUF filenames (lowercase). + /// Repos vary in spelling (e.g. Qwen ships `fp16`, bartowski ships `f16`), + /// so each preset may accept several tags. + pub fn gguf_tags(&self) -> &'static [&'static str] { + match self { + Self::Q4K => &["q4_k_m"], + Self::Q8 => &["q8_0"], + Self::F16 => &["f16", "fp16"], + Self::None => &["f32", "fp32"], + } + } + /// Get bytes per weight pub fn bytes_per_weight(&self) -> f32 { match self { @@ -241,4 +286,43 @@ mod tests { assert_eq!(QuantPreset::from_str("q4k"), Some(QuantPreset::Q4K)); assert_eq!(QuantPreset::Q4K.bytes_per_weight(), 0.5); } + + #[test] + fn test_weights_repo_gguf_twin_for_safetensors_alias() { + // `phi` -> microsoft/Phi-4-mini-instruct hosts safetensors only; a + // quantized request must route to the GGUF twin, not the base repo. + let repo = resolve_weights_repo("phi", QuantPreset::Q4K); + assert_eq!(repo, "bartowski/microsoft_Phi-4-mini-instruct-GGUF"); + assert!(repo.contains("GGUF")); + } + + #[test] + fn test_weights_repo_unquantized_stays_on_base_repo() { + assert_eq!( + resolve_weights_repo("phi", QuantPreset::None), + "microsoft/Phi-4-mini-instruct" + ); + } + + #[test] + fn test_weights_repo_native_gguf_alias_unchanged() { + assert_eq!( + resolve_weights_repo("qwen", QuantPreset::Q4K), + "Qwen/Qwen2.5-14B-Instruct-GGUF" + ); + } + + #[test] + fn test_weights_repo_unknown_id_passes_through() { + assert_eq!( + resolve_weights_repo("custom/model", QuantPreset::Q4K), + "custom/model" + ); + } + + #[test] + fn test_gguf_tags_cover_repo_spelling_variants() { + assert!(QuantPreset::F16.gguf_tags().contains(&"fp16")); + assert_eq!(QuantPreset::Q4K.gguf_tags(), &["q4_k_m"]); + } } diff --git a/docs/adr/ADR-259-ruvllm-darwin-mode-local-mutator.md b/docs/adr/ADR-259-ruvllm-darwin-mode-local-mutator.md index edc8a764a..774afdbf7 100644 --- a/docs/adr/ADR-259-ruvllm-darwin-mode-local-mutator.md +++ b/docs/adr/ADR-259-ruvllm-darwin-mode-local-mutator.md @@ -1,6 +1,6 @@ # ADR-259: ruvllm as Local Mutator Backend for Darwin Mode -**Status:** Implemented (code + unit tests + CLI; live-serve e2e blocked by a ruvllm download bug — see Implementation status) +**Status:** Implemented (code + unit tests + CLI; the download-path bugs that blocked the live-serve e2e are fixed — see Implementation status) ## Implementation status (2026-06-18) @@ -11,11 +11,16 @@ Implemented in `agent-harness-generator` (`@metaharness/darwin`): - `__tests__/ruvllm-mutator.test.ts` — 4 tests vs a real `node:http` mock (success, fence-strip, unreachable→no-op, malformed→no-op). Full darwin suite **354/354** green. -**Honest gap:** the live-serve e2e (evolve against a real local model) is **blocked by a ruvllm -2.1.0 download bug** — `ruvllm download phi` fails on `tokenizer_config.json` (the file is served -via an HTTP 307 redirect that ruvllm does not follow; `curl -L` fetches it fine). So the HTTP -*contract* is verified by unit tests, but an end-to-end run against a served model is pending a -ruvllm fix (or manual model placement). Recommend fixing the redirect-follow in `ruvllm download`. +**Honest gap (updated):** the live-serve e2e (evolve against a real local model) was blocked by +two `ruvllm download` bugs, both now fixed: +1. **HTTP 307 redirect on aux files** (`tokenizer_config.json` etc.) — **fixed 2026-06-18** in + commit `946275a61` (PR #590) via a redirect-following `curl -L` fallback. +2. **GGUF weight downloads** — the remaining gap after PR #590: `get_files_to_download()` sent an + unexpanded glob (`*Q4_K_M.gguf`) literally (404), and the GGUF alias resolved to the + safetensors repo. Fixed (PIR WP0b, issue #846) by expanding the pattern against the real + HuggingFace file listing (`/api/models//tree/`, multi-part GGUF included) and by + routing quantized requests to a registry-defined GGUF twin repo. +With both fixed, an end-to-end run against a served model is unblocked. **Value note (ADR-087):** the mutator is not the quality lever — deterministic and frontier-LLM mutators both hit the 0.985 scorer ceiling. RuvllmMutator's benefit is *operational* (fully local, diff --git a/docs/adr/ADR-305-adopt-latentmesh-adr009-control-loop-spine.md b/docs/adr/ADR-305-adopt-latentmesh-adr009-control-loop-spine.md new file mode 100644 index 000000000..22bf8e820 --- /dev/null +++ b/docs/adr/ADR-305-adopt-latentmesh-adr009-control-loop-spine.md @@ -0,0 +1,255 @@ +# ADR-305: Adopt Autogenous ADR-401 and LatentMesh ADR-009 as the Perpetual Intelligence Runtime's Definition and Control-Loop Spine + +- **Status**: Proposed +- **Date**: 2026-08-19 +- **Deciders**: RuV Perpetual Intelligence Runtime (PIR) Program +- **Related**: ADR-306, ADR-307, ADR-309, ADR-312, ADR-313, ADR-315 (PIR, this program); LatentMesh ADR-009 "Online Causal Control Loop" (LatentMesh repo, 2026-08-18, status Proposed); autogenous ADR-401 "The Perpetual Intelligence Machine" (autogenous repo, 2026-08-16, status Accepted/Partial) and ADR-400 "Self-Evolving Mesh Perpetual Loop" (autogenous repo, status Accepted — Implemented); ruflo ADR-322/322A/322B/322C "Metaharness Flywheel Integration" (ruflo repo, `v3/docs/adr/`, 2026-07-28, status Accepted); see `docs/research/perpetual-intelligence-runtime/04-verification-addendum.md` +- **Tags**: pir, latentmesh, autogenous, control-loop, governance, cross-repo + +## Context + +This program's brief asked for a new cross-mechanism architecture combining +self-evolving physical intelligence, persistent transactional memory, and +verified latent agent communication. Research for this ADR set (see +`docs/research/perpetual-intelligence-runtime/02-asset-map.md`, compiled +2026-08-19) found that architecture already designed, one day earlier, inside +`ruvnet/LatentMesh`'s own +[`docs/adr/009-online-causal-control-loop.md`](https://github.com/ruvnet/LatentMesh/blob/main/docs/adr/009-online-causal-control-loop.md) +(dated 2026-08-18, status "Proposed"). That ADR names a role for every +component in this program's brief — RuFlo, MetaHarness/Darwin, RuVector, +MidStream, Radio, RVF/RVM, RuView, and Autogenous — inside one loop: + +``` +execute → transfer latent state → counterfactual audit (LatentMesh ADR-003) + → measure causal value + → update edge value/authority ceiling (LatentMesh ADR-008) + → persist (LatentMesh ADR-005) + → change topology (LatentMesh ADR-006, Darwin) + → next execution +``` + +LatentMesh ADR-009 states plainly what is built and what is not: *"The +statistical primitive (LatentMesh ADR-003) and admission gate (LatentMesh +ADR-008) are implemented; the closed loop across live components is not +wired."* That is the actual gap this program should close — not a greenfield +design problem. + +**Verification note (updated)**: a second agent (asset-scout) subsequently +cloned `ruvnet/LatentMesh` directly (HEAD `922ea196`, 2026-08-18) and +confirmed the loop diagram and the "not wired" quote above verbatim against +source, including the per-stage "not implemented" markers on ADR-004 through +ADR-008. **One material correction to the asset map's framing: LatentMesh is +a small research prototype, not a substantial codebase.** The entire +workspace is 1,407 LOC across four crates (`latentmesh-core` 272, +`latentmesh-align` 454, `latentmesh-gate` 534, `latentmesh-bench` 147; 23 +tests total) — roughly 1/23rd the size of `ruvector-core` alone. **There is +no network transport crate anywhere in the workspace.** "Adopt LatentMesh +ADR-009 as the spine" means adopting a *design contract* and ~1.4K LOC of +tested primitives (the causal-edge and admission-gate math), not inheriting a +mature system. Every later PIR ADR and work package must be scoped against +that reality — WP5 (wire LatentMesh live, ADR-309) in particular is building +a transport layer that does not exist today, not integrating one. + +LatentMesh's maintainers are also still actively revising scope — the asset +map notes ADR-009 itself was revised twice in one day — so this program's +timeline is exposed to their churn (see `03-program-plan.md`, Top Risks §2). + +## Reconciliation with autogenous ADR-401 (material finding, added post-draft) + +Independent verification of `ruvnet/autogenous` (asset-scout, HEAD `b5c6e838`, +2026-08-19) surfaced a second, materially different finding the original +asset map did not capture: autogenous's ADR sequence runs **391 through 403** +(13 ADRs), not the four the asset map cited (391/392/393/397). The missing +ones include +[`ADR-401-perpetual-intelligence-machine.md`](https://github.com/ruvnet/autogenous/blob/main/docs/adr/ADR-401-perpetual-intelligence-machine.md) +— **"The Perpetual Intelligence Machine," status Accepted (framing + +capability map) · Partial (implementation), dated 2026-08-16** — and +[`ADR-400-self-evolving-mesh-perpetual-loop.md`](https://github.com/ruvnet/autogenous/blob/main/docs/adr/ADR-400-self-evolving-mesh-perpetual-loop.md), +status "Accepted — Implemented (first flywheel turn measured)." This author +independently confirmed ADR-401's content by reading it directly. + +ADR-401 defines a 10-capability map (observe→diagnose→propose→execute→measure→revise, +governed self-improvement, cross-organization intelligence, and more), an +operating loop, and a V1 acceptance test — implemented mostly in +`packages/radio-moe/src/*.ts` (6,171 LOC, 3,161 LOC of tests), not the Rust +crates the asset map described. Several of its capabilities are already +**Built and measured** (e.g. peer-loss recovery at 30% mesh loss, p50 0.34ms; +fused-mixture decision quality beating best-single agent 100% vs 66.7%), +while others are honestly marked Partial, Gap, or Narrative — ADR-401 itself +models the same claims-honesty discipline this program has been trying to +adopt from LatentMesh. It also references a third ADR series it labels +"metaharness ADR-322" (flywheel receipts/promotion) — **that citation is a +misattribution**. A fourth research pass located the actual document at +**`ruvnet/ruflo`, `v3/docs/adr/ADR-322-metaharness-flywheel-integration.md`** +— "Adopt `@metaharness/{flywheel,darwin}` as pluggable engines behind +ruflo's ADR-176 self-improvement flywheel," status Accepted (phases 0–2 +implemented), dated 2026-07-28. `ruvnet/metaharness` (the renamed +`agent-harness-generator`) has its own 230-ADR series topping out at +ADR-250 — no ADR-322 exists there. **This program cites the dependency as +"ruflo ADR-322" going forward; every reference to it elsewhere in this +program's documents should be corrected to match** (see +`04-verification-addendum.md` §5). + +ruflo ADR-322 has a directly load-bearing implementation detail for this +program: its child ADR-322B states, verbatim, *"A proposer produces +untrusted candidates only. It cannot issue promotion decisions or mutate +active policy."* This is the same separation-of-powers boundary autogenous +ADR-401's capability-5 table row describes as "not yet one checked +predicate" — **but that row is stale relative to ADR-401's own Decision +section.** ADR-401's **Update 1 §3, "Converge the promotion invariant to one +predicate," is marked DONE**: `mesh-evolve.ts` exports +`promoteAuthorized(candidate, champion, { authorized, reversible }) → +PromotionDecision`, the single gate `Promote = Better ∧ Safe ∧ Authorized ∧ +Reversible`, with each conjunct independently blocking and +`evolveMesh` routing every promotion through it — proven by +`test/promote-authorized.test.ts` (all-four promotes; any three-of-four does +not). This program cites the Decision section, not the stale capability +table, as ADR-401's authoritative status on this point (see ADR-315 for the +corrected scope this implies). ruflo ADR-322A independently implements the +same separation as one atomic transaction (`promoteFlywheelCandidate` as +sole promotion authority, verified under 100 concurrent promotion attempts +producing exactly one commit). This program +adopts that separation-of-powers invariant as a **governing invariant**, +alongside the six carried from the original brief (see Decision §3 below). + +**This changes the decision below**: LatentMesh ADR-009 is a *proposed, +unwired, ~1.4K-LOC integration contract*. Autogenous ADR-400/401 are +**Accepted, partially-to-fully implemented, with measured results**, and +ADR-401 is, on its face, largely the same product this program's brief +describes. WP1 must read ADR-401 in full and choose explicitly between +adopting/extending it or stating in writing why the PIR program defines a +parallel Perpetual Intelligence Machine — silently re-deriving an Accepted +ADR-401 across this program's other ten ADRs would be the worst outcome this +program could produce. + +## Decision + +The Perpetual Intelligence Runtime does **not** define its own product +framing or its own cross-mechanism architecture. It adopts two existing, +already-Proposed-or-Accepted decisions from sibling repos, at two different +levels: + +1. **Program definition of record**: PIR adopts autogenous ADR-401's + 10-capability map, its "perpetual means operational continuity, not + infallibility" framing, and its V1/30-day acceptance-test structure as the + program's own definition of what is being built and how it will be judged + done. Where a PIR ADR in this set (ADR-306 through ADR-315) covers ground + ADR-401 already scores as Built or Partial, that PIR ADR must say so + explicitly and describe itself as closing ADR-401's named gap, not as + introducing a new capability. +2. **Communication-fabric design contract**: PIR adopts LatentMesh ADR-009's + seven-stage online causal control loop (execute → transfer → counterfactual + audit → measure → update authority → persist → evolve topology) as the + design contract specifically for the Latent Communication Fabric bounded + context (ADR-309, ADR-310, ADR-311) — the one part of ADR-401's capability + map (capability 6/7 boundary-crossing communication) that autogenous's own + repo does not itself implement. +3. PIR work packages are scoped to close the gaps **both** ADRs already + declare — LatentMesh ADR-009's "closed loop not wired" and autogenous + ADR-401's own Partial/Gap rows — not to re-derive either document's + claims. autogenous ADR-400/401 cite "metaharness ADR-322" for flywheel + receipts/promotion; that citation is a misattribution corrected above — + the actual document is **ruflo ADR-322** (Accepted, phases 0–2 + implemented), and its child ADR-322B's separation-of-powers invariant + ("a proposer produces untrusted candidates only; it cannot issue + promotion decisions or mutate active policy") is adopted here as a + seventh governing invariant alongside the six carried from the brief, + binding on every PIR ADR that defines a mutation-proposal or + promotion-decision mechanism (ADR-306, ADR-313, ADR-315). +4. A coordination channel is opened with both the `ruvnet/LatentMesh` and + `ruvnet/autogenous` maintainers before any ADR in this program assigns a + number, or makes a claim, that could conflict with either repo's own ADR + sequence. Every cross-repo ADR reference in this program's documents must + name the owning repo explicitly (e.g. "LatentMesh ADR-009", "autogenous + ADR-401", "ruvector ADR-134") — the asset map documents an ADR-103 + numbering collision across repos (ruvector's ADR-103 is unrelated to the + witness/fix-manifest ADR-103 that lives in claude-flow/Ruflo), and this + program must not create a second instance of that ambiguity. +5. The program's committed first work package (WP1) is, before any other PIR + work starts: (a) read autogenous ADR-401 in full and produce the + explicit adopt/diverge decision required above, (b) confirm LatentMesh + ADR-009's loop against source (done — see Verification note), (c) + confirm ruflo ADR-322/322A/322B/322C against source (**done**: cloned + directly, HEAD `fa13ee4`, 2026-08-15; the separation-of-powers quote, + the 322C canonical-encoding/signature stack including its three signing + domains, and the evidence-grading vocabulary all check out verbatim — + see `04-verification-addendum.md` §8), and (d) apply the **fix-history + verification rule** below to every remaining inherited claim this + program has not yet independently checked. +6. **Fix-history verification rule (added after PR #847 review)**: an + inherited "known bug," "gap," or "not yet implemented" claim from any + source document — the program brief, an upstream ADR, or a prior research + pass in this program itself — must be checked against that path's actual + fix history (`git log` on the named file/module, the owning repo's + release notes or merged PRs) before being repeated in a PIR ADR. It is + not sufficient that the asserting document's prose says the bug is open. + This rule exists because all three of this ADR set's blocking review + findings (ADR-401's promotion predicate, the "metaharness ADR-251" + citation, and the ADR-150 misattribution — see ADR-315, ADR-306, ADR-313) + shared the same root cause: a claim was carried forward from an upstream + document without checking whether upstream's own state had since moved + past it, or whether the citation resolved to a real document at all. The + `ruvllm` HTTP-307 bug ADR-313 originally cited as open (later found + already fixed on `main`, commit `946275a61`) is the concrete instance + that surfaced this pattern. + +## Consequences + +### Positive + +- Avoids duplicating a design that already exists and is already + cross-component-aware; every later PIR ADR gets a concrete loop stage to + attach to instead of inventing placement. +- Forces early cross-repo coordination instead of discovering a conflict + after multiple ADRs and work packages are already built on a diverging + architecture. +- Inherits LatentMesh ADR-009's own honesty discipline (narrowing its novelty + claims against StateBridge/LatentMAS/MANTA/E2-Explainer) as the model for + how this program's own ADRs should be written. + +### Negative + +- Couples this program's schedule to a repo it does not control, whose + maintainers are still actively revising scope (twice in one day, per the + asset map). +- The loop's accuracy has not been independently verified by this program as + of this ADR — see the Verification note above. If WP1's direct read of + LatentMesh ADR-009 contradicts the asset map's summary, every downstream + PIR ADR that assumes this loop shape needs re-review. +- Adds an explicit dependency: no PIR work package that assigns cross-repo + ADR numbers may proceed until the LatentMesh coordination channel exists. + +## Security / Validation Gates + +- **Cross-repo ADR-numbering discipline**: every reference to a non-`ruvector` + ADR in any PIR document must name the owning repo. This is a documentation + gate, not a code gate, but it is treated as a blocking requirement for WP1 + sign-off given the asset map's documented ADR-103 collision precedent. +- **Hosted-RVM honesty discipline** (carried from ruvector ADR-285): any + claim this program makes about LatentMesh's or RVM's isolation/verification + strength must match what has actually been tested, not what is aspired to. + +## Affected Repos + +- `ruvnet/LatentMesh` (primary — architecture spine, coordination target) +- `ruvnet/ruvector` (RuVector, RVF, RVM, ruvLLM components named in the loop) +- `ruvnet/rvm` (witness/capability enforcement referenced by the loop) +- `ruvnet/autogenous` (governance role named in the loop) +- `ruvnet/RuView` (sensing role named in the loop) + +## Dependencies + +None — this is the foundational ADR for the PIR program. ADR-306, ADR-307, +ADR-309, and ADR-312 each depend on this ADR's adoption decision. + +## Alternatives Considered + +- **Design a new cross-mechanism architecture from scratch**: rejected — the + asset map's headline finding is that this would duplicate work already done + one day earlier in a sibling repo, and would create exactly the kind of + cross-repo architectural conflict this ADR is written to avoid. +- **Fork LatentMesh ADR-009's loop into a `ruvector`-local copy instead of + coordinating with LatentMesh**: rejected — forking invites drift between + the two repos' understanding of the loop, which is the same failure mode + the asset map warns against for the RVM/Autogenous witness-crate + duplication (see ADR-312). diff --git a/docs/adr/ADR-306-dream-machine-sona-darwin-unification.md b/docs/adr/ADR-306-dream-machine-sona-darwin-unification.md new file mode 100644 index 000000000..3569781b5 --- /dev/null +++ b/docs/adr/ADR-306-dream-machine-sona-darwin-unification.md @@ -0,0 +1,187 @@ +# ADR-306: Dream Machine — Adopt the Consolidating Evaluation Engine, Wired to research-gate and Darwin + +- **Status**: Proposed +- **Date**: 2026-08-19 +- **Deciders**: RuV Perpetual Intelligence Runtime (PIR) Program +- **Related**: ADR-305 (PIR, depends on); ADR-312 (PIR, shares verification stack); ADR-313 (PIR, downstream consumer); ruvector ADR-282 (research-gate); ruflo ADR-322/322A/322B/322C (flywheel integration, Accepted — verified against source); ruflo ADR-381 (Proposed — stream identity + budget-exhaustion recovery only, not the statistics; see Context); ruflo PR #2956 (the anytime-valid statistics mechanism itself); dream-machine ADR-0001 (Accepted, engine v0.1.0 shipped); metaharness `docs/dream-cycle/` (Nightly Dream Cycle — not an ADR; corrects "metaharness ADR-251," which does not exist); see `docs/research/perpetual-intelligence-runtime/04-verification-addendum.md` §6, §8 +- **Tags**: pir, dream-machine, promotion, evaluation, cross-repo + +## Context + +Invariant 5 of the program is: *"every promoted mutation must outperform its +parent."* This ADR's premise changed twice during research for this program +(see `04-verification-addendum.md` §6 for the full trail): + +1. **First pass**: no asset named "Dream Machine" exists; the closest + analogue is SONA's dream-replay engine (`05-MEMORY-DREAMS.md`), and this + would be a from-scratch build. +2. **Second pass**: real, CI-wired, cryptographically-signed statistical + promotion machinery already exists inside `ruvector` under a different + name — `scripts/research-gate/` + `.github/workflows/research-*.yml`, + backed by `crates/ruvector-sota-bench/harness` (`statistics.ts` paired + bootstrap, `vetoes.ts` hard vetoes, `flywheel.ts` Ed25519-signed replay + bundles), documented in ruvector ADR-282. This significantly de-risked + what had been flagged as the program's top risk. +3. **Third pass (this ADR)**: **a literal `ruvnet/dream-machine` repo + exists**, is real, public, published to npm, and its own **ADR-0001** is + Accepted with engine v0.1.0 shipped (compile / ledger / witness / + schedule / memory modules, CLI/TUI, 85 tests, ~2,558 LOC). Its thesis: + *"Freeze the model. Evolve the harness. **Evaluation is not promotion — + the machine never merges; a human does.**"* It composes + `@metaharness/flywheel`, `@metaharness/darwin`, `@metaharness/redblue`, + the `metaharness` CLI, `ruvector`, and `agentdb` as optional/peer + dependencies, and its own text names two prior instances it + **subsumes**: `ruvnet/ruflo`'s nightly dream cycle and, per its own + "Prior instances" line, "metaharness ADR-251 (MetaHarness Nightly Dream + Cycle)." **That second citation does not exist and this ADR does not + restate it as fact**: `ruvnet/metaharness`'s ADR series is 230 files + topping out at `ADR-250-sota-proof-ladder.md` — no ADR-251. Its Nightly + Dream Cycle material instead lives in `docs/dream-cycle/` + (`2026-08-13-gist.md`, `2026-08-14-gist.md`, `LEDGER.md`), not as an ADR. + The bad citation is inherited from dream-machine ADR-0001's own text, + noted here as its provenance rather than independently verified. + +**"Dream Machine" therefore now exists in four places**, and this program +must name which is canonical for which layer rather than building a fifth: + +| Layer | Canonical implementation | +|---|---| +| Generalized, product-level evaluation engine (compile/ledger/witness/schedule/memory, CLI/TUI) | `ruvnet/dream-machine` ADR-0001 (Accepted, v0.1.0 shipped) | +| Statistical significance + hard vetoes + signed replay bundles, already CI-wired inside `ruvector` | `ruvector` ADR-282 (`scripts/research-gate/`, `crates/ruvector-sota-bench/harness`) | +| Evaluation↔promotion transaction model, separation of proposer vs. promotion authority | ruflo ADR-322/322A/322B (Accepted — implemented; see ADR-305, ADR-313) | +| Sequential/anytime-valid statistical evidence across adaptively-chosen candidates | ruflo **PR #2956** (the mechanism: `α_k = α_total·6/(π²k²)`, 0.6% measured family-wise false-promotion rate over 1,000 simulated nulls, bound holds **per epoch**); ruflo **ADR-381** (Proposed — governs stream identity and budget-exhaustion recovery *over* that mechanism, not the statistics themselves) | +| Earlier reference instances, now subsumed | `ruvnet/ruflo` nightly dream cycle; `ruvnet/metaharness` `docs/dream-cycle/` (not an ADR — see above) | + +**Version drift**: `ruvnet/dream-machine` composes `@metaharness/darwin` +0.9.1 / `@metaharness/flywheel` 0.1.10; `ruvector` currently pins `darwin` +0.8.0 / `flywheel` 0.1.7. This program's WP0b (MetaHarness +dependency-compliance remediation) should account for this drift when it +fixes the `optionalDependencies` non-compliance documented in +`METAHARNESS-README.md` (see ADR-313 for the source citation — the policy is +ruflo ADR-150, "MetaHarness Integration Surfaces in `npx ruflo`," Implemented +2026-06-16; neither `ruvector`'s nor `metaharness`'s own ADR-150 is the right +document, both being unrelated). + +## Decision + +The Perpetual Intelligence Runtime does not build a new evaluation service. +It **adopts `ruvnet/dream-machine`'s engine (ADR-0001) as the evaluation +core**, wired to `ruvector`'s already-CI-integrated statistical layer: + +1. `ruvnet/dream-machine`'s compile/ledger/witness/schedule/memory pipeline + becomes the orchestration layer for PIR's mutation-evaluation cycle, + consuming Darwin mutation proposals (`@metaharness/darwin`, per ADR-313) + and producing evidence-gated verdicts. +2. `ruvector` ADR-282's `research-gate` (`statistics.ts` paired bootstrap, + `vetoes.ts` hard vetoes, `flywheel.ts` Ed25519-signed replay bundles) + supplies the statistical significance layer dream-machine's own engine + calls into for `ruvector`-hosted mutation evaluation — this program does + not reimplement paired-bootstrap significance testing a second time. +3. SONA's dream-replay engine (`05-MEMORY-DREAMS.md`) remains an optional + pre-filter feeding candidates into this pipeline before the more + expensive statistical evaluation runs, not a replacement for it. +4. The evaluation↔promotion transaction boundary follows ruflo ADR-322A/ + 322B: an evaluation verdict is advisory input, never a promotion + decision in itself. +5. **Dream-machine's constitutional principle is adopted and is not + negotiable within this program: "Evaluation is not promotion — the + machine never merges; a human does."** This exact sentence is verbatim in + dream-machine's `README.md` (L19–20) and `packages/cli/README.md`, not in + ADR-0001 itself — ADR-0001 §2.4 states the same substance in its own + words: *"Evaluation is not promotion. The session never merges, never + self-promotes flywheel state…"* and *"Promotion is a human act."* This + ADR cites the README's phrasing because it is the more quotable form, and + attributes it to the repo rather than to ADR-0001 specifically. Automated + gates (research-gate's statistics, dream-machine's ledger/witness + pipeline, ruflo's promotion transaction) may recommend promote/reject; + only a human-authorized action performs the final merge into an active + policy or codebase. This constrains the frozen-weights-and-governed-mutation + loop this program builds (ADR-313, ADR-315) — no PIR work package may + wire an unattended `/loop`-style auto-merge path, mirroring ADR-0001's + own explicit phase-3/4 gating of unattended promotion pending separate + privilege, spend, and rollout controls. + +## Consequences + +### Positive + +- Converts what was the program's single largest identified risk (building + a promotion-evaluation system from nothing) into a consolidation task + across four already-Accepted-or-implemented pieces of prior art. +- Inherits ruflo PR #2956's measured statistical guarantee (0.6% family-wise + false-promotion rate, per epoch) instead of needing to re-derive or + re-validate a sequential-testing scheme from scratch; ADR-381 (Proposed) + layers stream-identity and budget-recovery governance on top of that + already-implemented mechanism. +- The "evaluation is not promotion, a human merges" principle gives + invariant 5 a hard human-in-the-loop backstop, directly addressing the + acceptance test's "zero unapproved capability expansion" requirement + (ADR-315) at the evaluation layer as well as the constitutional layer. + +### Negative + +- Four separate prior instances (dream-machine, ruflo dream cycle, + metaharness `docs/dream-cycle/`, ruvector research-gate) must be reconciled into one + coherent pipeline for this program; no repo checked by this program's + research passes has published that reconciliation yet — it is WP1/WP2's + deliverable, not a pre-existing fact this ADR can cite. +- Adds a real external dependency (`ruvnet/dream-machine`, v0.1.0, a young + shipped engine) to `ruvector`'s promotion pipeline, with its own version + churn risk on top of the already-identified `@metaharness/*` version + drift. +- The "a human merges" principle is a deliberate throughput ceiling: it + rules out a fully unattended 30-day acceptance run unless the acceptance + harness (WP12) is itself designed around scheduled human checkpoints + rather than continuous autonomous promotion — a scope clarification this + ADR surfaces but does not resolve. + +## Security / Validation Gates + +- **Proof-gated promotion**: `ruvector-proof-gate`/`rvm-proof` (ruvector + ADR-227 and sibling RVM ADRs) still gates every promotion; dream-machine's + verdict and research-gate's statistical result are inputs to that gate, + never a bypass of it. +- **Witness-chain requirement**: every verdict (promote or reject) emits an + RVM witness record (ruvector ADR-134 schema); this program's shared + witness/anchoring contract (ADR-312) is the mechanism that makes + dream-machine's own ledger/witness modules and RVM's witness chain + cross-verifiable. +- **Human-merge constitutional gate**: no CI or scheduled-worker path may + execute a final merge/promotion without an explicit human-authorized + action recorded in the witness chain, per ADR-0001's principle adopted + above. +- **Standard repo gate**: `npx @claude-flow/cli@latest security scan` after + any change to the promotion pipeline's signing or verification code. + +## Affected Repos + +- `ruvnet/dream-machine` (adopted engine, external dependency) +- `ruvnet/ruvector` (`scripts/research-gate/`, `crates/ruvector-sota-bench/harness`, ADR-282; SONA dream-replay) +- `ruvnet/ruflo` (ADR-322/322A/322B transaction model — Accepted, verified verbatim against source; PR #2956 — the sequential-statistics mechanism; ADR-381 — Proposed, stream-identity/budget-recovery governance only) +- `ruvnet/metaharness` (`docs/dream-cycle/`, prior reference instance — not an ADR) + +## Dependencies + +Depends on ADR-305 (adopts the control-loop and cross-repo coordination +posture this evaluation core plugs into). Shares its verification stack with +ADR-312. ADR-313 (SHAPER-pattern evolution loop) depends on this ADR — +Darwin's mutation proposals need a verdict from this pipeline before +promotion. + +## Alternatives Considered + +- **Build a new evaluation service from scratch** (the program's original + framing): rejected — three separate research passes converged on the fact + that this would duplicate at least four existing pieces of prior art, the + newest of which (`ruvnet/dream-machine`) is already shipped and Accepted. +- **Adopt only `ruvector` ADR-282's research-gate and ignore + `ruvnet/dream-machine`**: rejected — research-gate is a strong statistical + layer but does not provide dream-machine's orchestration (compile/ledger/ + schedule/memory/CLI-TUI) layer, and ADR-0001 explicitly positions itself + as the consolidating design other implementations should align with. +- **Allow unattended promotion once statistical significance is met**: + rejected — contradicts ADR-0001's explicit constitutional principle and + autogenous ADR-401's own admission that its `Better ∧ Safe ∧ Authorized ∧ + Reversible` promotion predicate is not yet fully closed; keeping a human + merge step is the safer default until that predicate is fully wired and + independently audited. diff --git a/docs/adr/ADR-307-three-level-persistent-memory-livemem-tarl.md b/docs/adr/ADR-307-three-level-persistent-memory-livemem-tarl.md new file mode 100644 index 000000000..bfd166fa0 --- /dev/null +++ b/docs/adr/ADR-307-three-level-persistent-memory-livemem-tarl.md @@ -0,0 +1,142 @@ +# ADR-307: Three-Level Persistent Memory Architecture (LiveMem + TARL Pattern) on RuVector + +- **Status**: Proposed +- **Date**: 2026-08-19 +- **Deciders**: RuV Perpetual Intelligence Runtime (PIR) Program +- **Related**: ADR-305 (PIR, depends on); ADR-309 (PIR, depends on this) +- **Tags**: pir, memory, livemem, tarl, rvf, rvm, witness + +## Context + +Invariants 1 and 2 of the program require: *"every observation may change +memory"* and *"every memory change is transactional."* Per +`docs/research/perpetual-intelligence-runtime/01-evidence-review.md`, two +grade-A primary sources ground the design of a persistent memory tier: + +- **LiveMem** — [arXiv:2608.02515](https://arxiv.org/abs/2608.02515), + "LiveMem: Maintaining Memory State Continuity in Long-Running LLM + Inference," submitted 2026-08-03 (v1), revised 2026-08-07 (v2). Confirms a + fixed-capacity memory state whose lifetime is independent of the active + context, maintained via a parallel memory branch (Gated DeltaNet-2 + backbone) alongside a bounded KV attention window, reframing long-running + inference as "computational state preservation." The system can answer + questions from memory state after supporting evidence has left the context + window. Grade A — evidence review flags a name collision with an unrelated + consumer iOS app ("LiveMem – Live Photo Editor"); this ADR always means the + arXiv paper. +- **TARL (Transaction-Aware Reliable Ledgers)** — + [arXiv:2608.03699](https://arxiv.org/abs/2608.03699), "TARL: + Transaction-Aware Reliable Ledgers for Executable Memory Management in + Long-Term Agents," submitted 2026-08-04 (v1), revised 2026-08-11 (v2). + Confirms a five-operation executable ledger — add / ignore / + revise-outdated-belief / reject-unreliable / defer-for-verification — with + accepted, pending, and rejected ledgers, explicitly framed as reducing + "memory pollution" and limiting cumulative corruption. Grade A. **This name + is heavily overloaded in prior literature** (Taint Analysis and + Reinforcement Learning, arXiv:2005.03813; Target-Aligned Reinforcement + Learning, arXiv:2603.29501; an unrelated `xushoukai/TARL` GitHub repo) — + none of which relate to agent memory ledgers. "TARL (Transaction-Aware + Reliable Ledgers)" is spelled out here on first use, and every subsequent + reference to TARL in this program's documents should do the same. + +RuVector already provides the durable substrate these two patterns need: +RVF (`crates/rvf` — append-only crash-safe segments, progressive indexing, +post-quantum signatures, canonical format per ruvector ADR-029) and RVM +(`crates/rvm` — mandatory hash-chained witness records for every privileged +action, per ruvector ADR-134). + +**Revised scope (per the deep-researcher's asset-map revision)**: the +three-tier architecture below is not a from-scratch build. Each tier already +has a concrete home in `ruvector`'s existing memory stack, and proof-gated +writes for that stack **already exist** (ruvector ADR-194, ADR-047) — meaning +"sign every memory transition via RVM witness records" is largely already +built for the underlying gate, not net-new. The net-new work this ADR +actually scopes is the TARL five-operation ledger *states and semantics* +layered on top of that existing proof-gate, not the gate itself. + +## Decision + +Implement three explicit memory tiers, formalizing components that mostly +already exist in `ruvector` rather than building three new stores: + +1. **Working context** — maps to `ruvllm`'s `working_memory` module, + unchanged by this ADR. +2. **Continuous latent state** — maps to `ruvllm`'s + `episodic_memory`/`semantic_cache`/`agentic_memory` modules, formalized to + follow LiveMem's fixed-capacity recurrent-state design (arXiv:2608.02515): + capacity is bounded and independent of context length, so state can + outlive whatever evidence originally produced it. +3. **Transactional RuVector memory** — maps to `ruvector-agent-memory` + (ruvector ADR-252) plus `reasoning_bank` and `ruvector-temporal-coherence` + (ruvector ADR-211), extended with TARL's five-operation ledger + (arXiv:2608.03699): every incoming statement maps to exactly one of add / + ignore / revise-outdated-belief / reject-unreliable / defer-for-verification, + with accepted, pending, and rejected ledger states persisted via RVF and + signed via the RVM witness records this tier's writes already produce + (ruvector ADR-194, ADR-047, ADR-134 schema). + +No incoming observation writes directly to the transactional tier without +passing through the TARL-style operation classification — this is what makes +invariant 2 ("every memory change is transactional") enforceable rather than +aspirational, on top of the write-path proof-gating that already exists. + +## Consequences + +### Positive + +- Both source patterns are grade-A, independently verifiable primary sources + — this ADR can cite concrete published mechanisms rather than inventing an + architecture from the brief's prose alone. +- The TARL ledger's reject/defer states give the program a structural answer + to memory poisoning (invariant 2), not just an append-only log that trusts + every write. +- Reuses RVF/RVM's existing durability and witness primitives rather than + building a parallel persistence layer. + +### Negative + +- Neither paper's reference implementation is open-sourced as of the + evidence review; this program is implementing the *pattern* described in + each paper's abstract and methodology, not integrating existing code — the + behavioral fidelity to each paper's reported properties is unverified until + this program's own implementation is tested against comparable benchmarks. +- Three explicit tiers add operational complexity (three storage/lifecycle + policies to reason about) versus a single undifferentiated memory store. +- The middle (continuous latent state) tier's fixed capacity means it can + legitimately forget — this is a design tradeoff, not a bug, but it must be + documented clearly so downstream consumers (e.g. ADR-309's latent + communication fabric) do not assume unbounded retention. + +## Security / Validation Gates + +- **Witness-chain requirement**: every state transition in this tier — + every TARL ledger operation (add/ignore/revise/reject/defer) and every + continuous-latent-state checkpoint — must emit an RVM witness record + (ruvector ADR-134 schema) before it is considered committed. No RVF write + without a corresponding witness entry. +- **Standard repo gate**: `npx @claude-flow/cli@latest security scan` after + any change to the ledger's write path, since it is a direct target for the + memory-poisoning attacks this design is meant to resist. + +## Affected Repos + +- `ruvnet/ruvector` (`crates/rvf`, `crates/rvm`, `crates/ruvector-core`) +- `agentdb` (memory subsystem consumer of this tiering) + +## Dependencies + +Depends on ADR-305 (adopts the control-loop this tier is embedded in). ADR-309 +(wiring LatentMesh live) depends on this ADR for RVF/RVM provenance wiring on +the memory-ledger side of latent communication. + +## Alternatives Considered + +- **A single undifferentiated memory store instead of three tiers**: + rejected — collapses the working-context/continuous-state/transactional + distinction that both source papers treat as load-bearing, and removes the + structural basis for enforcing invariant 2. +- **Build the transactional ledger without the TARL five-operation + classification (plain accept-or-reject)**: rejected — TARL's + revise-outdated-belief and defer-for-verification states are what let the + ledger correct itself over time rather than only ever accumulating or + discarding; a binary scheme loses that self-correction path. diff --git a/docs/adr/ADR-308-worldcycle-verification-physical-action-loop.md b/docs/adr/ADR-308-worldcycle-verification-physical-action-loop.md new file mode 100644 index 000000000..675dbaffb --- /dev/null +++ b/docs/adr/ADR-308-worldcycle-verification-physical-action-loop.md @@ -0,0 +1,118 @@ +# ADR-308: WorldCycle-Style Verification for the Physical Action Loop + +- **Status**: Proposed +- **Date**: 2026-08-19 +- **Deciders**: RuV Perpetual Intelligence Runtime (PIR) Program +- **Related**: ADR-313 (PIR, depends on); ADR-306 (PIR, downstream consumer) +- **Tags**: pir, worldcycle, verification, physical-action, evaluation + +## Context + +Invariant 6 of the program requires: *"every physical action produces new +evidence."* Per +`docs/research/perpetual-intelligence-runtime/01-evidence-review.md`, this is +grounded in a grade-A source: + +- **WorldCycle** — [arXiv:2608.04964](https://arxiv.org/abs/2608.04964), + "WorldCycle: Self-Verifiable Reinforcement Learning for Long-Horizon Video + World Models," submitted 2026-08-05. The abstract states verbatim: + "WorldCycle reduces state returning drift by up to 44% and lifts + composite-action accuracy nearly 4x over the base model." A diagnostic + benchmark, CycleBench, ships alongside it. The mechanism: verification + signals derived from reversible/closed action cycles — an action sequence + plus its inverse should return to the initial state — used for + annotation-free supervision. Grade A, exact figure match against the + program brief; no name collision found in the evidence review's search. + +This paper's reversible-action-sequence verification is exactly the kind of +"new evidence" invariant 6 asks for: an executed action either returns the +world to a predictable state (when composed with its inverse) or it does not, +and that discrepancy is itself evidence usable for supervision, independent +of any external label. + +## Decision + +Adopt WorldCycle's reversible-action-sequence verification (arXiv:2608.04964) +as an explicit stage in the physical action loop, positioned between +"observe consequences" and "Dream Machine evaluation" (ADR-306). Concretely: + +1. For every executed physical action sequence where a reasonable inverse + exists, construct the inverse sequence and measure state-return drift + against the pre-action state. +2. Use the drift measurement as an annotation-free verification signal fed + into the mutation's evaluation record, alongside whatever supervised or + task-specific signals already exist. +3. Adopt the paper's reported figures — **up to 44% long-horizon drift + reduction and ~4x composite-action accuracy** over an unverified baseline — + as the acceptance bar for this program's Phase 3 world-model component. + This program has not yet run its own CycleBench-equivalent benchmark; the + 44%/4x figures are the paper's reported results on its own benchmark, not + yet confirmed against this program's task set. This ADR commits to + re-measuring against CycleBench or an internal equivalent before treating + the figures as validated in this program's context. + +## Consequences + +### Positive + +- Gives invariant 6 a concrete, annotation-free verification mechanism + instead of relying solely on external task-success labels, which are + expensive and may not exist for every physical action. +- The reversible-action-cycle technique composes cleanly with Dream Machine + (ADR-306): drift measurements are exactly the kind of pre-filter signal + Dream Machine's dream-replay stage is meant to cheaply evaluate. +- Grade-A, exact-figure-match evidence — this ADR can cite a concrete + acceptance bar rather than an aspirational one. + +### Negative + +- Not every physical action has a well-defined, safe-to-execute inverse + (e.g. destructive or irreversible actions); this ADR does not specify a + fallback verification path for that case, which is an open implementation + question for the owning work package (WP10). +- The 44%/4x figures come from CycleBench, a benchmark this program has not + reproduced; treating them as this program's acceptance bar before + re-measurement risks anchoring on numbers that may not transfer to PIR's + actual task distribution. +- Adds execution cost: every verified action sequence now also requires + executing (or simulating) its inverse, which is not free in a physical or + physically-simulated environment. + +## Security / Validation Gates + +- **Proof-gated promotion**: drift-verification results feed into the same + `ruvector-proof-gate`/`rvm-proof` promotion path as Dream Machine's verdict + (ADR-306) — this ADR does not introduce a separate, unaudited promotion + path. +- **Structural frozen-weights enforcement** (shared with ADR-313): the + verification stage must not introduce a code path that could be mistaken + for a fine-tuning signal on the frozen foundation model — drift + measurements feed the mutation-evaluation record, never a gradient update. +- **Witness-chain requirement**: each drift-verification result is logged to + the witness chain (ruvector ADR-134 schema) as part of the mutation's + evaluation record, so it is auditable alongside the eventual promotion + decision. + +## Affected Repos + +- `ruvnet/ruvector` (`crates/ruvector-nervous-system`; new crate + `ruvector-worldcycle-verify`, per `03-program-plan.md`'s Crates section) + +## Dependencies + +Depends on ADR-313 (SHAPER-pattern skill/harness evolution loop) — this +verification stage sits inside the physical action loop that ADR-313's +mutation surfaces produce candidates for. ADR-306 (Dream Machine) is a +downstream consumer of this stage's drift-verification signal. + +## Alternatives Considered + +- **Rely only on external task-success labels for invariant 6**: rejected — + labels are expensive, not always available for physical actions, and do + not by themselves establish that "new evidence" was produced by the action + as invariant 6 requires. +- **Adopt WorldCycle's full video-world-model architecture, not just its + verification signal**: rejected as out of scope for this ADR — the program + brief and evidence review both frame WorldCycle's contribution to this + program narrowly as its annotation-free verification mechanism, not a + replacement for PIR's own physical-action execution stack. diff --git a/docs/adr/ADR-309-latentmesh-greenfield-crates-wire-format-coordination.md b/docs/adr/ADR-309-latentmesh-greenfield-crates-wire-format-coordination.md new file mode 100644 index 000000000..528ee280d --- /dev/null +++ b/docs/adr/ADR-309-latentmesh-greenfield-crates-wire-format-coordination.md @@ -0,0 +1,132 @@ +# ADR-309: Build LatentMesh Integration Inside ruvector as New Crates, Coordinated on Wire Format + +- **Status**: Proposed +- **Date**: 2026-08-19 +- **Deciders**: RuV Perpetual Intelligence Runtime (PIR) Program +- **Related**: ADR-305 (PIR, depends on); ADR-307 (PIR, depends on); ADR-310, ADR-311 (PIR, depend on this); LatentMesh ADR-003, ADR-005, ADR-006, ADR-008 (LatentMesh repo); ruvector ADR-159 (rvagent-a2a) +- **Tags**: pir, latentmesh, greenfield, cross-repo, transport + +## Context + +Invariant 3 of the program requires: *"every agent communication is +attributable."* The original framing of this work package described it as +"wiring LatentMesh live" — implying an existing integration that merely +needed its remaining pieces connected. Direct verification (see +`04-verification-addendum.md` §1) corrects that framing on two points: + +1. **Inside `ruvector`, there is zero existing wiring to `ruvnet/LatentMesh` + today.** The only trace is an unmerged branch, `origin/docs/link-latentmesh`. + It is not cloned locally and not integrated with RuVector in any shipped + form. +2. **`ruvnet/LatentMesh` itself is a small research prototype**, not a + mature system to integrate against: 1,407 LOC across four crates + (`latentmesh-core` 272, `latentmesh-align` 454, `latentmesh-gate` 534, + `latentmesh-bench` 147; 23 tests total), and **there is no network + transport crate anywhere in its workspace**. LatentMesh's own ADR-009 + confirms this: the statistical primitive (ADR-003) and admission gate + (ADR-008) are implemented, but network transport, RVF packaging, and RVM + enforcement wiring are all explicitly marked "not implemented" — + externally, not just inside `ruvector`. + +This changes the work's nature: this is greenfield engineering inside +`ruvector`, coordinated against an external, evolving, small-scale design +contract — not an integration task against existing code on either side. + +## Decision + +Build the `ruvector`-side LatentMesh integration as **new crates**, not as a +completion of an existing integration: + +1. House the new crates under `crates/rvAgent/`, alongside the existing + `rvagent-a2a` (ruvector ADR-159), or as a new `latentmesh` crate family — + the exact placement is an implementation decision for the owning work + package, not fixed by this ADR. +2. Implement, inside `ruvector`, the three pieces LatentMesh's own ADRs mark + as not implemented anywhere: network transport, RVF packaging (model + identity, transform, permitted recipients, provenance, witness history as + artifact metadata, per LatentMesh ADR-008), and RVM `rvm-cap` admission + enforcement. +3. Open an explicit, standing coordination channel with the + `ruvnet/LatentMesh` maintainers so the two sides converge on one wire + format rather than diverging — this program does not unilaterally define + a wire format LatentMesh's own crates (`latentmesh-core`, + `latentmesh-align`, `latentmesh-gate`) must then be retrofitted to match. +4. The acceptance bar for this work package is a live multi-agent task + running LatentMesh's causal-edge verification (LatentMesh ADR-003) + end-to-end for the first time from `ruvector` — per LatentMesh ADR-009, + this has never been run against a live multi-agent task anywhere, inside + or outside `ruvector`. + +## Consequences + +### Positive + +- Scoping this as greenfield construction (not integration) sets accurate + expectations for the owning work package's effort and timeline — a + transport layer does not exist on either side of this coordination and + must be built, not merely wired. +- A live first run of LatentMesh's causal-edge verification would be a + genuine first for the mechanism anywhere in the `ruvnet` org, not just for + this program. +- Coordinating on wire format from the start avoids the two sides + independently building incompatible transports and discovering the + mismatch late. + +### Negative + +- This is real, unstarted engineering effort on a mechanism (causal-edge + latent communication) with no live precedent anywhere — schedule risk is + the program's own top-ranked risk as of this research pass (see + `03-program-plan.md`, Top Risks §1). +- LatentMesh's maintainers are still actively revising scope (its own + ADR-009 was revised twice in one day); a wire-format coordination channel + reduces but does not eliminate exposure to that churn. +- LatentMesh's small scale (1,407 LOC) means this program may end up writing + substantially more `ruvector`-side code than exists in the entire upstream + repo it is coordinating against — a proportion worth surfacing to + reviewers who assume "integrating with an existing project" implies a + smaller `ruvector`-side footprint. + +## Security / Validation Gates + +- **Causal-audit CI gate** (shared with ADR-310): any PR touching the new + `latentmesh`-integration crates or downstream consumers must pass a + controlled-replacement causal audit before merge. +- **Witness-chain requirement**: RVF packaging for every latent frame + includes provenance and witness history as artifact metadata (LatentMesh + ADR-008's own requirement), anchored via this program's shared witness + contract (ADR-312). +- **RVM admission enforcement**: no latent frame is accepted without passing + `rvm-cap` admission — this is the concrete implementation of invariant 3 + ("every agent communication is attributable") for this bounded context. +- **Hosted-RVM honesty discipline** (ruvector ADR-285): if any part of this + transport layer runs in a hosted (non-bare-metal) mode, it must not claim + bare-metal isolation strength. + +## Affected Repos + +- `ruvnet/ruvector` (new crates, primary build location) +- `ruvnet/LatentMesh` (wire-format coordination, primary as design contract) +- `ruvnet/rvm` (`rvm-cap` admission enforcement) + +## Dependencies + +Depends on ADR-305 (adopts LatentMesh ADR-009 as the design contract this +work implements) and ADR-307 (RVF/RVM provenance wiring the memory-ledger +side of this transport depends on). ADR-310 (causal-attribution gate) and +ADR-311 (anomaly quarantine) both depend on this ADR — neither has a +transport layer to gate or quarantine until this ADR's crates exist. + +## Alternatives Considered + +- **Wait for `ruvnet/LatentMesh` to build its own transport layer before + starting `ruvector`-side work**: rejected — LatentMesh's own maintainers + have not committed to a timeline, and this program's acceptance test + depends on a live run of the causal-edge verification mechanism; waiting + indefinitely is not compatible with the program's schedule. +- **Build a `ruvector`-only latent-communication mechanism instead of + coordinating with LatentMesh's wire format**: rejected — this is exactly + the "parallel architecture" ADR-305 already rejected at the program level; + a `ruvector`-only mechanism would not benefit from LatentMesh's existing + causal-edge verification math (`latentmesh-align`, `latentmesh-gate`) and + would fragment the `ruvnet` org's latent-communication story further. diff --git a/docs/adr/ADR-310-causal-attribution-gate-latent-communication.md b/docs/adr/ADR-310-causal-attribution-gate-latent-communication.md new file mode 100644 index 000000000..84732641b --- /dev/null +++ b/docs/adr/ADR-310-causal-attribution-gate-latent-communication.md @@ -0,0 +1,127 @@ +# ADR-310: Causal-Attribution Gate for Latent Communication + +- **Status**: Proposed +- **Date**: 2026-08-19 +- **Deciders**: RuV Perpetual Intelligence Runtime (PIR) Program +- **Related**: ADR-309 (PIR, depends on); ADR-311 (PIR, downstream consumer); ruflo PR #2956 (anytime-valid sequential-evidence mechanism); ruflo ADR-381 (Proposed — stream identity + budget-exhaustion recovery over that mechanism) +- **Tags**: pir, causal-audit, ci-gate, latent-communication, security + +## Context + +Invariant 3 of the program requires: *"every agent communication is +attributable."* Per +`docs/research/perpetual-intelligence-runtime/01-evidence-review.md`, this is +grounded in a grade-A source, cited here with a corrected date: + +- **Causal audit of latent multi-agent communication** — + [arXiv:2607.26773](https://arxiv.org/abs/2607.26773), "Do Latent Channels + Actually Communicate? A Causal Audit of Latent Multi-Agent LLM + Communication." **Submission date: 2026-07-29** (arXiv's own timestamp). + The program brief's original citation of "Aug 5" is incorrect and is not + used anywhere in this program's documents. Grade A. The paper's core + finding: end-task performance gains alone do not establish that a receiver + actually used task-relevant information passed through a latent (KV-cache) + channel — a controlled-replacement causal audit is needed to distinguish + genuine communication from confounded correlation. Tested on Qwen3-4B/8B + over GSM8K, ARC-C, and MATH-500. + +This paper is the evidentiary basis for invariant 3: without a causal audit, +"agent A's latent message caused agent B's behavior change" is exactly the +kind of unfalsifiable claim the paper's methodology exists to test. + +## Decision + +Every latent-channel deployment inside this program's Latent Communication +Fabric context (built per ADR-309) must pass a controlled-replacement causal +audit, modeled on arXiv:2607.26773's methodology, before its performance +claims can justify further rollout. Concretely: + +1. This becomes a **required CI gate** on any pull request touching + `latentmesh-align` (or its `ruvector`-side consumers built under ADR-309), + the anomaly-quarantine module (ADR-311), or any downstream consumer of + latent-channel output — not a one-time paper reproduction run once and + forgotten. +2. The audit runs against benchmark families equivalent in structure to the + paper's own (GSM8K/ARC-C/MATH-500-style internal tasks), using a + controlled-replacement methodology: replace the latent channel's content + with a control (unrelated or null) payload and confirm the receiving + agent's behavior changes accordingly when the real payload is restored. +3. Statistical claims produced by this gate (e.g. "the latent channel's + effect on receiver behavior is significant") follow ruflo PR #2956's + anytime-valid e-process scheme (`α_k = α_total·6/(π²k²)` per-test + allocation, so `Σα_k = α_total` holds across arbitrarily many + adaptively-chosen PRs) when the gate runs repeatedly over time, rather + than treating each PR's audit as an independent, uncorrected significance + test. Ruflo ADR-381 (Proposed) is the governance layer over that + mechanism — per-project stream identity and an audited, + `confirm: true`-gated evidence-epoch reset for budget exhaustion. **The + false-promotion bound this composition provides is per-epoch, not + global**: after a reset, the guarantee is family-wise false-promotion + probability ≤ `α_total` for that epoch, and this gate's own statistical + claims must be stated the same way. +4. A CI failure on this gate blocks merge; it does not merely warn. + +## Consequences + +### Positive + +- Gives invariant 3 an enforcement mechanism that runs on every relevant + change, not just once at program kickoff — a latent channel that "worked" + at audit time but silently stops actually communicating (only correlating) + after a later change would otherwise go undetected. +- Reuses a peer-reviewed, grade-A methodology instead of inventing an + in-house causal-attribution test from scratch. +- Composing with ruflo PR #2956's sequential-evidence scheme (governed by + ADR-381) keeps the gate's statistical claims sound, per epoch, even as it + runs many times over the program's lifetime, rather than accumulating + false-positive risk across repeated single tests. + +### Negative + +- A controlled-replacement causal audit is more expensive to run than a + simple end-task performance comparison; this adds CI latency to every PR + touching the gated modules. +- The gate's benchmark families are internal analogues of GSM8K/ARC-C/ + MATH-500, not the exact published benchmarks — fidelity to the paper's + original methodology needs independent validation before the gate's + results are treated as equivalent-strength evidence to the paper's own. +- Gating on this gate alone does not itself catch anomalous or malicious + latent payloads — that is ADR-311's scope; a channel can pass causal + attribution and still carry a tampered payload. + +## Security / Validation Gates + +- **Causal-audit CI gate** (this ADR's core mechanism): blocking, not + advisory, on every PR touching the scoped modules. +- **Witness-chain requirement**: every audit run and its verdict are + witness-logged (this program's shared anchoring contract, ADR-312), so + the audit history for any given latent-channel change is queryable + end-to-end. +- **Sequential-evidence discipline**: statistical claims from repeated gate + runs follow ruflo PR #2956's e-process scheme (governed by ADR-381) rather + than compounding uncorrected significance tests, and are stated as + per-epoch bounds, not global ones. + +## Affected Repos + +- `ruvnet/ruvector` (CI workflow, the new LatentMesh-integration crates from ADR-309) +- `ruvnet/LatentMesh` (`latentmesh-align`, if the gate is also adopted upstream — coordination item, not required by this ADR) + +## Dependencies + +Depends on ADR-309 (there is no latent-channel code to gate until the +greenfield transport/RVF-packaging work exists). ADR-311 (anomaly +quarantine) is a downstream consumer — quarantine decisions are informed by, +but distinct from, this gate's causal-attribution verdict. + +## Alternatives Considered + +- **A one-time causal-audit reproduction at program kickoff, not a + standing CI gate**: rejected — a static audit cannot catch regressions + introduced by later changes to `latentmesh-align` or its consumers, which + is exactly the failure mode invariant 3 is meant to prevent on an ongoing + basis. +- **Use end-task performance improvement alone as the attribution signal**: + rejected — this is precisely the confounded-correlation failure mode + arXiv:2607.26773 documents; performance gains do not establish that the + latent channel itself was the causal mechanism. diff --git a/docs/adr/ADR-311-anomaly-quarantine-latent-channels-net-new.md b/docs/adr/ADR-311-anomaly-quarantine-latent-channels-net-new.md new file mode 100644 index 000000000..fa2831cf7 --- /dev/null +++ b/docs/adr/ADR-311-anomaly-quarantine-latent-channels-net-new.md @@ -0,0 +1,149 @@ +# ADR-311: Anomaly Quarantine for Latent Channels (Net-New Work — Not "LATTE") + +- **Status**: Proposed +- **Date**: 2026-08-19 +- **Deciders**: RuV Perpetual Intelligence Runtime (PIR) Program +- **Related**: ADR-309, ADR-310 (PIR, depends on both); ADR-312 (PIR, shares provenance chain) +- **Tags**: pir, quarantine, latent-communication, security, net-new + +## Context + +**"LATTE" is not a real paper.** Per +`docs/research/perpetual-intelligence-runtime/01-evidence-review.md` item 6, +this program's original brief cited "LATTE" as prior art for anomaly +quarantine of multi-agent latent communication. An extensive search effort — +direct phrase search across all major combinations — found eight or more +unrelated papers using "LATTE" as an acronym (a latent diffusion transformer +for video, atomic environment descriptors, hyperbolic Lorentz attention for +EEG, a robotics trajectory transformer, quantum error-correction decoding, +federated test-time adaptation, bank-transaction embeddings, linear-time +attention) — **none of which relate to multi-agent latent-communication +anomaly quarantine.** No paper under this name, in this domain, was found to +exist. This ADR states that explicitly and permanently: **any future +reference to "LATTE" as prior art for this quarantine mechanism is +incorrect, and this ADR's decision must never be described as "implementing +LATTE."** + +The closest genuine match on topic is grade-graded separately in the +evidence review: + +- [arXiv:2606.28958](https://arxiv.org/abs/2606.28958), "When Latent Agents + Lie: KV-Cache Integrity in Multi-Agent LLM Collaboration" — confirmed to + use an HMAC-SHA256 manifest-based integrity/tamper-detection scheme (774 + honest payloads accepted, 295 tampered rejected in the paper's own + evaluation). This is related in spirit — it is about detecting + compromised latent-channel payloads — but it is a **different mechanism**: + cryptographic integrity verification via HMAC manifest, not statistical + anomaly quarantine, and it does not use the name "LATTE" anywhere. + +**This ADR's quarantine mechanism is original work informed by +arXiv:2606.28958, not an implementation of "LATTE" or any other paper.** +Where this program needs statistical/behavioral anomaly detection beyond +what a cryptographic integrity manifest alone provides, that half of the +mechanism has no external prior art to lean on and is being built for the +first time by this program. + +## Decision + +Build anomaly quarantine for latent-channel updates as a first-party +contribution, combining two elements this program can cite concretely: + +1. **Integrity verification**: adopt arXiv:2606.28958's HMAC-manifest + approach for detecting tampered latent-channel payloads — a manifest + binds a payload to an expected hash, and a mismatch is rejected before + the payload reaches a receiving agent. +2. **Provenance chaining**: bind quarantine decisions into this program's + shared witness/anchoring contract (ADR-312), specifically anchoring + quarantine verdicts through `rvm-witness`/autogenous `witness` provenance + chains, so a quarantine decision is auditable alongside the rest of the + mutation/promotion history. +3. **Statistical anomaly detection** (the genuinely novel half): design and + implement statistical/behavioral anomaly scoring for latent-channel + updates that HMAC integrity checking alone cannot catch (e.g. a + cryptographically valid but behaviorally anomalous payload from a + compromised-but-still-signing agent). This is explicitly documented, in + this ADR and in every derived design document, as original work with no + existing paper to validate it against — its effectiveness must be + established empirically by this program's own test suite, not cited from + a source that does not exist. +4. Every quarantine ADR, design doc, code comment, or status report produced + by this program must describe this mechanism as "net-new anomaly + quarantine informed by arXiv:2606.28958," never as "LATTE" or an + implementation of it. + +## Consequences + +### Positive + +- Gives the quarantine mechanism a concrete, citable foundation for its + integrity-verification half (arXiv:2606.28958's measured 774/295 + accept/reject split) rather than an unsupported claim. +- Being explicit that the statistical-anomaly half is novel work sets + accurate expectations for validation effort — this program budgets time + to build and test an anomaly-scoring mechanism, not to integrate an + existing one. +- Prevents a specific, identified credibility risk: an ADR or status report + citing "LATTE" as if it were real prior art would be discovered as false + by any reviewer who searches for the paper, undermining trust in this + program's other, genuinely grade-A-cited claims. + +### Negative + +- The statistical-anomaly-detection half has no published baseline to + benchmark against — this program must define its own success criteria and + validation methodology from scratch, which is a real, unbounded design + task rather than a scoped integration. +- Combining a cryptographic mechanism (HMAC manifest, deterministic) with a + statistical mechanism (anomaly scoring, probabilistic) in one quarantine + pipeline introduces two different failure/false-positive regimes that need + separate tuning and separate testing. +- This work package (WP7, per `03-program-plan.md`) explicitly depends on + ADR-309 and ADR-310 both landing first — there is no latent-channel + transport to quarantine, and no causal-attribution baseline to compare + against, until those exist. + +## Security / Validation Gates + +- **Integrity gate**: every latent-channel payload is checked against its + HMAC-SHA256 manifest before delivery; a mismatch quarantines the payload + and never delivers it to the receiving agent. +- **Statistical anomaly gate**: payloads that pass integrity verification + but score above the anomaly threshold are also quarantined, pending + further review — the exact threshold and scoring methodology are an + implementation detail for the owning work package, not fixed by this ADR. +- **Witness-chain requirement**: every quarantine decision (pass, integrity + failure, or anomaly hold) is anchored via this program's shared witness + contract (ADR-312), making quarantine history auditable. +- **Causal-audit interaction**: a quarantined payload does not count toward + a latent channel's causal-attribution evidence (ADR-310) — quarantine and + causal audit are complementary, not substitutes for each other. + +## Affected Repos + +- `ruvnet/ruvector` (new quarantine module, built on ADR-309's crates) +- `ruvnet/rvm` (`rvm-witness` provenance anchoring) +- `ruvnet/autogenous` (`witness` provenance anchoring, per ADR-312's shared contract) + +## Dependencies + +Depends on ADR-309 (latent-channel transport must exist before it can be +quarantined) and ADR-310 (causal-attribution gate — quarantine and causal +audit are complementary controls on the same channel). Shares its provenance +mechanism with ADR-312. + +## Alternatives Considered + +- **Describe this mechanism as an implementation of "LATTE"** (the + program's original framing): rejected outright — no such paper exists; + doing so would be a factually false citation in a permanent architecture + record. +- **Skip statistical anomaly detection and rely on HMAC integrity checking + alone**: rejected — integrity checking only catches *tampered* payloads + signed incorrectly; it does not catch a validly-signed but behaviorally + anomalous payload from a compromised agent that still holds valid signing + credentials, which is exactly the gap statistical anomaly scoring is meant + to close. +- **Wait for external prior art on multi-agent latent-channel anomaly + quarantine before building this**: rejected — the evidence review already + confirms none exists after a genuine search effort; waiting indefinitely + is not compatible with invariant 3's enforcement needs. diff --git a/docs/adr/ADR-312-shared-witness-schema-anchoring-contract.md b/docs/adr/ADR-312-shared-witness-schema-anchoring-contract.md new file mode 100644 index 000000000..5a6419e4a --- /dev/null +++ b/docs/adr/ADR-312-shared-witness-schema-anchoring-contract.md @@ -0,0 +1,193 @@ +# ADR-312: Shared Witness Record Schema and Cross-Layer Anchoring Contract (rvm-witness ↔ autogenous witness) + +- **Status**: Proposed +- **Date**: 2026-08-19 +- **Deciders**: RuV Perpetual Intelligence Runtime (PIR) Program +- **Related**: ADR-305 (PIR, depends on); ADR-306, ADR-307, ADR-309, ADR-315 (PIR, consumers); ruflo ADR-322/322C (flywheel receipt/ledger/verification protocol, Accepted — implemented, verified verbatim against source); ruflo PR #2956 (anytime-valid sequential-evidence mechanism); ruflo ADR-381 (Proposed — stream identity + budget-exhaustion recovery over that mechanism); ruvector ADR-134 (witness schema/log format); see `docs/research/perpetual-intelligence-runtime/04-verification-addendum.md` §3, §5, §8 +- **Tags**: pir, witness, provenance, security, cross-repo + +## Context + +The program's original framing (from `03-program-plan.md`'s initial draft) +proposed resolving a perceived duplication: `ruvnet/rvm`'s `rvm-witness` +crate and `ruvnet/autogenous`'s `witness` crate both implement an +append-only, hash-chained, tamper-evident log, described as having +"near-identical framing." The proposed decision was to make `rvm-witness` +canonical and have `autogenous`'s `witness` crate depend on or converge with +it. + +**Direct comparison of both crates does not support that framing** (full +detail in `04-verification-addendum.md` §3): + +| | `autogenous/crates/witness` | `rvm`'s `crates/rvm-witness` (vendored in `ruvector`) | +|---|---|---| +| Size | 302 LOC, one file | 4,405 LOC, multi-file | +| Hash | SHA-256 over canonical JSON | u64 chain/record hashes | +| Auth | Ed25519, per-role `SigningAuthority` | Keyed chain MAC with derivation + ratcheting | +| Record shape | JSON artifacts (genome, mutation, antibody, incident) | 64-byte cache-line-aligned records in a fixed-capacity ring buffer | +| Runtime | std, service-side, offline+deterministic | `no_std`, hypervisor-side | + +The two crates are correct for their respective layers — SHA-256-over-JSON +does not fit a `no_std` 64-byte-aligned ring buffer, and `rvm-witness`'s +keyed-MAC chain is deliberately not a signature scheme suitable for +cross-service, offline verification. **Merging them, or making one depend on +the other, would be a design error**, not a simplification. + +A better anchor already exists, and this program has now verified it +directly against a clone of `ruvnet/ruflo` (HEAD `fa13ee4`, 2026-08-15; 177 +ADRs in `v3/docs/adr/`), not merely inherited it. `ruflo ADR-322C` (part of +the Accepted — phases-0–2-implemented — ADR-322 flywheel-integration series) +defines a receipt/ledger/verification protocol built specifically to be a +portable, offline-verifiable, cross-layer wire format: **RFC 8785 JCS +canonical JSON, SHA-256 digests, Ed25519 signatures with domain separation** +(`Ed25519(domainPrefix || 0x00 || canonicalBytes)`) — confirmed to use +**two distinct Ed25519 signing domains** (`ruflo/flywheel-receipt/v1` and +`ruflo/flywheel-ledger-head/v1`), not one, plus a third domain-separated +prefix (`ruflo/bootstrap/v1`) that seeds the deterministic paired +bootstrap's statistics rather than signing anything — with explicit identity +derivation (`candidateId = +SHA-256(JCS(candidate policy))`, `receiptId = SHA-256(JCS(unsigned receipt +payload))`). Every authorizing term in a 322C record carries an explicit +evidence grade — **`recomputed`, `signature-verified`, or +`trusted-assertion`** — a vocabulary this ADR adopts below for grading +anchored claims. UUIDv7 run IDs, deterministic paired-bootstrap statistical +recomputation, an O_EXCL cross-process lock with directory-fsynced +compare-and-swap, and fail-closed verification (unknown fields, non-finite +numbers, and negative zero all rejected) are likewise confirmed against +source. **This same verification pass corroborates the ADR-103 ambiguity +this program flagged elsewhere (ADR-305)**: ADR-322C line 105 states its +keys "use ADR-103's provider mechanism but a distinct purpose/domain" — +confirming the witness-manifest ADR-103 is `ruflo`'s, not `ruvector`'s. + +Separately, `ruflo ADR-381` is **Proposed** (not Accepted; date 2026-08-10) +and governs a narrower scope than this ADR originally attributed to it. The +anytime-valid sequential statistical evidence scheme itself — `α_k = +α_total · 6/(π²k²)` per-test allocation so `Σα_k = α_total`, and the +measured 0.6% family-wise false-promotion rate over 1,000 simulated nulls — +belongs to **ruflo PR #2956**, which ADR-381 *governs* rather than defines: +ADR-381's own decision is (1) scoping the α ledger to the ADR-322 +transaction state, one stream per project root, and (2) +`resetSequentialEvidence`, an explicit, `confirm: true`-gated, human-reasoned +**evidence-epoch** reset for budget exhaustion that expires all outstanding +receipts so stale evidence cannot be replayed against a fresh budget. +**The false-promotion bound is per-epoch, not global**: after a reset, the +guarantee is family-wise false-promotion probability ≤ `α_total` for that +epoch — any PIR document citing this bound must state it the same way. + +## Decision + +Resolve the witness-layer question as a **shared record schema plus a +cross-layer anchoring contract**, not a crate merge or dependency edge: + +1. `rvm-witness` remains the canonical implementation for its layer — + hypervisor-side, `no_std`, privileged-action recording. `autogenous`'s + `witness` crate remains the canonical implementation for its layer — + service-side, std, JSON-artifact governance records. Neither is refactored + to depend on the other. +2. Both layers adopt **ruflo ADR-322C's canonical encoding and + domain-separated Ed25519 signature scheme** as the shared, portable + record format for any witness record that needs to be verified *across* + layers — specifically, an autogenous promotion decision that needs to be + anchored into an RVM witness chain (or vice versa) is represented using + ADR-322C's canonical-JSON + domain-separated-Ed25519 encoding at the + anchoring boundary, regardless of each crate's own internal + representation. +3. Where a witness record makes a statistical claim (e.g. "this mutation's + improvement was significant"), that claim's evidence follows ruflo PR + #2956's anytime-valid e-process scheme (governed by ADR-381's stream + identity and evidence-epoch reset) rather than a single uncorrected + significance test — this is the concrete mechanism that makes "outperform + its parent" (invariant 5) auditable across an arbitrarily long sequence of + promotion attempts within an epoch. Any witness record's statistical + claim is stated as a **per-epoch** bound, not a global one, and each + authorizing term is tagged with 322C's evidence grade + (`recomputed`/`signature-verified`/`trusted-assertion`) so a reader can + tell which parts of the claim were independently recomputed versus merely + asserted. +4. ruvector ADR-134's witness schema (the 64-byte cache-line-aligned, + hash-chained record format used by `rvm-witness`) is unchanged by this + ADR; this decision governs the boundary where a non-RVM witness record + needs to be anchored into or verified against an RVM chain, not RVM's own + internal format. + +## Consequences + +### Positive + +- Avoids a design error (merging two crates built for genuinely different + runtimes and threat models) that the original framing would have produced. +- Reuses an already-Accepted, already-implemented cross-service verification + protocol (ruflo ADR-322C) instead of this program inventing a fifth + witness-record format. +- Gives every PIR ADR that emits witness records (ADR-306, ADR-307, ADR-309, + ADR-315) one anchoring contract to target, regardless of which underlying + crate produced the record. + +### Negative + +- Requires cross-repo sign-off from `ruvnet/rvm`, `ruvnet/autogenous`, and + `ruvnet/ruflo` maintainers on the shared boundary format — more + coordination surface than a single-repo crate-dependency change would have + been, even though it is architecturally the correct choice. +- `autogenous` self-labels "research prototype" status; adopting ruflo + ADR-322C's format at the anchoring boundary does not itself stabilize + autogenous's own witness crate's internal API, which may still churn. +- This ADR does not eliminate the two independent witness implementations — + it deliberately keeps both. Anyone expecting "one witness crate for the + whole program" from the original framing needs to be told explicitly that + this ADR chose interoperability over consolidation. + +## Security / Validation Gates + +- **Witness-chain requirement**: every cross-layer anchoring event (an + autogenous promotion record anchored into an RVM chain, or the reverse) + must use ruflo ADR-322C's canonical encoding and produce a verifiable + domain-separated Ed25519 signature before either side treats the record as + committed. +- **Fail-closed verification**: unknown fields, non-finite numbers, and + negative zero are rejected at the anchoring boundary, per ADR-322C's own + verification rules — this program does not weaken that contract at the + boundary. +- **Sequential-evidence discipline**: any witness record carrying a + statistical promotion claim states its evidence per ruflo PR #2956's + anytime-valid e-process scheme (governed by ADR-381), not a single-test + p-value, expressed as a **per-epoch** bound, so the acceptance harness's + (ADR-306, WP12) day-30 comparison remains statistically sound within each + evidence epoch — a day-30-vs-day-1 comparison spanning an epoch reset must + not silently claim a global bound it does not have. +- **Standard repo gate**: `npx @claude-flow/cli@latest security scan` after + any change to signing, canonicalization, or verification code in either + witness crate or the anchoring boundary. + +## Affected Repos + +- `ruvnet/rvm` (`rvm-witness`, unchanged internally) +- `ruvnet/autogenous` (`witness` crate, unchanged internally) +- `ruvnet/ruflo` (ADR-322/322C canonical encoding/signature scheme — Accepted; PR #2956's sequential-evidence mechanism; ADR-381's stream-identity/epoch-reset governance — Proposed; all consumed, not modified, by this ADR) +- `ruvnet/ruvector` (anchoring-boundary implementation, RVM witness consumer) + +## Dependencies + +Depends on ADR-305 (adopts the cross-repo coordination posture this ADR +requires). ADR-306 (Dream Machine), ADR-307 (three-level memory), ADR-309 +(LatentMesh transport), and ADR-315 (constitutional gate) all depend on this +ADR for how their respective witness records get anchored across layers. + +## Alternatives Considered + +- **Make `autogenous`'s witness crate depend on `rvm-witness`** (the + program's original framing): rejected — see Context; the two crates target + incompatible runtimes (`no_std` hypervisor-side ring buffer vs. std + service-side JSON), and forcing a dependency edge between them would + either break `rvm-witness`'s `no_std` constraint or strip `autogenous`'s + witness crate of the JSON/Ed25519 shape its own consumers expect. +- **Invent a new, program-specific witness schema instead of adopting ruflo + ADR-322C's**: rejected — ADR-322C is already Accepted and implemented with + a fail-closed verification suite; inventing a fifth schema would add + coordination surface without adding capability. +- **Leave the two witness crates fully independent, with no anchoring + contract at all**: rejected — this would leave invariant 3 ("every agent + communication is attributable") and invariant 5 ("every promoted mutation + must outperform its parent") unauditable across the autogenous/RVM + boundary specifically, which is exactly the boundary this program's + Governance & Constitution context needs to cross. diff --git a/docs/adr/ADR-313-shaper-frozen-weight-skill-harness-evolution.md b/docs/adr/ADR-313-shaper-frozen-weight-skill-harness-evolution.md new file mode 100644 index 000000000..8fc40b3fd --- /dev/null +++ b/docs/adr/ADR-313-shaper-frozen-weight-skill-harness-evolution.md @@ -0,0 +1,186 @@ +# ADR-313: SHAPER-Pattern Skill/Harness Evolution Loop (Frozen Weights) + +- **Status**: Proposed +- **Date**: 2026-08-19 +- **Deciders**: RuV Perpetual Intelligence Runtime (PIR) Program +- **Related**: ADR-306 (PIR, depends on); ADR-308 (PIR, downstream consumer); ADR-305 (PIR, separation-of-powers invariant); ruflo ADR-150 "MetaHarness Integration Surfaces in `npx ruflo`" (Implemented, 2026-06-16 — the real source of `METAHARNESS-README.md`'s documented `optionalDependencies` invariant; see Context); ruvector ADR-259 (ruvllm mutator backend); ruvector ADR-271 (darwin_guard); ruflo ADR-322/322A/322B (proposer/promotion separation, Accepted — verified verbatim against source) +- **Tags**: pir, shaper, darwin, frozen-weights, evolution + +## Context + +The acceptance test's central constraint is frozen foundation-model weights: +the model never changes, only the skills, context, and execution harness +around it. Per +`docs/research/perpetual-intelligence-runtime/01-evidence-review.md`, this +is grounded in a grade-A source: + +- **SHAPER** — [arXiv:2608.11350](https://arxiv.org/abs/2608.11350), + "Self-Evolving Embodied Agents via Skill-Harness Evolution," submitted + 2026-08-11 (matches the program brief's date exactly). Confirms a + train-free framework that keeps model parameters frozen while evolving + reusable skills and a context/code harness through target-environment + rollouts; the same frozen model serves as both planner and optimizer. + Evaluated on VLABench and ESI-Bench. Grade A; no name collision found. + +`ruvector` already has a real evolutionary loop that maps onto this pattern: +Darwin (`@metaharness/darwin`), called from `harness/src/darwin.ts` (ANN +config evolution), `examples/mragent`'s `scorePolicy` function, and +`crates/sona/src/darwin_guard.rs` (ruvector ADR-271) — profile → baseline → +mutate (seven approved surfaces via `CodeGenerator`, e.g. `OpenRouterMutator`, +`RuvllmMutator`) → sandbox → 6-term score → archive-as-tree → repeat. +`ruvllm` is a real, wired local mutator backend (ruvector ADR-259). + +**One concrete, already-identified bug blocks this work package** and must +be fixed first (program plan WP0b), not discovered mid-implementation: + +1. `METAHARNESS-README.md` claims `optionalDependencies` compliance, + attributing the policy to "**ADR-150**: MetaHarness Integration Surfaces + (**upstream**)." Neither `ruvector`'s own ADR-150 + (`ADR-150-pi-brain-ruvltra-tailscale.md`, "π Brain + RuvLtra via + Tailscale — Semantic Embedding Upgrade") nor `metaharness`'s own ADR-150 + (`ADR-150-tailscale-local-frontier-concurrent-benchmarks.md`) is the + right document — both are unrelated. **The upstream document resolves to + `ruflo`'s ADR-150**: `v3/docs/adr/ADR-150-metaharness-integration-surfaces.md`, + *"ADR-150 — MetaHarness Integration Surfaces in `npx ruflo`,"* Status + **Implemented** (2026-06-16, rev. 06-17). Its normative rule 2 is + verbatim the policy `METAHARNESS-README.md` claims compliance with: + *"Optional in `package.json`: `@metaharness/*` packages MUST appear in + `optionalDependencies` or `peerDependencies` (optional), never in + `dependencies`."* This is the fourth instance, in this ADR set, of the + same pattern the set exists to catch — assuming the wrong repo owns an + ADR number before checking (see ADR-305 Decision §6); it resolves the + same way the "ruflo ADR-322, never metaharness ADR-322" and "ADR-103" + cases did. Against that real source, the confirmed bug is: the nine + `@metaharness/*` packages in `crates/ruvector-sota-bench/harness` are + plain (hard) dependencies, contradicting ruflo ADR-150 rule 2 — the + harness currently hard-fails to install without them. ruflo ADR-150 rule + 4 — *"at least one CI job must run `--ignore-optional` … the only + structural defense against accidentally promoting an optional dep to + required"* — is the stronger, CI-testable acceptance criterion this work + package should adopt instead of a plain `npm install` check (see Decision + §4 and Security Gates below). + +**A second bug this ADR previously cited — an HTTP-307 redirect bug in +`ruvllm`'s model-download path — is already fixed on `main`** (commit +`946275a61`, PR #590, 2026-06-18). This ADR no longer treats it as a +blocker. Verifying that fix surfaced the actual remaining download blocker: +a **GGUF glob/alias bug in `ruvllm-cli`'s `get_files_to_download()`** +(`download.rs:193`'s glob pattern and `models.rs:65`'s alias resolution +disagree on which files a given model alias should pull), which still +blocks reliable end-to-end live-serve testing of the mutator backend. This +correction is itself an instance of the verification discipline ADR-305 now +states as a program-wide rule: an inherited "known bug" claim must be +checked against fix history (`git log` on the named path, upstream release +notes) before being repeated in a new ADR, not trusted from the asserting +document's prose alone. + +## Decision + +Implement the physical-intelligence evolution loop with foundation-model +weights frozen throughout, following SHAPER's pattern (arXiv:2608.11350): + +1. The same frozen model serves as both planner and optimizer; only skills, + context, and the execution harness evolve — mapped onto Darwin's existing + mutation surfaces (`harness/src/darwin.ts`, `examples/mragent` + `scorePolicy`, `crates/sona/src/darwin_guard.rs`). +2. This is enforced **structurally**, not by policy: a CI check fails the + build if any mutation surface reachable from the promotion pipeline + imports a training/fine-tuning API. Policy alone ("please don't + fine-tune") is not sufficient for the acceptance test's frozen-weights + verification requirement (day-30 re-hash must be bit-identical to day 0). +3. Darwin's mutation proposals are exactly that — proposals. Per ruflo + ADR-322B's separation-of-powers invariant, adopted as a governing + invariant in ADR-305, quoted here verbatim against source (confirmed + `ADR-322B-darwin-proposer-adapter.md` line 10): *"A proposer produces + untrusted candidates only. It cannot issue promotion decisions or mutate + active policy."* ADR-322 line 15 reinforces the same point from the + Darwin-adapter side: *"Darwin adapters remain candidate generators and + never gain promotion authority."* Darwin's mutation surfaces in this + program never gain promotion authority either; every proposal routes + through ADR-306's adopted evaluation pipeline before any change to active + policy. +4. WP0b's remaining blocking bug is fixed before this work package's + live-serve testing begins: the `optionalDependencies` non-compliance + (make the nine `@metaharness/*` packages genuinely optional per ruflo + ADR-150 rule 2, or correct `METAHARNESS-README.md` to state the real + hard-dependency requirement) and the `ruvllm-cli` GGUF glob/alias bug in + `get_files_to_download()` (`download.rs:193`, `models.rs:65`). The + acceptance criterion for the dependency fix is ruflo ADR-150 rule 4's CI + job on the `--ignore-optional` install path, not merely "`npm install` + succeeds" — that is the structural defense against silently re-promoting + an optional dependency to required. The previously-cited HTTP-307 + redirect bug is not part of this gate — it shipped fixed on `main` before + this ADR was written. + +## Consequences + +### Positive + +- Grounds the frozen-weights constraint in a concrete, exact-date-matching + grade-A source rather than only the program brief's prose. +- Reuses Darwin's already-real evolutionary loop instead of building a new + mutation-proposal mechanism. +- The structural (CI-enforced) frozen-weights check, combined with + ADR-322B's separation-of-powers invariant, gives this program two + independent enforcement layers for "the model never changes and a + proposer never self-promotes" — a single-point-of-failure policy + violation in either layer alone does not compromise the other. + +### Negative + +- This work package cannot start live-serve testing until WP0b's remaining + bug (the GGUF glob/alias mismatch) is fixed — an explicit, tracked + blocking dependency, not a soft preference. The HTTP-307 bug this ADR + originally also gated on turned out to already be fixed on `main`, + illustrating why every inherited bug claim needs a fix-history check + before it is repeated (see ADR-305). +- Darwin currently exists as an external npm dependency + (`@metaharness/darwin`) called from three sites, not a first-class + in-repo asset; this ADR does not itself resolve that architectural + question (vendor vs. formalize-as-dependency), leaving it to the owning + work package. +- A CI check for "no training/fine-tuning API import" is a static, + import-based check; it does not catch a sufficiently obfuscated or + dynamically-loaded fine-tuning path. This is a known limitation, not + claimed to be closed by this ADR. + +## Security / Validation Gates + +- **Structural frozen-weights enforcement**: CI fails the build if any + mutation surface reachable from the promotion pipeline imports a + training/fine-tuning API. +- **Separation-of-powers invariant** (ruflo ADR-322B, adopted via ADR-305): + Darwin's mutation surfaces never gain promotion authority; enforced by + ADR-306's adopted evaluation/promotion pipeline, not by this ADR directly. +- **Proof-gated promotion**: every mutation still passes through + `ruvector-proof-gate`/`rvm-proof` regardless of SHAPER-pattern compliance. +- **WP0b blocking gate**: this work package's live-serve acceptance criteria + cannot be claimed complete while either the `optionalDependencies` + compliance bug or the `ruvllm-cli` GGUF glob/alias bug + (`get_files_to_download()`) remains open. The dependency fix is verified + by ruflo ADR-150 rule 4's CI job on the `--ignore-optional` install path, + not by a plain successful `npm install`. + +## Affected Repos + +- `ruvnet/ruvector` (`crates/sona`, `crates/ruvllm` mutator backend, `crates/ruvector-sota-bench/harness`, `agent-harness-generator`/Darwin integration sites) +- `ruvnet/ruflo` (ADR-150 and ADR-322/322A/322B — cited as source policy/invariant, not modified by this ADR) + +## Dependencies + +Depends on ADR-306 (Dream Machine evaluation pipeline — every mutation +proposal needs a verdict before promotion) and on ADR-305's adopted +separation-of-powers invariant. ADR-308 (WorldCycle verification) depends on +this ADR — it verifies the physical-action outputs this evolution loop +produces. + +## Alternatives Considered + +- **Allow a fine-tuning fallback path for cases the frozen-weights harness + can't handle**: rejected — this directly contradicts the acceptance test's + central constraint and SHAPER's own pattern; any capability gap should be + addressed via richer harness/skill mutation surfaces, not weight updates. +- **Defer fixing WP0b's remaining bug until it actually blocks a specific + task**: rejected — it is already identified, small, and cheap to fix; + deferring it guarantees it surfaces mid-implementation of this ADR's + higher-priority work instead of being resolved ahead of time. diff --git a/docs/adr/ADR-314-kv-cache-cross-model-migration-ruvllm.md b/docs/adr/ADR-314-kv-cache-cross-model-migration-ruvllm.md new file mode 100644 index 000000000..d395da0cc --- /dev/null +++ b/docs/adr/ADR-314-kv-cache-cross-model-migration-ruvllm.md @@ -0,0 +1,116 @@ +# ADR-314: KV-Cache Cross-Model Migration in ruvLLM (Fast-Follow) + +- **Status**: Proposed +- **Date**: 2026-08-19 +- **Deciders**: RuV Perpetual Intelligence Runtime (PIR) Program +- **Related**: none within this program's critical path (independent parallel track) +- **Tags**: pir, kv-cache, ruvllm, fast-follow, cross-model + +## Context + +Fast-follow scope item 4 of the program (per `03-program-plan.md`'s scope +decision) is KV-cache cross-model migration, selected because it has the +program's strongest evidence and is the cheapest item to ship. Per +`docs/research/perpetual-intelligence-runtime/01-evidence-review.md`: + +- **Cross-model KV-cache mapping** — + [arXiv:2608.03893](https://arxiv.org/abs/2608.03893), "Cross-Model KV + Cache Transfer in LLM Families: A Closed-Form Linear Mapping for Prefill + Reuse," submitted 2026-08-04 16:26 UTC (matches the brief's date exactly). + **Grade A — the strongest-evidence item in the evidence review.** Exact + figure match on every reported number: the closed-form linear mapper runs + "2.7-25x faster than re-prefill." Tested across six model pairs spanning + three model families; the linear mapper retains 73-98% of the receiver's + standalone-prefill accuracy on four pairs, while **two pairs degrade + sharply**. A nonlinear MLP variant recovers up to +37pp HellaSwag accuracy + on the failing pairs. + +This is the concrete implementation target for a `ruvllm` capability: +`crates/ruvllm` already provides paged attention, KV cache management, and +SONA learning (built on `ruvector-core`/`ruvector-sona`), but cross-*provider* +or cross-*model-family* KV-cache migration is not centered here today — that +role sits closer to claude-flow's ADR-026 3-tier routing, which is a +different concern (routing between providers, not migrating cache state +between models). + +## Decision + +Implement arXiv:2608.03893's closed-form linear KV-cache mapper as a +`ruvllm` capability, ships independently of the Phase 1–3 PIR branch since it +depends only on `ruvllm`: + +1. Implement the closed-form linear mapper for same-family model migration + in `crates/ruvllm`, targeting `kv_cache.rs`, `paged_attention.rs`, and + `serving/kv_cache_manager.rs`. +2. Implement the paper's nonlinear MLP fallback specifically for the pairs + the paper itself identifies as degrading under the linear mapper — this + is not optional; the evidence review explicitly notes this fallback is + what "directly supports the brief's implication that migration quality + must be predicted/handled before blind use." +3. Add a routing gate that predicts transfer quality **before** migrating — + never migrate blind. The gate's prediction determines whether to use the + linear mapper, the MLP fallback, or refuse migration and fall back to a + full re-prefill for a pair judged too degraded for either. +4. This work package has no dependency on the rest of this program's ADR set + (ADR-305 through ADR-313, ADR-315) and can start immediately in parallel. + +## Consequences + +### Positive + +- Grade-A, exact-figure-match evidence gives this ADR a concrete, + independently reproducible acceptance bar (2.7-25x speedup; 73-98% + accuracy retention on four of six tested pairs). +- Fully independent of the rest of the program's critical path — delivers + value on its own schedule without blocking or being blocked by ADR-305 + through ADR-313 or ADR-315. +- The "predict transfer quality before migrating" routing gate directly + addresses the paper's own finding that two of six pairs degrade sharply — + this ADR does not treat the mapper as universally safe. + +### Negative + +- The paper's reported figures come from its own six-pair benchmark; this + program has not yet reproduced them against its own model inventory — + the acceptance bar should be re-confirmed against `ruvllm`'s actual served + models, not assumed to transfer directly. +- The routing gate's prediction accuracy is itself an open engineering + question — a gate that mispredicts transfer quality could either block + safe migrations (losing the speedup) or allow unsafe ones (the exact + failure mode this ADR is designed to prevent). +- Two additional code paths (linear mapper, MLP fallback) plus a routing + gate add real maintenance surface to `ruvllm`'s KV-cache management code. + +## Security / Validation Gates + +- **Proof-gated promotion**: this capability's rollout follows the same + `ruvector-proof-gate`/`rvm-proof` promotion path as any other mutation to + `ruvllm`'s serving path — it is not exempt from standard promotion gating + merely because it ships on an independent schedule. +- **Standard repo gate**: `npx @claude-flow/cli@latest security scan` after + any change to `kv_cache.rs`, `paged_attention.rs`, or + `serving/kv_cache_manager.rs`, since KV-cache handling is a + security-sensitive serving-path component. + +## Affected Repos + +- `ruvnet/ruvector` (`crates/ruvllm`; new npm package `@ruvector/kv-migrate`) + +## Dependencies + +None — independent parallel track, can start immediately regardless of the +status of ADR-305 through ADR-313 or ADR-315. + +## Alternatives Considered + +- **Implement only the linear mapper, skip the MLP fallback**: rejected — + the evidence review is explicit that the two-of-six-pairs-degrade finding + is exactly why a fallback (and a routing gate) is needed; shipping the + linear mapper alone would silently produce degraded migrations on known + bad pairs. +- **Migrate blind (no routing gate) and rely on downstream task performance + to catch bad migrations**: rejected — this is the same + confounded-correlation failure mode ADR-310's causal-audit gate is + designed to prevent elsewhere in this program; predicting transfer + quality before migrating is cheaper and safer than detecting a bad + migration after the fact. diff --git a/docs/adr/ADR-315-governance-constitution-capability-expansion.md b/docs/adr/ADR-315-governance-constitution-capability-expansion.md new file mode 100644 index 000000000..4f4e04dad --- /dev/null +++ b/docs/adr/ADR-315-governance-constitution-capability-expansion.md @@ -0,0 +1,170 @@ +# ADR-315: Governance Constitution for Capability Expansion + +- **Status**: Proposed +- **Date**: 2026-08-19 +- **Deciders**: RuV Perpetual Intelligence Runtime (PIR) Program +- **Related**: ADR-312 (PIR, depends on); ADR-306 (PIR, distinct from ordinary promotion gating); ADR-305 (PIR, invariant 7 — proposer/promotion separation, binding here); autogenous ADR-393 "Product Thesis — Adaptive Agent Firewall" (autogenous repo); autogenous ADR-401 capability 5 and Update 1 §3 (governed self-improvement, `promoteAuthorized` — Done) +- **Tags**: pir, governance, constitution, capability-expansion, security + +## Context + +The acceptance test requires "zero unapproved capability expansion" — no +mutation may silently grant an agent a new tool, a new physical action +class, or a new communication peer without an explicit, higher-bar approval +distinct from ordinary behavioral-mutation promotion (ADR-306). +`ruvnet/autogenous` already implements a constitution/admission-gate pattern +for exactly this purpose (`constitution` crate, part of its +observe → explain → mutate → prove → canary → promote/rollback loop), and its +own ADR-401 (see ADR-305's reconciliation) frames governed self-improvement +as capability 5 of its 10-capability map: `Promote = Better ∧ Safe ∧ +Authorized ∧ Reversible`. + +**Correction from PR review**: an earlier draft of this ADR described that +predicate as "not yet fully closed as one checked gate," citing ADR-401's +capability-table row 5. **That row is stale relative to ADR-401's own +Decision section.** ADR-401's **Update 1 §3 is marked DONE**: `mesh-evolve.ts` +exports `promoteAuthorized(candidate, champion, { authorized, reversible }) +→ PromotionDecision`, the single gate is implemented with each conjunct +independently blocking, `evolveMesh` routes every promotion through it, and +`test/promote-authorized.test.ts` proves no promotion path can skip a +conjunct. The predicate is closed upstream — this ADR does not scope work +to close it. + +**Maturity caveat, corrected in this program's verification pass** (see +`04-verification-addendum.md` §2): `ruvnet/autogenous`'s README self-labels +the whole repo **"research prototype"** status, and states plainly that +"performance and economics claims in the ADRs are hypotheses until +benchmarked" — even though several of its individual ADRs (400, 401, 402, +403) carry **Accepted** status. This program treats the repo-level badge as +the governing signal for API stability: autogenous's constitution/ +admission-gate API should be treated as unstable, and this program budgets +time for API churn rather than assuming production-grade stability. The +governance loop's actual implementation lives in `packages/radio-moe/src/*.ts` +(action-gate.ts, mesh-evolve.ts, disclosure.ts, reputation.ts — 6,171 LOC +total), not the Rust `constitution` crate alone. + +## Decision + +Adopt `autogenous`'s constitution/admission-gate pattern, **anchored on the +already-implemented `promoteAuthorized` predicate**, as the enforcement point +for zero-unapproved-capability-expansion: + +1. Every mutation that would expand an agent's capability set — new tool + access, new physical action class, new communication peer — requires + explicit constitutional approval logged to the witness chain, **distinct + from** ordinary behavioral-mutation promotion (ADR-306's evaluation + pipeline). A mutation passing ADR-306's promotion gate does not + automatically pass this gate; capability expansion needs its own, + separately-authorized approval record. This gate is itself bound by + governing invariant 7 (adopted in ADR-305, from ruflo ADR-322B): whatever + proposed the capability-expanding mutation cannot also issue this gate's + approval — approval authority and proposal authority must be held by + distinct actors in the witness chain, the same separation-of-powers rule + ADR-313 enforces on Darwin's mutation surfaces. +2. This program **adopts** `mesh-evolve.ts`'s `promoteAuthorized` predicate + (`Promote = Better ∧ Safe ∧ Authorized ∧ Reversible`, all four conjuncts + already independently blocking upstream) as the mechanism whose + "Authorized" conjunct this gate's capability-expansion approval satisfies. + The residual work this program actually scopes is narrower than the + original framing: (a) the `ruvector`-side integration wiring PIR's + capability/tool/action tables into `promoteAuthorized`'s `authorized` + parameter, and (b) the distinctness rule in §1 above — ensuring a + capability-expanding mutation's "Authorized" check is evaluated against + *this program's* capability-expansion approval record specifically, not + merely against `promoteAuthorized`'s general authorization state. This + program does not build or close the predicate itself; that work is + already done upstream. +3. Approval records for capability expansion are anchored via this + program's shared witness contract (ADR-312), so the 30-day acceptance + harness (per `03-program-plan.md`) can query "zero unapproved capability + expansion" directly by diffing the capability/tool/action tables at day 0 + vs. day 30 against this gate's approval log. +4. Given autogenous's self-labeled research-prototype status, this program's + integration against its constitution/admission-gate API is built with an + explicit API-stability buffer (versioned interface, integration tests + that fail loudly on upstream API changes) rather than a tight, assumed- + stable coupling. + +## Consequences + +### Positive + +- Reuses `autogenous`'s already-designed governance concept (constitution, + admission gate) instead of inventing a parallel capability-expansion + approval mechanism. +- Directly operationalizes the acceptance test's "zero unapproved capability + expansion" requirement as a queryable log, not just a stated goal. +- Explicitly separating capability-expansion approval from ordinary mutation + promotion (ADR-306) prevents the specific failure mode where a + statistically-significant, well-tested mutation quietly also expands an + agent's capability set without anyone noticing. +- `promoteAuthorized` being DONE upstream (ADR-401 Update 1 §3) meaningfully + reduces this ADR's scope versus the original framing — this program + integrates against a finished, tested predicate instead of building or + completing one. + +### Negative + +- Coupling to a self-labeled research-prototype API means this integration + carries real churn risk; the API-stability buffer in Decision §4 adds + engineering overhead specifically to manage that risk. +- This program's residual scope depends on `promoteAuthorized`'s upstream + API remaining stable (see the research-prototype caveat above) — a + breaking change to its `authorized`/`reversible` parameters or return + shape would require rework on the `ruvector`-side integration, even though + the predicate's core logic is not this program's responsibility to build. +- Two separate approval paths (behavioral promotion via ADR-306, capability + expansion via this ADR) add process overhead versus a single unified + promotion gate — deliberate, per the acceptance test's own requirement + that these be distinct, but a real cost. + +## Security / Validation Gates + +- **Constitutional admission gate** (this ADR's core mechanism): every + capability-expanding mutation requires explicit, separately-logged + approval before it can take effect — blocking, not advisory. +- **Witness-chain requirement**: every constitutional approval or denial is + anchored via ADR-312's shared witness contract, queryable end-to-end for + the 30-day acceptance harness's capability-table diff. +- **Distinctness from behavioral promotion**: this gate is never satisfied + merely by a mutation passing ADR-306's evaluation pipeline — the two are + independently blocking. +- **Separation-of-powers invariant** (governing invariant 7, ADR-305): the + actor that proposed a capability-expanding mutation cannot also approve + it through this gate. +- **Hosted-RVM honesty discipline** (ruvector ADR-285): if any part of this + gate's enforcement runs in a hosted (non-bare-metal) mode, isolation + claims must match what has actually been tested. +- **Standard repo gate**: `npx @claude-flow/cli@latest security scan` after + any change touching capability tables or the admission-gate integration. + +## Affected Repos + +- `ruvnet/autogenous` (`constitution` crate, `packages/radio-moe/src/action-gate.ts` and `mesh-evolve.ts`) +- `ruvnet/ruvector` (integration point, capability/tool tables) +- `ruvnet/rvm` (witness anchoring via ADR-312) + +## Dependencies + +Depends on ADR-312 (the shared witness/anchoring contract this gate's +approval records use). Distinct from, but coordinates with, ADR-306's +promotion pipeline — a mutation may need to pass both gates independently. + +## Alternatives Considered + +- **Fold capability-expansion approval into ADR-306's ordinary promotion + gate as one more check**: rejected — the acceptance test explicitly + requires querying capability expansion independently of general + performance-based promotion; conflating the two would make that query + impossible to answer cleanly. +- **Build a `ruvector`-native constitutional gate instead of integrating + with autogenous's**: rejected — autogenous's constitution/admission-gate + concept is already designed for exactly this purpose, and building a + parallel mechanism would repeat the same anti-pattern ADR-305 already + rejected at the program level (parallel architecture instead of adopting + existing design work). +- **Treat autogenous's Accepted-status ADRs (400/401) as sufficient + evidence of API stability, ignoring the repo-level prototype badge**: + rejected — per this program's verification pass, the badge and individual + ADR statuses are not always in agreement, and the badge is the more + conservative signal for integration planning. diff --git a/docs/adr/ADR-316-adr-numbering-hygiene.md b/docs/adr/ADR-316-adr-numbering-hygiene.md new file mode 100644 index 000000000..a83af27e9 --- /dev/null +++ b/docs/adr/ADR-316-adr-numbering-hygiene.md @@ -0,0 +1,83 @@ +# ADR-316: ADR Numbering Hygiene — Frozen Duplicates, Canonical Counter, Collision Gate + +**Status**: Proposed +**Date**: 2026-08-19 +**Relates to**: PIR program issue #845 (WP0a), epic #837 +**Supersedes**: the "renumber every duplicate" framing in issue #845's original scope + +## Context + +`docs/adr/` accumulated duplicate ADR numbers because numbers were allocated +by multiple concurrent authors (humans, agents, nightly research runs) with no +single counter. A full audit of `origin/main` (2026-08-19) verified: + +- **336 ADR files** total: 289 on the plain `ADR-NNN` counter, 47 in + namespaced families (`ADR-CE-*`, `ADR-DB-*`, `ADR-QE-*`, `ADR-TTS-*`), + which are separate numbering spaces and have **no** internal duplicates. +- Highest allocated plain number at audit time: **ADR-304** (ADR-305–315 were + then claimed on the `feat/pir-adrs` branch and have since merged via + PR #847 — hence this ADR is 316). +- **27 plain numbers are duplicated**, spanning **61 files**: + - ×5: **ADR-272** + - ×3: ADR-264, ADR-252, ADR-194, ADR-144 + - ×2: ADR-268, 266, 260, 258, 256, 254, 143, 139, 138, 137, 136, 135, + 134, 133, 132, 117, 096, 095, 094, 093, 091, 090 + +This corrects two figures in issue #845's body: the "~15+" duplicate estimate +(verified: 27), and "ADR-040 ×3" — **ADR-040 is not a collision**. The +`ADR-040` / `ADR-040a` / `ADR-040b` suffix pattern is an intentional sub-ADR +convention (a parent decision with lettered companion documents) and is +preserved as a distinct, valid numbering form. + +## Decision + +1. **Duplicate numbers are frozen historical artifacts. No existing ADR file + is renamed or renumbered.** These numbers appear in commit messages, PR + bodies, crate docs, code comments, research documents, and external links + (the shared brain, other repos' citations of `ruvector` ADRs). Renaming + breaks every external reference silently, and redirect stubs cannot cover + references we do not control. The collision damage is capped and known; + renumbering damage would be open-ended. + +2. **Disambiguation is by slug, not by number.** From now on, any citation of + a duplicated number MUST use the form **`ADR-NNN (slug)`**, where the slug + is the filename remainder, e.g. `ADR-134 (witness-schema-log-format)` vs. + `ADR-134 (ruvector-claude-code-deep-integration)`. Citations of + non-duplicated numbers may remain plain `ADR-NNN`. + +3. **New ADRs are allocated from a single canonical counter.** The counter is + the plain `ADR-NNN` sequence; the next free number is always + max(allocated) + 1. Sub-ADRs (`NNNa`, `NNNb`, …) remain valid as lettered + companions to an existing parent ADR and do not consume counter numbers. + Namespaced families (`ADR-CE-*` etc.) keep their own internal sequences. + "Allocated" includes numbers claimed on open ADR-authoring branches — + check open PRs before claiming, as this ADR did with ADR-305–315. + +4. **The generated index is the counter's source of truth.** + `docs/adr/INDEX.md` — generated by `node scripts/adr-index.mjs` — lists + every ADR file with its number, title, path, date, status, and duplicate + flag, and states the **next available number** at the top. Authors and + number-allocating tooling (e.g. `ruflo-adr:adr-create`) MUST read the next + number from the regenerated index, not from a stale cache or a directory + glob. Regenerate the index in the same PR that adds an ADR. + +5. **CI gates new collisions.** `node scripts/adr-index.mjs --check` exits + non-zero if `docs/adr/` contains a duplicate plain number that is not in + the frozen historical list above (or if a frozen number's file count + grows). The frozen list is hardcoded in the script and MUST NOT be + extended — a check failure means the new file must be renumbered before + merge, never that the list should grow. + +## Consequences + +- Issue #845's acceptance criteria are re-scoped: "zero duplicate numbers" is + replaced by "zero *unfrozen* duplicate numbers, enforced by CI"; the + renumber/reference-update/redirect-stub items become moot; the policy, + index, CI-check, and allocate-from-true-max items are satisfied here. +- Load-bearing ambiguous citations (ADR-134, ADR-256, ADR-266 called out in + #845) are resolved at the citation site by the `ADR-NNN (slug)` form; PIR + documents should adopt it as they are touched, without a mass rewrite. +- The 4-digit-namespace assumption in the filename grammar + (`ADR-(?:[A-Z]{2,4}-)?NNN[a-z]?-slug.md`) is now normative; files that do + not parse are ignored by the index and should be renamed to conform when + next edited. diff --git a/docs/adr/INDEX.md b/docs/adr/INDEX.md new file mode 100644 index 000000000..6fdb0582f --- /dev/null +++ b/docs/adr/INDEX.md @@ -0,0 +1,364 @@ +# ADR Index + +**Next available ADR number: 317** + +> Generated by `node scripts/adr-index.mjs` — do not edit by hand. +> This file is the canonical allocation counter for new ADR numbers +> (policy: `ADR-316`). Duplicate numbers listed below are frozen +> historical artifacts and are cited as `ADR-NNN (slug)`. +> CI gate: `node scripts/adr-index.mjs --check`. + +- ADR files indexed: **348** (301 on the canonical counter, 47 in namespaced families) +- Highest allocated number: **ADR-316** +- Frozen duplicate numbers: **27** (spanning 61 files) + +| Number | Title | File | Last commit | Status | Duplicate | +|---|---|---|---|---|---| +| ADR-001 | ADR-001: Ruvector Core Architecture | [`ADR-001-ruvector-core-architecture.md`](./ADR-001-ruvector-core-architecture.md) | 2026-08-13 | Proposed | | +| ADR-002 | ADR-002: RuvLLM Integration with Ruvector | [`ADR-002-ruvllm-integration.md`](./ADR-002-ruvllm-integration.md) | 2026-08-13 | Proposed | | +| ADR-003 | ADR-003: SIMD Optimization Strategy for Ruvector and RuvLLM | [`ADR-003-simd-optimization-strategy.md`](./ADR-003-simd-optimization-strategy.md) | 2026-08-13 | ✅ Implemented (v2.1.1) | | +| ADR-004 | ADR-004: KV Cache Management Strategy for RuvLLM | [`ADR-004-kv-cache-management.md`](./ADR-004-kv-cache-management.md) | 2026-08-13 | Proposed | | +| ADR-005 | ADR-005: WASM Runtime Integration | [`ADR-005-wasm-runtime-integration.md`](./ADR-005-wasm-runtime-integration.md) | 2026-08-13 | | | +| ADR-006 | ADR-006: Unified Memory Pool and Paging Strategy | [`ADR-006-memory-management.md`](./ADR-006-memory-management.md) | 2026-08-13 | | | +| ADR-007 | ADR-007: Security Review & Technical Debt Remediation | [`ADR-007-security-review-technical-debt.md`](./ADR-007-security-review-technical-debt.md) | 2026-08-13 | Active | | +| ADR-008 | ADR-008: mistral-rs Integration for Production-Scale LLM Serving | [`ADR-008-mistral-rs-integration.md`](./ADR-008-mistral-rs-integration.md) | 2026-08-13 | Proposed | | +| ADR-009 | ADR-009: Structured Output / JSON Mode for Reliable Agentic Workflows | [`ADR-009-structured-output.md`](./ADR-009-structured-output.md) | 2026-08-13 | Proposed | | +| ADR-010 | ADR-010: Function Calling / Tool Use in RuvLLM | [`ADR-010-function-calling.md`](./ADR-010-function-calling.md) | 2026-08-13 | Proposed | | +| ADR-011 | ADR-011: Prefix Caching for 10x Faster RAG and Chat Applications | [`ADR-011-prefix-caching.md`](./ADR-011-prefix-caching.md) | 2026-08-13 | Proposed | | +| ADR-012 | ADR-012: Security Remediation and Hardening | [`ADR-012-security-remediation.md`](./ADR-012-security-remediation.md) | 2026-08-13 | Accepted | | +| ADR-013 | ADR-013: HuggingFace Model Publishing Strategy | [`ADR-013-huggingface-publishing.md`](./ADR-013-huggingface-publishing.md) | 2026-08-13 | **Accepted** - 2026-01-20 | | +| ADR-014 | ADR-014: Coherence Engine Architecture | [`ADR-014-coherence-engine.md`](./ADR-014-coherence-engine.md) | 2026-08-13 | Proposed | | +| ADR-015 | ADR-015: Coherence-Gated Transformer (Sheaf Attention) | [`ADR-015-coherence-gated-transformer.md`](./ADR-015-coherence-gated-transformer.md) | 2026-08-13 | Proposed | | +| ADR-016 | ADR-016: Delta-Behavior System - Domain-Driven Design Architecture | [`ADR-016-delta-behavior-ddd-architecture.md`](./ADR-016-delta-behavior-ddd-architecture.md) | 2026-08-13 | Proposed | | +| ADR-017 | ADR-017: Temporal Tensor Compression with Tiered Quantization | [`ADR-017-temporal-tensor-compression.md`](./ADR-017-temporal-tensor-compression.md) | 2026-08-13 | Proposed | | +| ADR-018 | ADR-018: Block-Based Storage Engine Architecture for the Temporal Tensor Store | [`temporal-tensor-store/ADR-018-block-based-storage-engine.md`](./temporal-tensor-store/ADR-018-block-based-storage-engine.md) | 2026-08-13 | Proposed | | +| ADR-019 | ADR-019: Tiered Quantization Formats for Temporal Tensor Store | [`temporal-tensor-store/ADR-019-tiered-quantization-formats.md`](./temporal-tensor-store/ADR-019-tiered-quantization-formats.md) | 2026-08-13 | Proposed | | +| ADR-020 | ADR-020: Temporal Scoring and Tier Migration Algorithm | [`temporal-tensor-store/ADR-020-temporal-scoring-tier-migration.md`](./temporal-tensor-store/ADR-020-temporal-scoring-tier-migration.md) | 2026-08-13 | Proposed | | +| ADR-021 | ADR-021: Delta Compression and Reconstruction Policies | [`temporal-tensor-store/ADR-021-delta-compression-reconstruction.md`](./temporal-tensor-store/ADR-021-delta-compression-reconstruction.md) | 2026-08-13 | Proposed | | +| ADR-022 | ADR-022: WASM API Surface and Cross-Platform Strategy | [`temporal-tensor-store/ADR-022-wasm-api-cross-platform.md`](./temporal-tensor-store/ADR-022-wasm-api-cross-platform.md) | 2026-08-13 | Proposed | | +| ADR-023 | ADR-023: Benchmarking, Failure Modes, and Acceptance Criteria | [`temporal-tensor-store/ADR-023-benchmarking-acceptance-criteria.md`](./temporal-tensor-store/ADR-023-benchmarking-acceptance-criteria.md) | 2026-08-13 | Proposed | | +| ADR-024 | ADR-024: Craftsman Ultra 30b 1bit — BitNet Integration with RuvLLM | [`ADR-024-craftsman-ultra-30b-1bit-bitnet-integration.md`](./ADR-024-craftsman-ultra-30b-1bit-bitnet-integration.md) | 2026-08-13 | Proposed | | +| ADR-025 | ADR-025: EXO-AI Multi-Paradigm Integration Architecture | [`ADR-025-exo-ai-multiparadigm-integration.md`](./ADR-025-exo-ai-multiparadigm-integration.md) | 2026-08-13 | Proposed | | +| ADR-026 | ADR-026: Vector-Native COW Branching (RVCOW) and Real Cognitive Containers | [`ADR-026-rvcow-branching-and-real-cognitive-containers.md`](./ADR-026-rvcow-branching-and-real-cognitive-containers.md) | 2026-08-13 | | | +| ADR-027 | ADR-027: Fix HNSW Index Segmentation Fault with Parameterized Queries | [`ADR-027-hnsw-parameterized-query-fix.md`](./ADR-027-hnsw-parameterized-query-fix.md) | 2026-08-13 | **Accepted** - 2026-01-28 | | +| ADR-028 | ADR-028: eHealth Platform Architecture for 50M Patient Records | [`ADR-028-ehealth-platform-architecture.md`](./ADR-028-ehealth-platform-architecture.md) | 2026-08-13 | Proposed | | +| ADR-029 | ADR-029: RVF as Canonical Binary Format Across All RuVector Libraries | [`ADR-029-rvf-canonical-format.md`](./ADR-029-rvf-canonical-format.md) | 2026-08-13 | Accepted | | +| ADR-030 | ADR-030: RVF Cognitive Container -- Self-Booting Vector Files | [`ADR-030-rvf-cognitive-container.md`](./ADR-030-rvf-cognitive-container.md) | 2026-08-13 | Proposed | | +| ADR-031 | ADR-031: RVF Example Repository — 24 Demonstrations Across Four Categories | [`ADR-031-rvf-example-repository.md`](./ADR-031-rvf-example-repository.md) | 2026-08-13 | Accepted | | +| ADR-032 | ADR-032: RVF WASM Integration into npx ruvector and rvlite | [`ADR-032-rvf-wasm-integration.md`](./ADR-032-rvf-wasm-integration.md) | 2026-08-13 | Accepted | | +| ADR-033 | ADR-033: Progressive Indexing Hardening — Centroid Stability, Adversarial Resilience, Recall Framing, and Mandatory Signatures | [`ADR-033-progressive-indexing-hardening.md`](./ADR-033-progressive-indexing-hardening.md) | 2026-08-13 | Accepted | | +| ADR-034 | ADR-034: QR Cognitive Seed — A World Inside a World | [`ADR-034-qr-cognitive-seed.md`](./ADR-034-qr-cognitive-seed.md) | 2026-08-13 | Implemented | | +| ADR-035 | ADR-035: Capability Report — Witness Bundles, Scorecards, and Governance | [`ADR-035-capability-report.md`](./ADR-035-capability-report.md) | 2026-08-13 | Implemented | | +| ADR-036 | ADR-036: RuVector AGI Cognitive Container with Claude Code Orchestration | [`ADR-036-agi-cognitive-container.md`](./ADR-036-agi-cognitive-container.md) | 2026-08-13 | Partially Implemented | | +| ADR-037 | ADR-037: Publishable RVF Acceptance Test | [`ADR-037-publishable-rvf-acceptance-test.md`](./ADR-037-publishable-rvf-acceptance-test.md) | 2026-08-13 | | | +| ADR-038 | ADR-038: npx ruvector & rvlite Witness Verification Integration | [`ADR-038-npx-ruvector-rvlite-witness-integration.md`](./ADR-038-npx-ruvector-rvlite-witness-integration.md) | 2026-08-13 | | | +| ADR-039 | ADR-039: RVF Solver WASM — Self-Learning AGI Engine Integration | [`ADR-039-rvf-solver-wasm-agi-integration.md`](./ADR-039-rvf-solver-wasm-agi-integration.md) | 2026-08-13 | | | +| ADR-040 | ADR-040: Causal Atlas RVF Runtime — Planet Detection & Life Candidate Scoring | [`ADR-040-causal-atlas-rvf-runtime-planet-detection.md`](./ADR-040-causal-atlas-rvf-runtime-planet-detection.md) | 2026-08-13 | Proposed | | +| ADR-040a | ADR-040a: Causal Atlas Dashboard Specification | [`ADR-040a-planet-detection-dashboard.md`](./ADR-040a-planet-detection-dashboard.md) | 2026-08-13 | Proposed | | +| ADR-040b | ADR-040b: Microlensing Detection & Cross-Domain Graph-Cut Extensions | [`ADR-040b-microlensing-graphcut-extensions.md`](./ADR-040b-microlensing-graphcut-extensions.md) | 2026-08-13 | Proposed | | +| ADR-042 | ADR-042: Security RVF — AIDefence + TEE Hardened Cognitive Container | [`ADR-042-Security-RVF-AIDefence-TEE.md`](./ADR-042-Security-RVF-AIDefence-TEE.md) | 2026-08-13 | | | +| ADR-043 | ADR-043: External Intelligence Providers for SONA Learning | [`ADR-043-external-intelligence-providers.md`](./ADR-043-external-intelligence-providers.md) | 2026-08-13 | | | +| ADR-044 | ADR-044: ruvector-postgres v0.3 Extension Upgrade | [`ADR-044-ruvector-postgres-v03-extension-upgrade.md`](./ADR-044-ruvector-postgres-v03-extension-upgrade.md) | 2026-08-13 | Accepted — Implementation in progress | | +| ADR-045 | ADR-045: Lean-Agentic Integration — Formal Verification & AI-Native Type Theory for RuVector | [`ADR-045-lean-agentic-integration.md`](./ADR-045-lean-agentic-integration.md) | 2026-08-13 | Proposed | | +| ADR-046 | ADR-046: Graph Transformer Unified Architecture | [`ADR-046-graph-transformer-architecture.md`](./ADR-046-graph-transformer-architecture.md) | 2026-08-13 | Accepted | | +| ADR-047 | ADR-047: Proof-Gated Mutation Protocol | [`ADR-047-proof-gated-mutation-protocol.md`](./ADR-047-proof-gated-mutation-protocol.md) | 2026-08-13 | Accepted | | +| ADR-048 | ADR-048: Sublinear Graph Attention | [`ADR-048-sublinear-graph-attention.md`](./ADR-048-sublinear-graph-attention.md) | 2026-08-13 | Accepted | | +| ADR-049 | ADR-049: Verified Training Pipeline | [`ADR-049-verified-training-pipeline.md`](./ADR-049-verified-training-pipeline.md) | 2026-08-13 | Accepted | | +| ADR-050 | ADR-050: Graph Transformer WASM and Node.js Bindings | [`ADR-050-graph-transformer-bindings.md`](./ADR-050-graph-transformer-bindings.md) | 2026-08-13 | Accepted | | +| ADR-051 | ADR-051: Physics-Informed Graph Transformer Layers | [`ADR-051-physics-informed-graph-layers.md`](./ADR-051-physics-informed-graph-layers.md) | 2026-08-13 | Accepted | | +| ADR-052 | ADR-052: Biological Graph Transformer Layers | [`ADR-052-biological-graph-layers.md`](./ADR-052-biological-graph-layers.md) | 2026-08-13 | Accepted | | +| ADR-053 | ADR-053: Temporal and Causal Graph Transformer Layers | [`ADR-053-temporal-causal-graph-layers.md`](./ADR-053-temporal-causal-graph-layers.md) | 2026-08-13 | Accepted | | +| ADR-054 | ADR-054: Economic Graph Transformer Layers | [`ADR-054-economic-graph-layers.md`](./ADR-054-economic-graph-layers.md) | 2026-08-13 | Accepted | | +| ADR-055 | ADR-055: Manifold-Aware Graph Transformer Layers | [`ADR-055-manifold-graph-layers.md`](./ADR-055-manifold-graph-layers.md) | 2026-08-13 | Accepted | | +| ADR-056 | ADR-056: RVF Knowledge Export for Developer Onboarding | [`ADR-056-rvf-knowledge-export.md`](./ADR-056-rvf-knowledge-export.md) | 2026-08-13 | Accepted | | +| ADR-057 | ADR-057: Federated RVF Format for Real-Time Transfer Learning | [`ADR-057-federated-rvf-transfer-learning.md`](./ADR-057-federated-rvf-transfer-learning.md) | 2026-08-13 | Proposed | | +| ADR-058 | ADR-058: RVF Hash Security Hardening and Optimization | [`ADR-058-hash-security-optimization.md`](./ADR-058-hash-security-optimization.md) | 2026-08-13 | Accepted | | +| ADR-059 | ADR-059: Shared Brain — Google Cloud Deployment | [`ADR-059-shared-brain-google-cloud.md`](./ADR-059-shared-brain-google-cloud.md) | 2026-08-13 | Accepted | | +| ADR-060 | ADR-060: Shared Brain Capabilities — Federated MicroLoRA Intelligence Substrate | [`ADR-060-shared-brain-capabilities.md`](./ADR-060-shared-brain-capabilities.md) | 2026-08-13 | Accepted | | +| ADR-061 | ADR-061: Reasoning Kernel Architecture — Brain-Augmented Targeted Reasoning | [`ADR-061-reasoning-kernel-architecture.md`](./ADR-061-reasoning-kernel-architecture.md) | 2026-08-13 | Accepted | | +| ADR-062 | ADR-062: Brainpedia — Structured Knowledge Encyclopedia with Delta-Based Editing | [`ADR-062-brainpedia-architecture.md`](./ADR-062-brainpedia-architecture.md) | 2026-08-13 | Accepted | | +| ADR-063 | ADR-063: WASM Executable Nodes — Deterministic Compute at the Edge | [`ADR-063-wasm-executable-nodes.md`](./ADR-063-wasm-executable-nodes.md) | 2026-08-13 | Accepted | | +| ADR-064 | ADR-064: Pi Brain Infrastructure & Landing Page | [`ADR-064-pi-brain-infrastructure.md`](./ADR-064-pi-brain-infrastructure.md) | 2026-08-13 | Accepted, Deployed | | +| ADR-065 | ADR-065: npm Publishing Strategy | [`ADR-065-npm-publishing-strategy.md`](./ADR-065-npm-publishing-strategy.md) | 2026-08-13 | Accepted | | +| ADR-066 | ADR-066: SSE MCP Transport | [`ADR-066-sse-mcp-transport.md`](./ADR-066-sse-mcp-transport.md) | 2026-08-13 | Accepted, Deployed — Updated 2026-04-02: SSE moved to dedicated subdomain `mcp.p | | +| ADR-067 | ADR-067: MCP Gate Permit System | [`ADR-067-mcp-gate-permit-system.md`](./ADR-067-mcp-gate-permit-system.md) | 2026-08-13 | Accepted, Implemented | | +| ADR-068 | ADR-068: Domain Expansion Transfer Learning | [`ADR-068-domain-expansion-transfer-learning.md`](./ADR-068-domain-expansion-transfer-learning.md) | 2026-08-13 | Accepted, Implemented | | +| ADR-069 | ADR-069: Edge-Net and Pi Brain Integration — Distributed Compute Intelligence | [`ADR-069-google-edge-network-deployment.md`](./ADR-069-google-edge-network-deployment.md) | 2026-08-13 | Proposed | | +| ADR-070 | ADR-070: npx ruvector Unified Integration | [`ADR-070-npx-ruvector-unified-integration.md`](./ADR-070-npx-ruvector-unified-integration.md) | 2026-08-13 | Proposed | | +| ADR-071 | ADR-071: npx ruvector Ecosystem Gap Analysis | [`ADR-071-npx-ruvector-ecosystem-gap-analysis.md`](./ADR-071-npx-ruvector-ecosystem-gap-analysis.md) | 2026-08-13 | Proposed | | +| ADR-072 | ADR-072: RVF Example Management and Downloads in npx ruvector | [`ADR-072-rvf-example-management-downloads.md`](./ADR-072-rvf-example-management-downloads.md) | 2026-08-13 | Proposed | | +| ADR-073 | ADR-073: π.ruv.io Platform Security Audit & Optimization | [`ADR-073-pi-platform-security-optimization.md`](./ADR-073-pi-platform-security-optimization.md) | 2026-08-13 | Accepted | | +| ADR-074 | ADR-074: RuvLLM Neural Embedding Integration | [`ADR-074-ruvllm-neural-embeddings.md`](./ADR-074-ruvllm-neural-embeddings.md) | 2026-08-13 | Implemented (Phase 2 — RlmEmbedder Active) | | +| ADR-075 | ADR-075: Wire Full RVF AGI Stack into mcp-brain-server | [`ADR-075-rvf-agi-stack-brain-integration.md`](./ADR-075-rvf-agi-stack-brain-integration.md) | 2026-08-13 | Implemented | | +| ADR-076 | ADR-076: AGI Capability Wiring Architecture | [`ADR-076-agi-capability-wiring-architecture.md`](./ADR-076-agi-capability-wiring-architecture.md) | 2026-08-13 | Implemented | | +| ADR-077 | ADR-077: Midstream Platform Integration into mcp-brain-server | [`ADR-077-midstream-brain-integration.md`](./ADR-077-midstream-brain-integration.md) | 2026-08-13 | Proposed | | +| ADR-078 | ADR-078: npx ruvector Midstream & Brain AGI Integration | [`ADR-078-npx-ruvector-midstream-integration.md`](./ADR-078-npx-ruvector-midstream-integration.md) | 2026-08-13 | Proposed | | +| ADR-079 | ADR-079: SQL Audit Script Hardening & Bug Fixes | [`ADR-079-sql-audit-script-hardening.md`](./ADR-079-sql-audit-script-hardening.md) | 2026-08-13 | Accepted | | +| ADR-080 | ADR-080: npx ruvector Deep Capability Audit | [`ADR-080-npx-ruvector-deep-capability-audit.md`](./ADR-080-npx-ruvector-deep-capability-audit.md) | 2026-08-13 | Accepted | | +| ADR-081 | ADR-081: Brain Server v0.2.8–0.2.10 Deploy + CLI/MCP Bug Fixes | [`ADR-081-brain-server-v028-deploy-cli-fixes.md`](./ADR-081-brain-server-v028-deploy-cli-fixes.md) | 2026-08-13 | Accepted | | +| ADR-082 | ADR-082: Brain Server Security Hardening — PII, Rate Limiting, Anti-Sybil | [`ADR-082-brain-security-hardening.md`](./ADR-082-brain-security-hardening.md) | 2026-08-13 | Accepted | | +| ADR-083 | ADR-083: Brain Server Training Loops — Closing the Store→Learn Gap | [`ADR-083-brain-training-loops.md`](./ADR-083-brain-training-loops.md) | 2026-08-13 | Accepted | | +| ADR-084 | ADR-084: ruvllm-wasm — First Functional npm Publish | [`ADR-084-ruvllm-wasm-publish.md`](./ADR-084-ruvllm-wasm-publish.md) | 2026-08-13 | Accepted | | +| ADR-085 | ADR-085: RuVector Neural Trader — Dynamic Market Graphs, MinCut Coherence Gating, and Proof-Gated Mutation | [`ADR-085-neural-trader-ruvector.md`](./ADR-085-neural-trader-ruvector.md) | 2026-08-13 | Proposed | | +| ADR-086 | ADR-086: Neural Trader WASM Bindings | [`ADR-086-neural-trader-wasm.md`](./ADR-086-neural-trader-wasm.md) | 2026-08-13 | Accepted | | +| ADR-087 | ADR-087: RuVix Cognition Kernel — An Operating System for the Agentic Age | [`ADR-087-ruvix-cognition-kernel.md`](./ADR-087-ruvix-cognition-kernel.md) | 2026-08-13 | **Accepted** — Phase A Implemented | | +| ADR-088 | ADR-088: CNN Contrastive Learning Integration for RuVector | [`ADR-088-cnn-contrastive-integration.md`](./ADR-088-cnn-contrastive-integration.md) | 2026-08-13 | **Proposed** | | +| ADR-089 | ADR-089: CNN Browser Demo for GitHub Pages | [`ADR-089-cnn-browser-demo.md`](./ADR-089-cnn-browser-demo.md) | 2026-08-13 | Accepted | | +| ADR-090 | ADR-090 Implementation Checklist: Ultra-Low-Bit QAT & Pi-Quantization | [`ADR-090-implementation-checklist.md`](./ADR-090-implementation-checklist.md) | 2026-08-13 | Ready for Implementation (Staged) | DUPLICATE ×2 — cite as `ADR-90 (implementation-checklist)` | +| ADR-090 | ADR-090: Ultra-Low-Bit QAT & Pi-Quantization — Domain-Driven Design Architecture | [`ADR-090-ultra-low-bit-qat-pi-quantization-ddd.md`](./ADR-090-ultra-low-bit-qat-pi-quantization-ddd.md) | 2026-08-13 | Accepted (Implementing) | DUPLICATE ×2 — cite as `ADR-90 (ultra-low-bit-qat-pi-quantization-ddd)` | +| ADR-091 | ADR-091 Implementation Checklist: INT8 CNN Quantization | [`ADR-091-implementation-checklist.md`](./ADR-091-implementation-checklist.md) | 2026-08-13 | Ready for Implementation | DUPLICATE ×2 — cite as `ADR-91 (implementation-checklist)` | +| ADR-091 | ADR-091: INT8 CNN Quantization — Domain-Driven Design Architecture | [`ADR-091-int8-cnn-quantization-ddd.md`](./ADR-091-int8-cnn-quantization-ddd.md) | 2026-08-13 | Accepted (Implementing) | DUPLICATE ×2 — cite as `ADR-91 (int8-cnn-quantization-ddd)` | +| ADR-092 | ADR-092: MoE Memory-Aware Routing — Domain-Driven Design Architecture | [`ADR-092-moe-memory-aware-routing-ddd.md`](./ADR-092-moe-memory-aware-routing-ddd.md) | 2026-08-13 | Accepted | | +| ADR-093 | ADR-093: Daily Discovery & Brain Training Program | [`ADR-093-daily-discovery-brain-training.md`](./ADR-093-daily-discovery-brain-training.md) | 2026-08-13 | Accepted | DUPLICATE ×2 — cite as `ADR-93 (daily-discovery-brain-training)` | +| ADR-093 | ADR-093: DeepAgents Complete Rust Conversion — Overview | [`ADR-093-deepagents-rust-conversion-overview.md`](./ADR-093-deepagents-rust-conversion-overview.md) | 2026-08-13 | | DUPLICATE ×2 — cite as `ADR-93 (deepagents-rust-conversion-overview)` | +| ADR-094 | ADR-094: Backend Protocol & Trait System | [`ADR-094-deepagents-backend-protocol-traits.md`](./ADR-094-deepagents-backend-protocol-traits.md) | 2026-08-13 | | DUPLICATE ×2 — cite as `ADR-94 (deepagents-backend-protocol-traits)` | +| ADR-094 | ADR-094: π.ruv.io Shared Web Memory on RuVector | [`ADR-094-pi-shared-web-memory.md`](./ADR-094-pi-shared-web-memory.md) | 2026-08-13 | Accepted (Implementing) | DUPLICATE ×2 — cite as `ADR-94 (pi-shared-web-memory)` | +| ADR-095 | ADR-095: Middleware Pipeline Architecture | [`ADR-095-deepagents-middleware-pipeline.md`](./ADR-095-deepagents-middleware-pipeline.md) | 2026-08-13 | | DUPLICATE ×2 — cite as `ADR-95 (deepagents-middleware-pipeline)` | +| ADR-095 | ADR-095: π.ruv.io API v2 — Full Capability Surface | [`ADR-095-pi-api-v2-capabilities.md`](./ADR-095-pi-api-v2-capabilities.md) | 2026-08-13 | Accepted | DUPLICATE ×2 — cite as `ADR-95 (pi-api-v2-capabilities)` | +| ADR-096 | ADR-096: Cloud-Native Data Pipeline, Real-Time Injection & Automated Optimization | [`ADR-096-cloud-pipeline-realtime-optimization.md`](./ADR-096-cloud-pipeline-realtime-optimization.md) | 2026-08-13 | Accepted | DUPLICATE ×2 — cite as `ADR-96 (cloud-pipeline-realtime-optimization)` | +| ADR-096 | ADR-096: Tool System — Filesystem, Execute, Grep, Glob | [`ADR-096-deepagents-tool-system.md`](./ADR-096-deepagents-tool-system.md) | 2026-08-13 | | DUPLICATE ×2 — cite as `ADR-96 (deepagents-tool-system)` | +| ADR-097 | ADR-097: SubAgent & Task Orchestration | [`ADR-097-deepagents-subagent-orchestration.md`](./ADR-097-deepagents-subagent-orchestration.md) | 2026-08-13 | | | +| ADR-098 | ADR-098: Memory, Skills & Summarization Middleware | [`ADR-098-deepagents-memory-skills-summarization.md`](./ADR-098-deepagents-memory-skills-summarization.md) | 2026-08-13 | | | +| ADR-099 | ADR-099: CLI & ACP Server Conversion | [`ADR-099-deepagents-cli-acp-server.md`](./ADR-099-deepagents-cli-acp-server.md) | 2026-08-13 | | | +| ADR-100 | ADR-100: RVF Integration & Crate Structure | [`ADR-100-deepagents-rvf-integration-crate-structure.md`](./ADR-100-deepagents-rvf-integration-crate-structure.md) | 2026-08-13 | | | +| ADR-101 | ADR-101: Testing Strategy & Fidelity Verification | [`ADR-101-deepagents-testing-strategy.md`](./ADR-101-deepagents-testing-strategy.md) | 2026-08-13 | | | +| ADR-102 | ADR-102: Implementation Roadmap & Phasing | [`ADR-102-deepagents-implementation-roadmap.md`](./ADR-102-deepagents-implementation-roadmap.md) | 2026-08-13 | | | +| ADR-103 | ADR-103: Review Amendments — Performance, RVF Integration & Security Hardening | [`ADR-103-deepagents-review-amendments.md`](./ADR-103-deepagents-review-amendments.md) | 2026-08-13 | | | +| ADR-104 | ADR-104: rvAgent MCP Tools/Resources, Enhanced Skills, and Topology-Aware Deployment | [`ADR-104-rvagent-mcp-skills-topology.md`](./ADR-104-rvagent-mcp-skills-topology.md) | 2026-08-13 | | | +| ADR-105 | ADR-104: rvAgent MCP Tools and Resources System | [`ADR-105-rvagent-mcp-implementation-details.md`](./ADR-105-rvagent-mcp-implementation-details.md) | 2026-08-13 | | | +| ADR-106 | ADR-106: RuVix Kernel Integration with RVF | [`ADR-106-ruvix-kernel-rvf-integration.md`](./ADR-106-ruvix-kernel-rvf-integration.md) | 2026-08-13 | | | +| ADR-107 | ADR-107: rvAgent Native Swarm Orchestration with WASM Integration | [`ADR-107-rvagent-native-swarm-wasm.md`](./ADR-107-rvagent-native-swarm-wasm.md) | 2026-08-13 | | | +| ADR-108 | ADR-108: rvAgent–ruvbot Integration Architecture | [`ADR-108-rvagent-ruvbot-integration.md`](./ADR-108-rvagent-ruvbot-integration.md) | 2026-08-13 | | | +| ADR-109 | ADR-109: Backup and Disaster Recovery Strategy | [`ADR-109-backup-disaster-recovery.md`](./ADR-109-backup-disaster-recovery.md) | 2026-08-13 | Accepted, Implemented | | +| ADR-110 | ADR-110: Neural-Symbolic Integration with Internal Voice | [`ADR-110-neural-symbolic-internal-voice.md`](./ADR-110-neural-symbolic-internal-voice.md) | 2026-08-13 | In Progress | | +| ADR-111 | ADR-111: Ruvocal UI Integration with rvAgent | [`ADR-111-ruvocal-ui-rvagent-integration.md`](./ADR-111-ruvocal-ui-rvagent-integration.md) | 2026-08-13 | | | +| ADR-112 | ADR-112: rvAgent MCP Server with SSE and stdio Transports | [`ADR-112-rvagent-mcp-server.md`](./ADR-112-rvagent-mcp-server.md) | 2026-08-13 | | | +| ADR-113 | ADR-113: RVF App Gallery and Ruvix-Powered Applications | [`ADR-113-rvf-app-gallery-ruvix-applications.md`](./ADR-113-rvf-app-gallery-ruvix-applications.md) | 2026-08-13 | | | +| ADR-114 | ADR-114: Ruvector-Core Hash Placeholder Embeddings | [`ADR-114-ruvector-core-hash-placeholders.md`](./ADR-114-ruvector-core-hash-placeholders.md) | 2026-08-13 | Accepted | | +| ADR-115 | ADR-115: Common Crawl Integration with Semantic Compression | [`ADR-115-common-crawl-temporal-compression.md`](./ADR-115-common-crawl-temporal-compression.md) | 2026-08-13 | Phase 1 Implemented | | +| ADR-116 | ADR-116: Spectral Graph Sparsifier Integration with pi.ruv.io | [`ADR-116-spectral-sparsifier-brain-integration.md`](./ADR-116-spectral-sparsifier-brain-integration.md) | 2026-08-13 | Accepted | | +| ADR-117 | ADR-117: Pseudo-Deterministic Canonical Minimum Cut | [`ADR-117-canonical-mincut-pseudo-deterministic.md`](./ADR-117-canonical-mincut-pseudo-deterministic.md) | 2026-08-13 | Shipped (all 3 tiers) | DUPLICATE ×2 — cite as `ADR-117 (canonical-mincut-pseudo-deterministic)` | +| ADR-117 | ADR-117: DrAgnes Dermatology Intelligence Platform | [`ADR-117-dragnes-dermatology-intelligence-platform.md`](./ADR-117-dragnes-dermatology-intelligence-platform.md) | 2026-08-13 | Proposed | DUPLICATE ×2 — cite as `ADR-117 (dragnes-dermatology-intelligence-platform)` | +| ADR-118 | ADR-118: Cost-Effective Common Crawl Strategy with Sparsifier-Aware Guardrails | [`ADR-118-cost-effective-crawl-strategy.md`](./ADR-118-cost-effective-crawl-strategy.md) | 2026-08-13 | Phase 1 Active | | +| ADR-119 | ADR-119: Historical Common Crawl Evolutionary Comparison | [`ADR-119-historical-crawl-evolutionary-comparison.md`](./ADR-119-historical-crawl-evolutionary-comparison.md) | 2026-08-13 | Accepted | | +| ADR-120 | ADR-120: WET Processing Pipeline for Medical + CS Corpus Import | [`ADR-120-wet-processing-pipeline.md`](./ADR-120-wet-processing-pipeline.md) | 2026-08-13 | Phase 1 Deployed | | +| ADR-121 | ADR-121: Gemini Google Search Grounding for Brain Optimizer | [`ADR-121-gemini-grounding-integration.md`](./ADR-121-gemini-grounding-integration.md) | 2026-08-13 | Implemented | | +| ADR-122 | ADR-122: rvAgent Autonomous Gemini Grounding Agents | [`ADR-122-rvagent-gemini-grounding-agents.md`](./ADR-122-rvagent-gemini-grounding-agents.md) | 2026-08-13 | Approved with Revisions | | +| ADR-123 | ADR-123: Pi Brain Cognitive Enrichment | [`ADR-123-brain-cognitive-enrichment.md`](./ADR-123-brain-cognitive-enrichment.md) | 2026-08-13 | Accepted | | +| ADR-124 | ADR-124: Dynamic MinCut with Partition Cache | [`ADR-124-dynamic-partition-cache.md`](./ADR-124-dynamic-partition-cache.md) | 2026-08-13 | Shipped — All 3 tiers shipped and deployed through ruvbrain-00130 | | +| ADR-125 | ADR-125: Resend Email Integration for Pi Brain Notifications | [`ADR-125-resend-email-brain-integration.md`](./ADR-125-resend-email-brain-integration.md) | 2026-08-13 | Proposed | | +| ADR-126 | ADR-126: Google Chat Bot for Pi Brain Interaction | [`ADR-126-google-chat-brain-integration.md`](./ADR-126-google-chat-brain-integration.md) | 2026-08-13 | Proposed | | +| ADR-127 | ADR-127: Gist Deep Research Loop — Brain-Guided Discovery Publishing | [`ADR-127-gist-deep-research-loop.md`](./ADR-127-gist-deep-research-loop.md) | 2026-08-13 | Implemented | | +| ADR-128 | ADR-128: SOTA Gap Implementations — Hybrid Search, MLA, KV-Cache, SSM, Graph RAG | [`ADR-128-sota-gap-implementations.md`](./ADR-128-sota-gap-implementations.md) | 2026-08-13 | Accepted | | +| ADR-129 | ADR-129: RuvLTRA Model Training & TurboQuant Optimization on Google Cloud | [`ADR-129-ruvltra-gcloud-training-turboquant.md`](./ADR-129-ruvltra-gcloud-training-turboquant.md) | 2026-08-13 | Accepted — Phase 1 (calibration) deployed and executing. Governance and release | | +| ADR-130 | ADR-130: MCP SSE Decoupling via Midstream Queue Architecture | [`ADR-130-mcp-sse-decoupling-midstream-queue.md`](./ADR-130-mcp-sse-decoupling-midstream-queue.md) | 2026-08-13 | **Deployed** (2026-04-02) — Phases 1-3 complete. SSE decoupled to `mcp.pi.ruv.io | | +| ADR-131 | ADR-131: Consciousness Metrics Crate — IIT 4.0 Φ, CES, ΦID, PID, Streaming, Bounds | [`ADR-131-consciousness-metrics-crate.md`](./ADR-131-consciousness-metrics-crate.md) | 2026-08-13 | Accepted (Updated) | | +| ADR-132 | ADR-132: E2E Browser Testing with @claude-flow/browser | [`ADR-132-e2e-browser-testing-claude-flow.md`](./ADR-132-e2e-browser-testing-claude-flow.md) | 2026-08-13 | Proposed | DUPLICATE ×2 — cite as `ADR-132 (e2e-browser-testing-claude-flow)` | +| ADR-132 | ADR-132: RVM Hypervisor Core — Standalone Coherence-Native Microhypervisor | [`ADR-132-ruvix-hypervisor-core.md`](./ADR-132-ruvix-hypervisor-core.md) | 2026-08-13 | Proposed | DUPLICATE ×2 — cite as `ADR-132 (ruvix-hypervisor-core)` | +| ADR-133 | ADR-133: Claude Code CLI Source Code Analysis | [`ADR-133-claude-code-source-analysis.md`](./ADR-133-claude-code-source-analysis.md) | 2026-08-13 | Deployed (2026-04-02) | DUPLICATE ×2 — cite as `ADR-133 (claude-code-source-analysis)` | +| ADR-133 | ADR-133: Partition Object Model | [`ADR-133-partition-object-model.md`](./ADR-133-partition-object-model.md) | 2026-08-13 | Proposed | DUPLICATE ×2 — cite as `ADR-133 (partition-object-model)` | +| ADR-134 | ADR-134: RuVector Deep Integration with Claude Code CLI | [`ADR-134-ruvector-claude-code-deep-integration.md`](./ADR-134-ruvector-claude-code-deep-integration.md) | 2026-08-13 | Proposed | DUPLICATE ×2 — cite as `ADR-134 (ruvector-claude-code-deep-integration)` | +| ADR-134 | ADR-134: Witness Schema and Log Format | [`ADR-134-witness-schema-log-format.md`](./ADR-134-witness-schema-log-format.md) | 2026-08-13 | Proposed | DUPLICATE ×2 — cite as `ADR-134 (witness-schema-log-format)` | +| ADR-135 | ADR-135: MinCut Decompiler with RVF Witness Chains | [`ADR-135-mincut-decompiler-with-witness-chains.md`](./ADR-135-mincut-decompiler-with-witness-chains.md) | 2026-08-13 | Deployed (2026-04-03) — 8-phase pipeline implemented. Louvain partitioning (35x | DUPLICATE ×2 — cite as `ADR-135 (mincut-decompiler-with-witness-chains)` | +| ADR-135 | ADR-135: Proof Verifier Design — Three-Layer Verification for Capability-Gated Mutation | [`ADR-135-proof-verifier-design.md`](./ADR-135-proof-verifier-design.md) | 2026-08-13 | Proposed | DUPLICATE ×2 — cite as `ADR-135 (proof-verifier-design)` | +| ADR-136 | ADR-136: GPU-Trained Deobfuscation Model | [`ADR-136-gpu-trained-deobfuscation-model.md`](./ADR-136-gpu-trained-deobfuscation-model.md) | 2026-08-13 | Deployed (2026-04-03) — Model trained (673K params, 95.7% val accuracy), exporte | DUPLICATE ×2 — cite as `ADR-136 (gpu-trained-deobfuscation-model)` | +| ADR-136 | ADR-136: Memory Hierarchy and Reconstruction — Four-Tier Coherence-Driven Memory Model | [`ADR-136-memory-hierarchy-reconstruction.md`](./ADR-136-memory-hierarchy-reconstruction.md) | 2026-08-13 | Proposed | DUPLICATE ×2 — cite as `ADR-136 (memory-hierarchy-reconstruction)` | +| ADR-137 | ADR-137: Bare-Metal Boot Sequence | [`ADR-137-bare-metal-boot-sequence.md`](./ADR-137-bare-metal-boot-sequence.md) | 2026-08-13 | Proposed | DUPLICATE ×2 — cite as `ADR-137 (bare-metal-boot-sequence)` | +| ADR-137 | ADR-137: npm Decompiler CLI and MCP Tools | [`ADR-137-npm-decompiler-cli-and-mcp.md`](./ADR-137-npm-decompiler-cli-and-mcp.md) | 2026-08-13 | Deployed (2026-04-03) — CLI command + 6 MCP tools implemented. Decompiler librar | DUPLICATE ×2 — cite as `ADR-137 (npm-decompiler-cli-and-mcp)` | +| ADR-138 | ADR-138: LLM Model Weight Decompiler | [`ADR-138-llm-weight-decompiler.md`](./ADR-138-llm-weight-decompiler.md) | 2026-08-13 | Implemented (2026-04-03) -- GGUF and Safetensors format decompilation with archi | DUPLICATE ×2 — cite as `ADR-138 (llm-weight-decompiler)` | +| ADR-138 | ADR-138: Seed Hardware Bring-Up | [`ADR-138-seed-hardware-bring-up.md`](./ADR-138-seed-hardware-bring-up.md) | 2026-08-13 | Proposed | DUPLICATE ×2 — cite as `ADR-138 (seed-hardware-bring-up)` | +| ADR-139 | ADR-139: Appliance Deployment Model — Edge Hub with Coherence-Native Control | [`ADR-139-appliance-deployment-model.md`](./ADR-139-appliance-deployment-model.md) | 2026-08-13 | Proposed | DUPLICATE ×2 — cite as `ADR-139 (appliance-deployment-model)` | +| ADR-139 | ADR-139: RVAgent Optimization Using Decompiled Claude Code Intelligence | [`ADR-139-rvagent-claude-code-optimization.md`](./ADR-139-rvagent-claude-code-optimization.md) | 2026-08-13 | Proposed | DUPLICATE ×2 — cite as `ADR-139 (rvagent-claude-code-optimization)` | +| ADR-140 | ADR-140: Agent Runtime Adapter — WASM Agents in Coherence Domains | [`ADR-140-agent-runtime-adapter.md`](./ADR-140-agent-runtime-adapter.md) | 2026-08-13 | Proposed | | +| ADR-141 | ADR-141: Coherence Engine — Kernel Integration and Runtime Pipeline | [`ADR-141-coherence-engine-kernel-integration.md`](./ADR-141-coherence-engine-kernel-integration.md) | 2026-08-13 | Accepted | | +| ADR-142 | ADR-142: TEE-Backed Cryptographic Verification for the RVM Hypervisor | [`ADR-142-tee-backed-cryptographic-verification.md`](./ADR-142-tee-backed-cryptographic-verification.md) | 2026-08-13 | Accepted | | +| ADR-143 | ADR-143: HEARmusica — High-Fidelity Rust Port of Tympan Open-Source Hearing Aid | [`ADR-143-hearmusica-tympan-rust-port.md`](./ADR-143-hearmusica-tympan-rust-port.md) | 2026-08-13 | Accepted | DUPLICATE ×2 — cite as `ADR-143 (hearmusica-tympan-rust-port)` | +| ADR-143 | ADR-143: Implement Missing Capabilities in ruvector | [`ADR-143-implement-missing-capabilities.md`](./ADR-143-implement-missing-capabilities.md) | 2026-08-13 | Accepted | DUPLICATE ×2 — cite as `ADR-143 (implement-missing-capabilities)` | +| ADR-144 | ADR-144: Candle-Whisper Integration with Musica for Pure-Rust Transcription | [`ADR-144-candle-whisper-musica-transcription.md`](./ADR-144-candle-whisper-musica-transcription.md) | 2026-08-13 | Accepted | DUPLICATE ×3 — cite as `ADR-144 (candle-whisper-musica-transcription)` | +| ADR-144 | ADR-144: DiskANN/Vamana Implementation | [`ADR-144-diskann-vamana-implementation.md`](./ADR-144-diskann-vamana-implementation.md) | 2026-08-13 | Implemented | DUPLICATE ×3 — cite as `ADR-144 (diskann-vamana-implementation)` | +| ADR-144 | ADR-144: Monorepo Quality Analysis Strategy and Test Plan | [`ADR-144-monorepo-quality-analysis-strategy.md`](./ADR-144-monorepo-quality-analysis-strategy.md) | 2026-08-13 | Accepted | DUPLICATE ×3 — cite as `ADR-144 (monorepo-quality-analysis-strategy)` | +| ADR-145 | ADR-145: WASM/NAPI Training Pipeline Fixes | [`ADR-145-wasm-training-pipeline-fixes.md`](./ADR-145-wasm-training-pipeline-fixes.md) | 2026-08-13 | Accepted | | +| ADR-146 | ADR-144: DiskANN/Vamana Implementation | [`ADR-146-diskann-vamana-implementation.md`](./ADR-146-diskann-vamana-implementation.md) | 2026-08-13 | Implemented | | +| ADR-147 | ADR-147: Stacked KV Cache Compression: TriAttention + TurboQuant Pipeline | [`ADR-147-stacked-kv-cache-triattention-turboquant.md`](./ADR-147-stacked-kv-cache-triattention-turboquant.md) | 2026-08-13 | Proposed | | +| ADR-148 | ADR-148: Brain Hypothesis Engine — Self-Improving Knowledge System with Gemini, DiskANN, and Auto-Experimentation | [`ADR-148-brain-hypothesis-engine.md`](./ADR-148-brain-hypothesis-engine.md) | 2026-08-13 | Proposed | | +| ADR-149 | ADR-149: Brain Performance Optimizations — SIMD Search, Batch Graph, Incremental LoRA, Quality Gating | [`ADR-149-brain-performance-optimizations.md`](./ADR-149-brain-performance-optimizations.md) | 2026-08-13 | Accepted | | +| ADR-150 | ADR-150: π Brain + RuvLtra via Tailscale — Semantic Embedding Upgrade | [`ADR-150-pi-brain-ruvltra-tailscale.md`](./ADR-150-pi-brain-ruvltra-tailscale.md) | 2026-08-13 | Proposed | | +| ADR-151 | ADR-151: Miller-Rabin–Driven Prime Optimizations (PIAL) | [`ADR-151-miller-rabin-prime-optimizations.md`](./ADR-151-miller-rabin-prime-optimizations.md) | 2026-08-13 | Accepted (Phase 0 landed 2026-04-16; performance targets revised — see "Phase 0 | | +| ADR-153 | ADR-153: Kalshi Integration via RuVector Neural Trader | [`ADR-153-kalshi-neural-trader-integration.md`](./ADR-153-kalshi-neural-trader-integration.md) | 2026-08-13 | Proposed | | +| ADR-154 | ADR-154: RaBitQ — Rotation-Based 1-Bit Quantization for ANNS | [`ADR-154-rabitq-rotation-binary-quantization.md`](./ADR-154-rabitq-rotation-binary-quantization.md) | 2026-08-13 | Proposed | | +| ADR-155 | ADR-155: ruLake — Vector-Native Federation Intermediary on RVF | [`ADR-155-rulake-datalake-layer.md`](./ADR-155-rulake-datalake-layer.md) | 2026-08-13 | **Accepted (M1)** — core abstraction + LocalBackend + FsBackend shipped | | +| ADR-156 | ADR-156: ruLake as Memory Substrate for Agent Brain Systems | [`ADR-156-rulake-as-memory-substrate.md`](./ADR-156-rulake-as-memory-substrate.md) | 2026-08-13 | **Proposed** — positioning addendum, not a replacement. ADR-155 still | | +| ADR-157 | ADR-157: Optional Accelerator Plane — `VectorKernel` Trait + Dispatch | [`ADR-157-optional-accelerator-plane.md`](./ADR-157-optional-accelerator-plane.md) | 2026-08-13 | **Proposed** — scaffolding-only decision. No kernel implementations | | +| ADR-158 | ADR-158: Optional Rotation Kind (Haar vs Randomized Hadamard) and QVCache Positioning | [`ADR-158-optional-rotation-and-qvcache-positioning.md`](./ADR-158-optional-rotation-and-qvcache-positioning.md) | 2026-08-13 | **Proposed** — a knob-locking decision plus a positioning statement. | | +| ADR-159 | ADR-159: A2A (Agent-to-Agent) Protocol Support for rvAgent | [`ADR-159-rvagent-a2a-protocol.md`](./ADR-159-rvagent-a2a-protocol.md) | 2026-08-13 | **Proposed — r3 (second review pass 2026-04-24)**. A new subcrate | | +| ADR-160 | ADR-160: ACORN — Predicate-Agnostic Filtered HNSW for ruvector | [`ADR-160-acorn-filtered-hnsw.md`](./ADR-160-acorn-filtered-hnsw.md) | 2026-08-13 | Proposed | | +| ADR-161 | ADR-161: Publish `ruvector-rabitq-wasm` as `@ruvector/rabitq-wasm` on npm | [`ADR-161-rabitq-wasm-npm-package.md`](./ADR-161-rabitq-wasm-npm-package.md) | 2026-08-13 | Proposed | | +| ADR-162 | ADR-162: Add `ruvector-acorn-wasm` crate and publish as `@ruvector/acorn-wasm` on npm | [`ADR-162-acorn-wasm-npm-package.md`](./ADR-162-acorn-wasm-npm-package.md) | 2026-08-13 | Proposed | | +| ADR-165 | ADR-165: Tiny RuvLLM Agents on Heterogeneous ESP32 SoCs | [`ADR-165-tiny-ruvllm-agents-on-esp32-soCs.md`](./ADR-165-tiny-ruvllm-agents-on-esp32-soCs.md) | 2026-08-13 | Proposed | | +| ADR-166 | ADR-166: ESP32 Rust Cross-Compile + Bring-Up Operations Manual | [`ADR-166-esp32-rust-cross-compile-bringup-ops.md`](./ADR-166-esp32-rust-cross-compile-bringup-ops.md) | 2026-08-13 | Proposed | | +| ADR-167 | ADR-167 — ruvector Hailo-8 NPU embedding backend | [`ADR-167-ruvector-hailo-npu-embedding-backend.md`](./ADR-167-ruvector-hailo-npu-embedding-backend.md) | 2026-08-13 | Proposed | | +| ADR-168 | ADR-168 — Cluster CLI surface | [`ADR-168-ruvector-hailo-cluster-cli-surface.md`](./ADR-168-ruvector-hailo-cluster-cli-surface.md) | 2026-08-13 | Accepted | | +| ADR-169 | ADR-169 — Cluster cache architecture | [`ADR-169-ruvector-hailo-cluster-cache-architecture.md`](./ADR-169-ruvector-hailo-cluster-cache-architecture.md) | 2026-08-13 | Accepted | | +| ADR-170 | ADR-170 — Tracing correlation | [`ADR-170-ruvector-hailo-cluster-tracing-correlation.md`](./ADR-170-ruvector-hailo-cluster-tracing-correlation.md) | 2026-08-13 | Accepted | | +| ADR-171 | ADR-171 — ruOS brain + ruview on Pi 5 + Hailo-8 | [`ADR-171-ruos-brain-ruview-pi5-edge-node.md`](./ADR-171-ruos-brain-ruview-pi5-edge-node.md) | 2026-08-13 | Proposed | | +| ADR-172 | ADR-172 — Deep security review | [`ADR-172-ruvector-hailo-security-review.md`](./ADR-172-ruvector-hailo-security-review.md) | 2026-08-13 | Proposed | | +| ADR-173 | ADR-173 — ruvllm + Hailo on Pi 5 | [`ADR-173-ruvllm-hailo-edge-llm.md`](./ADR-173-ruvllm-hailo-edge-llm.md) | 2026-08-13 | Proposed | | +| ADR-174 | ADR-174 — ruOS thermal optimizer | [`ADR-174-ruos-thermal-overclock-pi5.md`](./ADR-174-ruos-thermal-overclock-pi5.md) | 2026-08-13 | Proposed | | +| ADR-175 | ADR-175 — Rust-side workarounds for Hailo Dataflow Compiler transformer-encoder bugs | [`ADR-175-hailo-rust-side-workarounds.md`](./ADR-175-hailo-rust-side-workarounds.md) | 2026-08-13 | accepted | | +| ADR-176 | ADR-176 — EPIC: Wire HEF into HailoEmbedder for NPU-accelerated embeddings | [`ADR-176-hef-integration-epic.md`](./ADR-176-hef-integration-epic.md) | 2026-08-13 | accepted | | +| ADR-177 | ADR-177 — Pi 4 / Pi 5 without AI HAT+ deploy | [`ADR-177-pi4-no-hat-deploy.md`](./ADR-177-pi4-no-hat-deploy.md) | 2026-08-13 | accepted | | +| ADR-178 | ADR-178 — ruvector + ruview / hailo cluster integration gap analysis | [`ADR-178-ruvector-ruview-hailo-integration-gap-analysis.md`](./ADR-178-ruvector-ruview-hailo-integration-gap-analysis.md) | 2026-08-13 | Proposed | | +| ADR-179 | ADR-179 — EPIC: ruvllm LLM inference on Pi 5 cluster | [`ADR-179-ruvllm-pi-cluster-deployment.md`](./ADR-179-ruvllm-pi-cluster-deployment.md) | 2026-08-13 | proposed | | +| ADR-180 | ADR-180 — ServingEngine continuous batching on Pi 5 | [`ADR-180-ruvllm-serving-engine-continuous-batching.md`](./ADR-180-ruvllm-serving-engine-continuous-batching.md) | 2026-08-13 | proposed | | +| ADR-181 | ADR-181 — In-tree pi_quant + BitNet b1.58 on Pi 5 | [`ADR-181-ruvllm-pi-quant-bitnet-integration.md`](./ADR-181-ruvllm-pi-quant-bitnet-integration.md) | 2026-08-13 | proposed | | +| ADR-182 | ADR-182 — Hailo-10H migration for the Pi 5 cluster | [`ADR-182-hailo-10-cluster-migration.md`](./ADR-182-hailo-10-cluster-migration.md) | 2026-08-13 | proposed | | +| ADR-183 | ADR-183 — Move `rand` to dev-dependencies in ruvllm_sparse_attention | [`ADR-183-sparse-attention-rand-dev-dependency.md`](./ADR-183-sparse-attention-rand-dev-dependency.md) | 2026-08-13 | accepted | | +| ADR-184 | ADR-184 — One-pass online softmax in SubquadraticSparseAttention::forward | [`ADR-184-sparse-attention-online-softmax.md`](./ADR-184-sparse-attention-online-softmax.md) | 2026-08-13 | accepted | | +| ADR-185 | ADR-185 — Exclude current block from non-causal landmark candidates | [`ADR-185-sparse-attention-noncausal-landmark-fix.md`](./ADR-185-sparse-attention-noncausal-landmark-fix.md) | 2026-08-13 | accepted | | +| ADR-186 | ADR-186 — Edge-case tests as CI gate before Hailo cluster integration | [`ADR-186-sparse-attention-edge-case-tests.md`](./ADR-186-sparse-attention-edge-case-tests.md) | 2026-08-13 | accepted | | +| ADR-187 | ADR-187 — Overflow-checked shape multiplication in `Tensor3::zeros` | [`ADR-187-tensor-zeros-overflow-check.md`](./ADR-187-tensor-zeros-overflow-check.md) | 2026-08-13 | accepted | | +| ADR-188 | ADR-188 — Document the intentional stamp scheme difference in sparse attention | [`ADR-188-sparse-attention-stamp-scheme-comment.md`](./ADR-188-sparse-attention-stamp-scheme-comment.md) | 2026-08-13 | accepted | | +| ADR-189 | ADR-189 — KV cache incremental decode for sparse attention on Hailo-10H | [`ADR-189-sparse-attention-kv-cache-incremental-decode.md`](./ADR-189-sparse-attention-kv-cache-incremental-decode.md) | 2026-08-13 | accepted | | +| ADR-190 | ADR-190 — Grouped-Query / Multi-Query Attention for Hailo-10H production models | [`ADR-190-sparse-attention-gqa-mqa-support.md`](./ADR-190-sparse-attention-gqa-mqa-support.md) | 2026-08-13 | accepted | | +| ADR-191 | ADR-191 — Pi Zero 2W production hardening for ruvllm_sparse_attention | [`ADR-191-sparse-attention-pi-zero-2w-production-hardening.md`](./ADR-191-sparse-attention-pi-zero-2w-production-hardening.md) | 2026-08-13 | proposed | | +| ADR-192 | ADR-192 — no_std + alloc support for `ruvllm_sparse_attention` | [`ADR-192-sparse-attention-no-std-esp32-support.md`](./ADR-192-sparse-attention-no-std-esp32-support.md) | 2026-08-13 | accepted | | +| ADR-193 | ADR-193 — RAIRS IVF: ruvector's First Inverted File Index Family | [`ADR-193-rairs-ivf.md`](./ADR-193-rairs-ivf.md) | 2026-08-13 | accepted | | +| ADR-194 | ADR-194 — GNN-Enhanced Candidate Reranking for Approximate ANN | [`ADR-194-gnn-rerank.md`](./ADR-194-gnn-rerank.md) | 2026-08-13 | accepted | DUPLICATE ×3 — cite as `ADR-194 (gnn-rerank)` | +| ADR-194 | ADR-194: Proof-Gated Vector Writes with Merkle-Accumulating Witness Logs | [`ADR-194-proof-gated-writes.md`](./ADR-194-proof-gated-writes.md) | 2026-08-13 | Proposed | DUPLICATE ×3 — cite as `ADR-194 (proof-gated-writes)` | +| ADR-194 | ADR-194 — RuVector Bundled ONNX Embedder: API Contract & Throughput | [`ADR-194-ruvector-onnx-embedder-api-and-throughput.md`](./ADR-194-ruvector-onnx-embedder-api-and-throughput.md) | 2026-08-13 | accepted | DUPLICATE ×3 — cite as `ADR-194 (ruvector-onnx-embedder-api-and-throughput)` | +| ADR-195 | ADR-195 — ONNX Embedder Unification Plan | [`ADR-195-ruvector-embedder-unification-plan.md`](./ADR-195-ruvector-embedder-unification-plan.md) | 2026-08-13 | proposed | | +| ADR-196 | ADR-196 — Structure-Preserving Graph Condensation | [`ADR-196-structure-preserving-graph-condensation.md`](./ADR-196-structure-preserving-graph-condensation.md) | 2026-08-13 | accepted | | +| ADR-197 | ADR-197 — Differentiable Min-Cut Condensation Loss | [`ADR-197-differentiable-min-cut-condensation-loss.md`](./ADR-197-differentiable-min-cut-condensation-loss.md) | 2026-08-13 | accepted | | +| ADR-198 | ADR-198 — Physical Perception Substrate | [`ADR-198-physical-perception-substrate.md`](./ADR-198-physical-perception-substrate.md) | 2026-08-13 | accepted | | +| ADR-199 | ADR-199 — Sky Monitor and SkyGraph Appliance | [`ADR-199-sky-monitor-skygraph-appliance.md`](./ADR-199-sky-monitor-skygraph-appliance.md) | 2026-08-13 | proposed | | +| ADR-202 | ADR-202 — Fixed-Topology Reuse + Periodic Rebuild on a Real Learned-GNN Trajectory | [`ADR-202-reuse-under-drift-real-gnn-trajectory.md`](./ADR-202-reuse-under-drift-real-gnn-trajectory.md) | 2026-08-13 | proposed | | +| ADR-205 | ADR-205 — Triangle-Inequality Cluster Pruning vs Tuned Plain IVF `nprobe` (Structural NO-GO) | [`ADR-205-region-pruned-ivf-vs-plain-ivf-nprobe.md`](./ADR-205-region-pruned-ivf-vs-plain-ivf-nprobe.md) | 2026-08-13 | proposed | | +| ADR-206 | ADR-206 — PQ/IVFADC Within-List Pruning vs Tuned Plain IVF `nprobe` (Scale-Gated WIN) | [`ADR-206-pq-ivfadc-within-list-pruning-vs-plain-ivf-nprobe.md`](./ADR-206-pq-ivfadc-within-list-pruning-vs-plain-ivf-nprobe.md) | 2026-08-13 | proposed | | +| ADR-210 | ADR-210: Default-On Semantic Embeddings — all-MiniLM-L6-v2 as the Intelligence Engine's Primary Embedder | [`ADR-210-default-on-semantic-embeddings-minilm.md`](./ADR-210-default-on-semantic-embeddings-minilm.md) | 2026-08-13 | accepted (with hardening edits, review of 2026-06-12) | | +| ADR-211 | ADR-211 — Temporal Coherence Decay for Agent Memory Retrieval | [`ADR-211-temporal-coherence-agent-memory.md`](./ADR-211-temporal-coherence-agent-memory.md) | 2026-08-13 | accepted | | +| ADR-251 | ADR-251: Agentic Time as a First-Class Runtime Primitive | [`ADR-251-agentic-time.md`](./ADR-251-agentic-time.md) | 2026-08-13 | proposed | | +| ADR-252 | ADR-252: Coherence-Weighted Agent Memory Compaction | [`ADR-252-agent-memory-compaction.md`](./ADR-252-agent-memory-compaction.md) | 2026-08-13 | Proposed | DUPLICATE ×3 — cite as `ADR-252 (agent-memory-compaction)` | +| ADR-252 | ADR-252: FastGRNN Training Pipeline for Tiny Dancer Routing | [`ADR-252-fastgrnn-training-pipeline.md`](./ADR-252-fastgrnn-training-pipeline.md) | 2026-08-13 | accepted | DUPLICATE ×3 — cite as `ADR-252 (fastgrnn-training-pipeline)` | +| ADR-252 | ADR-252: Multi-Vector MaxSim Late Interaction Search | [`ADR-252-multi-vector-maxsim.md`](./ADR-252-multi-vector-maxsim.md) | 2026-08-13 | Accepted — PoC merged, production graduation pending | DUPLICATE ×3 — cite as `ADR-252 (multi-vector-maxsim)` | +| ADR-253 | ADR-253 — HelixDB vs RuVector: Comparative Analysis and Improvement Opportunities | [`ADR-253-helixdb-comparison-ruvector-improvements.md`](./ADR-253-helixdb-comparison-ruvector-improvements.md) | 2026-08-13 | proposed | | +| ADR-254 | ADR-254 — Coherence-Gated HNSW Search | [`ADR-254-coherence-hnsw-search.md`](./ADR-254-coherence-hnsw-search.md) | 2026-08-13 | proposed | DUPLICATE ×2 — cite as `ADR-254 (coherence-hnsw-search)` | +| ADR-254 | ADR-254 — ruvector-turbovec: a multi-bit TurboQuant FastScan ANN index | [`ADR-254-ruvector-turbovec-fastscan-index.md`](./ADR-254-ruvector-turbovec-fastscan-index.md) | 2026-08-13 | accepted | DUPLICATE ×2 — cite as `ADR-254 (ruvector-turbovec-fastscan-index)` | +| ADR-255 | ADR-255 — ruvector ↔ OIA Model integration (Open Intelligence Architecture v0.1) | [`ADR-255-oia-model-integration.md`](./ADR-255-oia-model-integration.md) | 2026-08-13 | proposed | | +| ADR-256 | ADR-256 — Hybrid Sparse-Dense Search: RRF and RSF alongside ScoreFusion | [`ADR-256-hybrid-sparse-dense-search.md`](./ADR-256-hybrid-sparse-dense-search.md) | 2026-08-13 | proposed | DUPLICATE ×2 — cite as `ADR-256 (hybrid-sparse-dense-search)` | +| ADR-256 | ADR-256 — Borrowing `metaharness` concepts into `npx ruvector` | [`ADR-256-metaharness-sdk-evaluation.md`](./ADR-256-metaharness-sdk-evaluation.md) | 2026-08-13 | proposed | DUPLICATE ×2 — cite as `ADR-256 (metaharness-sdk-evaluation)` | +| ADR-257 | ADR-257 — Extract `ruqu` and `rvdna` into standalone repos (git submodules) | [`ADR-257-ruqu-rvdna-standalone-submodules.md`](./ADR-257-ruqu-rvdna-standalone-submodules.md) | 2026-08-13 | proposed | | +| ADR-258 | ADR-258 — ruvector-hnsw-repair: Pluggable HNSW Deletion Strategies | [`ADR-258-hnsw-delete-repair.md`](./ADR-258-hnsw-delete-repair.md) | 2026-08-13 | accepted | DUPLICATE ×2 — cite as `ADR-258 (hnsw-delete-repair)` | +| ADR-258 | ADR-258: GPU Optimization of RDT/OpenMythos ACT Halting Loop | [`ADR-258-ruvllm-rdt-gpu-optimization.md`](./ADR-258-ruvllm-rdt-gpu-optimization.md) | 2026-08-13 | Accepted | DUPLICATE ×2 — cite as `ADR-258 (ruvllm-rdt-gpu-optimization)` | +| ADR-259 | ADR-259: ruvllm as Local Mutator Backend for Darwin Mode | [`ADR-259-ruvllm-darwin-mode-local-mutator.md`](./ADR-259-ruvllm-darwin-mode-local-mutator.md) | 2026-08-13 | Implemented (code + unit tests + CLI; live-serve e2e blocked by a ruvllm downloa | | +| ADR-260 | ADR-260: Darwin Mode as Evolutionary Substrate for MetaHarness | [`ADR-260-darwin-mode-metaharness-integration.md`](./ADR-260-darwin-mode-metaharness-integration.md) | 2026-08-13 | Accepted | DUPLICATE ×2 — cite as `ADR-260 (darwin-mode-metaharness-integration)` | +| ADR-260 | ADR-260: PhotonLayer — Learned-Optical-Frontend Computing Simulator | [`ADR-260-photonlayer-optical-computing-simulator.md`](./ADR-260-photonlayer-optical-computing-simulator.md) | 2026-08-13 | Proposed | DUPLICATE ×2 — cite as `ADR-260 (photonlayer-optical-computing-simulator)` | +| ADR-261 | ADR-261: PhotonLayer — Mask Exchange Format & Determinism Invariant | [`ADR-261-photonlayer-mask-exchange-and-determinism.md`](./ADR-261-photonlayer-mask-exchange-and-determinism.md) | 2026-08-13 | Proposed | | +| ADR-262 | ADR-262: PhotonLayer — Privacy-Preserving Optical Verification | [`ADR-262-photonlayer-privacy-preserving-optical-verification.md`](./ADR-262-photonlayer-privacy-preserving-optical-verification.md) | 2026-08-13 | Proposed | | +| ADR-263 | ADR-263 — PhotonLayer FiberGate | [`ADR-263-photonlayer-fibergate-transmission-matrix.md`](./ADR-263-photonlayer-fibergate-transmission-matrix.md) | 2026-08-13 | proposed | | +| ADR-264 | ADR-264: LSM-ANN — Write-Optimised Streaming Vector Index for Agent Memory | [`ADR-264-lsm-ann.md`](./ADR-264-lsm-ann.md) | 2026-08-13 | Accepted | DUPLICATE ×3 — cite as `ADR-264 (lsm-ann)` | +| ADR-264 | ADR-264: Matryoshka-Aware Coarse-to-Fine Vector Search | [`ADR-264-matryoshka-coarse-fine-search.md`](./ADR-264-matryoshka-coarse-fine-search.md) | 2026-08-13 | Proposed | DUPLICATE ×3 — cite as `ADR-264 (matryoshka-coarse-fine-search)` | +| ADR-264 | ADR-264: Product Quantization with Asymmetric Distance Computation | [`ADR-264-pq-adc-search.md`](./ADR-264-pq-adc-search.md) | 2026-08-13 | Proposed | DUPLICATE ×3 — cite as `ADR-264 (pq-adc-search)` | +| ADR-265 | ADR-265: RuVector Comprehensive Benchmark Suite | [`ADR-265-ruvector-comprehensive-benchmark-suite.md`](./ADR-265-ruvector-comprehensive-benchmark-suite.md) | 2026-08-13 | Accepted | | +| ADR-266 | ADR-266: MetaHarness Integration for Autonomous ANN Optimization (Darwin Mode) | [`ADR-266-metaharness-darwin-ann-optimization.md`](./ADR-266-metaharness-darwin-ann-optimization.md) | 2026-08-13 | Accepted | DUPLICATE ×2 — cite as `ADR-266 (metaharness-darwin-ann-optimization)` | +| ADR-266 | ADR-266: MetaHarness Integration for Autonomous ANN Optimization (Darwin Mode) | [`ADR-266-metaharness-darwin-integration.md`](./ADR-266-metaharness-darwin-integration.md) | 2026-08-13 | Accepted | DUPLICATE ×2 — cite as `ADR-266 (metaharness-darwin-integration)` | +| ADR-267 | ADR-267: SOTA Validation Protocol for RuVector | [`ADR-267-sota-validation-protocol.md`](./ADR-267-sota-validation-protocol.md) | 2026-08-13 | Accepted | | +| ADR-268 | ADR-268: Capability-Gated ANN Search | [`ADR-268-capability-gated-ann.md`](./ADR-268-capability-gated-ann.md) | 2026-08-13 | Proposed | DUPLICATE ×2 — cite as `ADR-268 (capability-gated-ann)` | +| ADR-268 | ADR-268 — SPANN Partition Spilling: Boundary-Safe ANN | [`ADR-268-spann-partition-spill.md`](./ADR-268-spann-partition-spill.md) | 2026-08-13 | accepted | DUPLICATE ×2 — cite as `ADR-268 (spann-partition-spill)` | +| ADR-269 | ADR-269: MRAgent Graph Memory over RuVector, Optimized by Darwin Mode | [`ADR-269-mragent-graph-memory-darwin-optimization.md`](./ADR-269-mragent-graph-memory-darwin-optimization.md) | 2026-08-13 | Accepted | | +| ADR-270 | ADR-270: Self-Reconstructing Graph Memory — Beyond MRAgent | [`ADR-270-self-reconstructing-graph-memory-beyond-sota.md`](./ADR-270-self-reconstructing-graph-memory-beyond-sota.md) | 2026-08-13 | Accepted | | +| ADR-271 | ADR-271: Metaharness-Darwin for SONA Self-Improvement — EWC Config Evolution, the weightAdapter Gene, and Ornith-1.0 Reward-Hacking Defenses | [`ADR-271-metaharness-darwin-sona-self-improvement.md`](./ADR-271-metaharness-darwin-sona-self-improvement.md) | 2026-08-13 | Proposed (all four components prototyped — PR #615) | | +| ADR-272 | ADR-272: Adaptive Recall-Targeted ANN Search | [`ADR-272-adaptive-recall-ann.md`](./ADR-272-adaptive-recall-ann.md) | 2026-08-13 | Proposed | DUPLICATE ×5 — cite as `ADR-272 (adaptive-recall-ann)` | +| ADR-272 | ADR-272: Bounded Context RAG via MinCut Graph Partitioning | [`ADR-272-bounded-rag-mincut.md`](./ADR-272-bounded-rag-mincut.md) | 2026-08-13 | Proposed | DUPLICATE ×5 — cite as `ADR-272 (bounded-rag-mincut)` | +| ADR-272 | ADR-272: Diverse Beam ANN — MMR Post-Reranking and Coherence-Pruned Beam Search | [`ADR-272-diverse-beam-ann.md`](./ADR-272-diverse-beam-ann.md) | 2026-08-13 | Proposed (implemented and benchmarked — `crates/ruvector-diverse-beam`) | DUPLICATE ×5 — cite as `ADR-272 (diverse-beam-ann)` | +| ADR-272 | ADR-272: Recall-Bounded Approximate Nearest-Neighbour Search | [`ADR-272-recall-bounded-ann.md`](./ADR-272-recall-bounded-ann.md) | 2026-08-13 | Proposed — proof-of-concept in `crates/ruvector-recall-bounded` | DUPLICATE ×5 — cite as `ADR-272 (recall-bounded-ann)` | +| ADR-272 | ADR-272: Speculative ANN Search | [`ADR-272-speculative-ann-search.md`](./ADR-272-speculative-ann-search.md) | 2026-08-13 | Proposed | DUPLICATE ×5 — cite as `ADR-272 (speculative-ann-search)` | +| ADR-273 | ADR-273 — rvAgent Harness Reliability Floor | [`ADR-273-rvagent-harness-reliability-floor.md`](./ADR-273-rvagent-harness-reliability-floor.md) | 2026-08-13 | accepted | | +| ADR-274 | ADR-274 — rvAgent Context Management: Masking over Summarization | [`ADR-274-rvagent-context-management.md`](./ADR-274-rvagent-context-management.md) | 2026-08-13 | accepted | | +| ADR-275 | ADR-275 — rvAgent Subagent Topology: Single Writer with Auxiliary Intelligence | [`ADR-275-rvagent-subagent-topology.md`](./ADR-275-rvagent-subagent-topology.md) | 2026-08-13 | accepted | | +| ADR-276 | ADR-276 — rvAgent Learning Loop: Gating, Trust Tiers and Measurement | [`ADR-276-rvagent-learning-loop-gating.md`](./ADR-276-rvagent-learning-loop-gating.md) | 2026-08-13 | accepted | | +| ADR-277 | ADR-277 — rvAgent Positioning, Protocols and Benchmark Claims | [`ADR-277-rvagent-positioning-and-claims.md`](./ADR-277-rvagent-positioning-and-claims.md) | 2026-08-13 | accepted | | +| ADR-278 | ADR-278 — rvAgent Self-Learning: Adopt the metaharness Flywheel; Shift from Memory to Policy | [`ADR-278-rvagent-flywheel-adoption.md`](./ADR-278-rvagent-flywheel-adoption.md) | 2026-08-13 | accepted | | +| ADR-279 | ADR-279 — No C in the Core; and the 2026 SOTA Program | [`ADR-279-no-c-and-the-sota-program.md`](./ADR-279-no-c-and-the-sota-program.md) | 2026-08-13 | accepted | | +| ADR-280 | ADR-280: Durable Metadata for Self-Contained RVF Artifacts | [`ADR-280-rvf-durable-self-contained-metadata.md`](./ADR-280-rvf-durable-self-contained-metadata.md) | 2026-08-13 | Proposed | | +| ADR-281 | ADR-281: Role-Aware Embedding APIs for Asymmetric Retrieval | [`ADR-281-role-aware-embedding-apis.md`](./ADR-281-role-aware-embedding-apis.md) | 2026-08-13 | Proposed | | +| ADR-282 | ADR-282: Pre-PR Quality Gate for Nightly “Dream” Research | [`ADR-282-nightly-research-quality-gate.md`](./ADR-282-nightly-research-quality-gate.md) | 2026-08-13 | Proposed | | +| ADR-283 | ADR-283: RVForge — One Canonical RVF to Signed Platform Installers | [`ADR-283-rvf-forge-canonical-installer-pipeline.md`](./ADR-283-rvf-forge-canonical-installer-pipeline.md) | 2026-08-13 | Accepted | | +| ADR-284 | ADR-284: RVF Execution Contract for RVM Backends | [`ADR-284-rvf-execution-contract.md`](./ADR-284-rvf-execution-contract.md) | 2026-08-13 | Accepted | | +| ADR-285 | ADR-285: Hosted RVM Security Boundary | [`ADR-285-hosted-rvm-security-boundary.md`](./ADR-285-hosted-rvm-security-boundary.md) | 2026-08-13 | Accepted | | +| ADR-286 | ADR-286: RVF Capability Schema Mapping into `rvm-cap` | [`ADR-286-rvf-capability-schema-mapping.md`](./ADR-286-rvf-capability-schema-mapping.md) | 2026-08-13 | Accepted | | +| ADR-287 | ADR-287: WASM Component Model Integration for the RVM Runtime | [`ADR-287-wasm-component-model-integration.md`](./ADR-287-wasm-component-model-integration.md) | 2026-08-13 | Proposed | | +| ADR-288 | ADR-288: Immutable Base RVF and Encrypted State Delta Lifecycle | [`ADR-288-immutable-base-state-delta-lifecycle.md`](./ADR-288-immutable-base-state-delta-lifecycle.md) | 2026-08-13 | Accepted | | +| ADR-289 | ADR-289: Desktop Host Adapters, Lifecycle CLI, and Embedding Surfaces | [`ADR-289-desktop-host-adapters.md`](./ADR-289-desktop-host-adapters.md) | 2026-08-13 | Accepted | | +| ADR-290 | ADR-290: Forge Build and Signing Trust Boundary | [`ADR-290-forge-build-signing-trust-boundary.md`](./ADR-290-forge-build-signing-trust-boundary.md) | 2026-08-13 | Proposed | | +| ADR-291 | ADR-291: Runtime Compatibility and Version Negotiation | [`ADR-291-runtime-compatibility-version-negotiation.md`](./ADR-291-runtime-compatibility-version-negotiation.md) | 2026-08-13 | Implemented | | +| ADR-292 | ADR-292: Native Acceleration Isolation | [`ADR-292-native-acceleration-isolation.md`](./ADR-292-native-acceleration-isolation.md) | 2026-08-13 | Proposed | | +| ADR-293 | ADR-293: RVM Installer and Appliance Formats | [`ADR-293-rvm-installer-appliance-formats.md`](./ADR-293-rvm-installer-appliance-formats.md) | 2026-08-13 | Proposed | | +| ADR-294 | ADR-294: RVForge Platform — Agent Store, Registry, and Trust System | [`ADR-294-rvforge-platform-store-registry-trust.md`](./ADR-294-rvforge-platform-store-registry-trust.md) | 2026-08-13 | Accepted | | +| ADR-295 | ADR-295: RVForge Agent Dock — Persistent Security and Control Surface | [`ADR-295-rvforge-agent-dock.md`](./ADR-295-rvforge-agent-dock.md) | 2026-08-13 | Implemented | | +| ADR-296 | ADR-296: Turbo4 — 4-bit Lloyd-Max Quantized Vector Datatype with Direct Packed HNSW Scoring | [`ADR-296-turbo4-quantized-vector-datatype.md`](./ADR-296-turbo4-quantized-vector-datatype.md) | 2026-08-13 | Accepted | | +| ADR-297 | ADR-297: Adaptive Compression & Retrieval Plane (ACRP) | [`ADR-297-adaptive-compression-retrieval-plane.md`](./ADR-297-adaptive-compression-retrieval-plane.md) | 2026-08-13 | Accepted | | +| ADR-299 | ADR-299: Namespace-Merge via S-T Mincut Routing | [`ADR-299-namespace-merge-mincut.md`](./ADR-299-namespace-merge-mincut.md) | 2026-08-13 | Accepted | | +| ADR-300 | ADR-300: Hierarchical Cluster-Summary Retrieval for Agent Memory RAG | [`ADR-300-hierarchical-cluster-rag.md`](./ADR-300-hierarchical-cluster-rag.md) | 2026-08-13 | Proposed | | +| ADR-301 | ADR-301: Semantic Query Cache for ANN | [`ADR-301-semantic-query-cache.md`](./ADR-301-semantic-query-cache.md) | 2026-08-13 | Proposed | | +| ADR-302 | ADR-302: Streaming Quantized Neighbourhood Graphs (QNG-Stream) | [`ADR-302-streaming-qng.md`](./ADR-302-streaming-qng.md) | 2026-08-13 | Proposed | | +| ADR-303 | ADR-303: Entropy-Adaptive Beam Search for ANN Graph Traversal | [`ADR-303-entropy-adaptive-ann.md`](./ADR-303-entropy-adaptive-ann.md) | 2026-08-13 | Closed — negative result (documented; not recommended for production) | | +| ADR-304 | ADR-304: Retrieval Receipts — Witness-Chained Provenance for ANN Query Results | [`ADR-304-retrieval-receipts.md`](./ADR-304-retrieval-receipts.md) | 2026-08-13 | Proposed. Experimental crate (`ruvector-retrieval-receipt`), not wired into | | +| ADR-305 | ADR-305: Adopt Autogenous ADR-401 and LatentMesh ADR-009 as the Perpetual Intelligence Runtime's Definition and Control-Loop Spine | [`ADR-305-adopt-latentmesh-adr009-control-loop-spine.md`](./ADR-305-adopt-latentmesh-adr009-control-loop-spine.md) | 2026-08-19 | Proposed | | +| ADR-306 | ADR-306: Dream Machine — Adopt the Consolidating Evaluation Engine, Wired to research-gate and Darwin | [`ADR-306-dream-machine-sona-darwin-unification.md`](./ADR-306-dream-machine-sona-darwin-unification.md) | 2026-08-19 | Proposed | | +| ADR-307 | ADR-307: Three-Level Persistent Memory Architecture (LiveMem + TARL Pattern) on RuVector | [`ADR-307-three-level-persistent-memory-livemem-tarl.md`](./ADR-307-three-level-persistent-memory-livemem-tarl.md) | 2026-08-19 | Proposed | | +| ADR-308 | ADR-308: WorldCycle-Style Verification for the Physical Action Loop | [`ADR-308-worldcycle-verification-physical-action-loop.md`](./ADR-308-worldcycle-verification-physical-action-loop.md) | 2026-08-19 | Proposed | | +| ADR-309 | ADR-309: Build LatentMesh Integration Inside ruvector as New Crates, Coordinated on Wire Format | [`ADR-309-latentmesh-greenfield-crates-wire-format-coordination.md`](./ADR-309-latentmesh-greenfield-crates-wire-format-coordination.md) | 2026-08-19 | Proposed | | +| ADR-310 | ADR-310: Causal-Attribution Gate for Latent Communication | [`ADR-310-causal-attribution-gate-latent-communication.md`](./ADR-310-causal-attribution-gate-latent-communication.md) | 2026-08-19 | Proposed | | +| ADR-311 | ADR-311: Anomaly Quarantine for Latent Channels (Net-New Work — Not "LATTE") | [`ADR-311-anomaly-quarantine-latent-channels-net-new.md`](./ADR-311-anomaly-quarantine-latent-channels-net-new.md) | 2026-08-19 | Proposed | | +| ADR-312 | ADR-312: Shared Witness Record Schema and Cross-Layer Anchoring Contract (rvm-witness ↔ autogenous witness) | [`ADR-312-shared-witness-schema-anchoring-contract.md`](./ADR-312-shared-witness-schema-anchoring-contract.md) | 2026-08-19 | Proposed | | +| ADR-313 | ADR-313: SHAPER-Pattern Skill/Harness Evolution Loop (Frozen Weights) | [`ADR-313-shaper-frozen-weight-skill-harness-evolution.md`](./ADR-313-shaper-frozen-weight-skill-harness-evolution.md) | 2026-08-19 | Proposed | | +| ADR-314 | ADR-314: KV-Cache Cross-Model Migration in ruvLLM (Fast-Follow) | [`ADR-314-kv-cache-cross-model-migration-ruvllm.md`](./ADR-314-kv-cache-cross-model-migration-ruvllm.md) | 2026-08-19 | Proposed | | +| ADR-315 | ADR-315: Governance Constitution for Capability Expansion | [`ADR-315-governance-constitution-capability-expansion.md`](./ADR-315-governance-constitution-capability-expansion.md) | 2026-08-19 | Proposed | | +| ADR-316 | ADR-316: ADR Numbering Hygiene — Frozen Duplicates, Canonical Counter, Collision Gate | [`ADR-316-adr-numbering-hygiene.md`](./ADR-316-adr-numbering-hygiene.md) | 2026-08-19 | Proposed | | +| ADR-CE-001 | ADR-CE-001: Sheaf Laplacian Defines Coherence Witness | [`coherence-engine/ADR-CE-001-sheaf-laplacian-coherence.md`](./coherence-engine/ADR-CE-001-sheaf-laplacian-coherence.md) | 2026-08-13 | Accepted | | +| ADR-CE-002 | ADR-CE-002: Incremental Coherence Computation | [`coherence-engine/ADR-CE-002-incremental-computation.md`](./coherence-engine/ADR-CE-002-incremental-computation.md) | 2026-08-13 | Accepted | | +| ADR-CE-003 | ADR-CE-003: PostgreSQL + Ruvector Unified Substrate | [`coherence-engine/ADR-CE-003-hybrid-storage.md`](./coherence-engine/ADR-CE-003-hybrid-storage.md) | 2026-08-13 | Accepted | | +| ADR-CE-004 | ADR-CE-004: Signed Event Log with Deterministic Replay | [`coherence-engine/ADR-CE-004-signed-event-log.md`](./coherence-engine/ADR-CE-004-signed-event-log.md) | 2026-08-13 | Accepted | | +| ADR-CE-005 | ADR-CE-005: First-Class Governance Objects | [`coherence-engine/ADR-CE-005-governance-objects.md`](./coherence-engine/ADR-CE-005-governance-objects.md) | 2026-08-13 | Accepted | | +| ADR-CE-006 | ADR-CE-006: Coherence Gate Controls Compute Ladder | [`coherence-engine/ADR-CE-006-compute-ladder.md`](./coherence-engine/ADR-CE-006-compute-ladder.md) | 2026-08-13 | Accepted | | +| ADR-CE-007 | ADR-CE-007: Thresholds Auto-Tuned from Production Traces | [`coherence-engine/ADR-CE-007-threshold-autotuning.md`](./coherence-engine/ADR-CE-007-threshold-autotuning.md) | 2026-08-13 | Accepted | | +| ADR-CE-008 | ADR-CE-008: Multi-Tenant Isolation | [`coherence-engine/ADR-CE-008-multi-tenant-isolation.md`](./coherence-engine/ADR-CE-008-multi-tenant-isolation.md) | 2026-08-13 | Accepted | | +| ADR-CE-009 | ADR-CE-009: Single Coherence Object | [`coherence-engine/ADR-CE-009-single-coherence-object.md`](./coherence-engine/ADR-CE-009-single-coherence-object.md) | 2026-08-13 | Accepted | | +| ADR-CE-010 | ADR-CE-010: Domain-Agnostic Nodes and Edges | [`coherence-engine/ADR-CE-010-domain-agnostic-substrate.md`](./coherence-engine/ADR-CE-010-domain-agnostic-substrate.md) | 2026-08-13 | Accepted | | +| ADR-CE-011 | ADR-CE-011: Residual = Contradiction Energy | [`coherence-engine/ADR-CE-011-residual-contradiction-energy.md`](./coherence-engine/ADR-CE-011-residual-contradiction-energy.md) | 2026-08-13 | Accepted | | +| ADR-CE-012 | ADR-CE-012: Gate = Refusal Mechanism with Witness | [`coherence-engine/ADR-CE-012-gate-refusal-witness.md`](./coherence-engine/ADR-CE-012-gate-refusal-witness.md) | 2026-08-13 | Accepted | | +| ADR-CE-013 | ADR-CE-013: Not Prediction | [`coherence-engine/ADR-CE-013-not-prediction.md`](./coherence-engine/ADR-CE-013-not-prediction.md) | 2026-08-13 | Accepted | | +| ADR-CE-014 | ADR-CE-014: Reflex Lane Default | [`coherence-engine/ADR-CE-014-reflex-lane-default.md`](./coherence-engine/ADR-CE-014-reflex-lane-default.md) | 2026-08-13 | Accepted | | +| ADR-CE-015 | ADR-CE-015: Adapt Without Losing Control | [`coherence-engine/ADR-CE-015-adapt-without-losing-control.md`](./coherence-engine/ADR-CE-015-adapt-without-losing-control.md) | 2026-08-13 | Accepted | | +| ADR-CE-016 | ADR-CE-016: RuvLLM CoherenceValidator Uses Sheaf Energy | [`coherence-engine/ADR-CE-016-ruvllm-coherence-validator.md`](./coherence-engine/ADR-CE-016-ruvllm-coherence-validator.md) | 2026-08-13 | Accepted | | +| ADR-CE-017 | ADR-CE-017: Unified Audit Trail | [`coherence-engine/ADR-CE-017-unified-audit-trail.md`](./coherence-engine/ADR-CE-017-unified-audit-trail.md) | 2026-08-13 | Accepted | | +| ADR-CE-018 | ADR-CE-018: Pattern-to-Restriction Bridge | [`coherence-engine/ADR-CE-018-pattern-restriction-bridge.md`](./coherence-engine/ADR-CE-018-pattern-restriction-bridge.md) | 2026-08-13 | Accepted | | +| ADR-CE-019 | ADR-CE-019: Memory as Nodes | [`coherence-engine/ADR-CE-019-memory-as-nodes.md`](./coherence-engine/ADR-CE-019-memory-as-nodes.md) | 2026-08-13 | Accepted | | +| ADR-CE-020 | ADR-CE-020: Confidence from Energy | [`coherence-engine/ADR-CE-020-confidence-from-energy.md`](./coherence-engine/ADR-CE-020-confidence-from-energy.md) | 2026-08-13 | Accepted | | +| ADR-CE-021 | ADR-CE-021: Shared SONA | [`coherence-engine/ADR-CE-021-shared-sona.md`](./coherence-engine/ADR-CE-021-shared-sona.md) | 2026-08-13 | Accepted | | +| ADR-CE-022 | ADR-CE-022: Failure Learning | [`coherence-engine/ADR-CE-022-failure-learning.md`](./coherence-engine/ADR-CE-022-failure-learning.md) | 2026-08-13 | Accepted | | +| ADR-DB-001 | ADR-DB-001: Delta Behavior Core Architecture | [`delta-behavior/ADR-DB-001-delta-behavior-core-architecture.md`](./delta-behavior/ADR-DB-001-delta-behavior-core-architecture.md) | 2026-08-13 | Proposed | | +| ADR-DB-002 | ADR-DB-002: Delta Encoding Format | [`delta-behavior/ADR-DB-002-delta-encoding-format.md`](./delta-behavior/ADR-DB-002-delta-encoding-format.md) | 2026-08-13 | Proposed | | +| ADR-DB-003 | ADR-DB-003: Delta Propagation Protocol | [`delta-behavior/ADR-DB-003-delta-propagation-protocol.md`](./delta-behavior/ADR-DB-003-delta-propagation-protocol.md) | 2026-08-13 | Proposed | | +| ADR-DB-004 | ADR-DB-004: Delta Conflict Resolution | [`delta-behavior/ADR-DB-004-delta-conflict-resolution.md`](./delta-behavior/ADR-DB-004-delta-conflict-resolution.md) | 2026-08-13 | Proposed | | +| ADR-DB-005 | ADR-DB-005: Delta Index Updates | [`delta-behavior/ADR-DB-005-delta-index-updates.md`](./delta-behavior/ADR-DB-005-delta-index-updates.md) | 2026-08-13 | Proposed | | +| ADR-DB-006 | ADR-DB-006: Delta Compression Strategy | [`delta-behavior/ADR-DB-006-delta-compression-strategy.md`](./delta-behavior/ADR-DB-006-delta-compression-strategy.md) | 2026-08-13 | Proposed | | +| ADR-DB-007 | ADR-DB-007: Delta Temporal Windows | [`delta-behavior/ADR-DB-007-delta-temporal-windows.md`](./delta-behavior/ADR-DB-007-delta-temporal-windows.md) | 2026-08-13 | Proposed | | +| ADR-DB-008 | ADR-DB-008: Delta WASM Integration | [`delta-behavior/ADR-DB-008-delta-wasm-integration.md`](./delta-behavior/ADR-DB-008-delta-wasm-integration.md) | 2026-08-13 | Proposed | | +| ADR-DB-009 | ADR-DB-009: Delta Observability | [`delta-behavior/ADR-DB-009-delta-observability.md`](./delta-behavior/ADR-DB-009-delta-observability.md) | 2026-08-13 | Proposed | | +| ADR-DB-010 | ADR-DB-010: Delta Security Model | [`delta-behavior/ADR-DB-010-delta-security-model.md`](./delta-behavior/ADR-DB-010-delta-security-model.md) | 2026-08-13 | Proposed | | +| ADR-QE-001 | ADR-QE-001: Quantum Engine Core Architecture | [`quantum-engine/ADR-QE-001-quantum-engine-core-architecture.md`](./quantum-engine/ADR-QE-001-quantum-engine-core-architecture.md) | 2026-08-13 | Proposed | | +| ADR-QE-002 | ADR-QE-002: Crate Structure & ruVector Integration | [`quantum-engine/ADR-QE-002-crate-structure-integration.md`](./quantum-engine/ADR-QE-002-crate-structure-integration.md) | 2026-08-13 | Proposed | | +| ADR-QE-003 | ADR-QE-003: WebAssembly Compilation Strategy | [`quantum-engine/ADR-QE-003-wasm-compilation-strategy.md`](./quantum-engine/ADR-QE-003-wasm-compilation-strategy.md) | 2026-08-13 | Proposed | | +| ADR-QE-004 | ADR-QE-004: Performance Optimization & Benchmarks | [`quantum-engine/ADR-QE-004-performance-optimization-benchmarks.md`](./quantum-engine/ADR-QE-004-performance-optimization-benchmarks.md) | 2026-08-13 | Proposed | | +| ADR-QE-005 | ADR-QE-005: Variational Quantum Eigensolver (VQE) Support | [`quantum-engine/ADR-QE-005-vqe-algorithm-support.md`](./quantum-engine/ADR-QE-005-vqe-algorithm-support.md) | 2026-08-13 | Proposed | | +| ADR-QE-006 | ADR-QE-006: Grover's Search Algorithm Implementation | [`quantum-engine/ADR-QE-006-grover-search-implementation.md`](./quantum-engine/ADR-QE-006-grover-search-implementation.md) | 2026-08-13 | Proposed | | +| ADR-QE-007 | ADR-QE-007: QAOA MaxCut Implementation | [`quantum-engine/ADR-QE-007-qaoa-maxcut-implementation.md`](./quantum-engine/ADR-QE-007-qaoa-maxcut-implementation.md) | 2026-08-13 | Proposed | | +| ADR-QE-008 | ADR-QE-008: Surface Code Error Correction Simulation | [`quantum-engine/ADR-QE-008-surface-code-error-correction.md`](./quantum-engine/ADR-QE-008-surface-code-error-correction.md) | 2026-08-13 | Proposed | | +| ADR-QE-009 | ADR-QE-009: Tensor Network Evaluation Mode | [`quantum-engine/ADR-QE-009-tensor-network-evaluation.md`](./quantum-engine/ADR-QE-009-tensor-network-evaluation.md) | 2026-08-13 | Proposed | | +| ADR-QE-010 | ADR-QE-010: Observability & Monitoring Integration | [`quantum-engine/ADR-QE-010-observability-monitoring.md`](./quantum-engine/ADR-QE-010-observability-monitoring.md) | 2026-08-13 | Proposed | | +| ADR-QE-011 | ADR-QE-011: Memory Gating & Power Management | [`quantum-engine/ADR-QE-011-memory-gating-power-management.md`](./quantum-engine/ADR-QE-011-memory-gating-power-management.md) | 2026-08-13 | Proposed | | +| ADR-QE-012 | ADR-QE-012: Min-Cut Coherence Integration | [`quantum-engine/ADR-QE-012-mincut-coherence-integration.md`](./quantum-engine/ADR-QE-012-mincut-coherence-integration.md) | 2026-08-13 | Proposed | | +| ADR-QE-013 | ADR-QE-013: Deutsch's Theorem — Proof, Historical Comparison, and Verification | [`quantum-engine/ADR-QE-013-deutsch-theorem-proof-verification.md`](./quantum-engine/ADR-QE-013-deutsch-theorem-proof-verification.md) | 2026-08-13 | Accepted | | +| ADR-QE-014 | ADR-QE-014: Exotic Quantum-Classical Hybrid Discoveries | [`quantum-engine/ADR-QE-014-exotic-discoveries.md`](./quantum-engine/ADR-QE-014-exotic-discoveries.md) | 2026-08-13 | Accepted | | +| ADR-QE-015 | ADR-QE-015: Quantum Hardware Integration & Scientific Instrument Layer | [`quantum-engine/ADR-QE-015-blockchain-forensics-scientific-instrument.md`](./quantum-engine/ADR-QE-015-blockchain-forensics-scientific-instrument.md) | 2026-08-13 | Accepted | | diff --git a/docs/research/perpetual-intelligence-runtime/01-evidence-review.md b/docs/research/perpetual-intelligence-runtime/01-evidence-review.md new file mode 100644 index 000000000..e64ca0b45 --- /dev/null +++ b/docs/research/perpetual-intelligence-runtime/01-evidence-review.md @@ -0,0 +1,84 @@ +# Evidence Review — RuV Perpetual Intelligence Runtime + +Status: draft for ADR seeding. Compiled 2026-08-19 by parallel web-verification research agents against the primary sources (arXiv abstracts, fetched directly). Every citation below was independently located and read; nothing is fabricated. Two of the eight claims in the original brief could not be substantiated and are marked UNVERIFIED — the program plan must not depend on those two as load-bearing evidence. + +## Summary table + +| # | Claim (brief's shorthand) | Found | Source | Grade | Numbers verified | +|---|---|---|---|---|---| +| 1 | SHAPER — frozen-weight embodied skill/harness evolution | Yes | arXiv:2608.11350 | A | qualitative claim confirmed | +| 2 | WorldCycle — reversible-action verification signals | Yes | arXiv:2608.04964 | A | 44% drift reduction, ~4x accuracy — exact match | +| 3 | LiveMem — fixed-capacity persistent memory state | Yes | arXiv:2608.02515 | A | qualitative claim confirmed | +| 4 | TARL — 5-op executable memory ledger | Yes | arXiv:2608.03699 | A | qualitative claim confirmed | +| 5 | Causal audit of latent multi-agent comms | Yes | arXiv:2607.26773 | A | date discrepancy (see below) | +| 6 | LATTE — anomaly quarantine for latent comms | **No** | — | **UNVERIFIED** | not found under this name | +| 7 | Cross-model KV-cache mapping (2.7–25x) | Yes | arXiv:2608.03893 | A | 2.7–25x and 2/6-pairs-degrade — exact match | +| 8 | Universal WiFi CSI "RF latent vocabulary" | **No** | — | **UNVERIFIED** | no matching paper found | + +Six of eight claims are grade A with primary sources directly confirming the mechanism and, where numeric, the exact figures. Two claims (LATTE, universal CSI vocabulary) are unverified after a genuine search effort and should be treated in the program plan as **internal design targets we would be first to build**, not as citations of prior work. + +--- + +## 1. SHAPER + +- **Found**: Yes — [arXiv:2608.11350](https://arxiv.org/abs/2608.11350), "Self-Evolving Embodied Agents via Skill-Harness Evolution," submitted 2026-08-11 (matches the brief's date exactly). +- **Grade**: A. +- **Claim vs. source**: Matches closely. The abstract confirms a train-free framework that keeps model parameters frozen while evolving reusable skills and a context/code harness through target-environment rollouts; the same frozen model serves as both planner and optimizer. Evaluated on VLABench and ESI-Bench (embodied agents with varied low-level action interfaces). +- **Notes**: No name collision found; "SHAPER" appears specific to this paper. + +## 2. WorldCycle + +- **Found**: Yes — [arXiv:2608.04964](https://arxiv.org/abs/2608.04964), "WorldCycle: Self-Verifiable Reinforcement Learning for Long-Horizon Video World Models," submitted 2026-08-05. +- **Grade**: A. +- **Claim vs. source**: Exact match on both numbers. Abstract states verbatim: "WorldCycle reduces state returning drift by up to 44% and lifts composite-action accuracy nearly 4x over the base model." A diagnostic benchmark, CycleBench, ships alongside it. Mechanism as claimed: verification signals derived from reversible/closed action cycles (an action sequence plus its inverse should return to the initial state) used for annotation-free supervision. +- **Notes**: No collision with unrelated prior work under this name. + +## 3. LiveMem + +- **Found**: Yes — [arXiv:2608.02515](https://arxiv.org/abs/2608.02515), "LiveMem: Maintaining Memory State Continuity in Long-Running LLM Inference," submitted 2026-08-03 (v1, matches exactly), revised 2026-08-07 (v2). +- **Grade**: A. +- **Claim vs. source**: Matches. Confirms a fixed-capacity memory state whose lifetime is independent of the active context, maintained via a parallel memory branch (Gated DeltaNet-2 backbone) alongside a bounded KV attention window — reframing long-running inference as "computational state preservation" rather than context growth. The system can answer questions from memory state after supporting evidence has left the context window. +- **Notes — name collision flagged**: "LiveMem" also names a pre-existing, unrelated consumer iOS app ("LiveMem – Live Photo Editor"). Different domain entirely, low confusion risk, but worth a footnote disambiguating "LiveMem (arXiv:2608.02515)" from the app. + +## 4. TARL + +- **Found**: Yes — [arXiv:2608.03699](https://arxiv.org/abs/2608.03699), "TARL: Transaction-Aware Reliable Ledgers for Executable Memory Management in Long-Term Agents," submitted 2026-08-04 (v1, matches exactly), revised 2026-08-11 (v2). +- **Grade**: A. +- **Claim vs. source**: Matches. Each incoming statement maps to one of five executable actions (add / ignore / revise-outdated-belief / reject-unreliable / defer-for-verification), maintaining accepted, pending, and rejected ledgers — explicitly framed as reducing "memory pollution" and limiting "cumulative corruption" (i.e., addressing memory poisoning). +- **Notes — name collision flagged, cite carefully**: "TARL" is heavily overloaded in prior ML/RL/robotics literature: "Taint Analysis and Reinforcement Learning" (robot software repair, arXiv:2005.03813), "Target-Aligned Reinforcement Learning" (arXiv:2603.29501), a separate "Test-time Adapted RL" concept, and an unrelated GitHub repo `xushoukai/TARL`. None relate to agent memory ledgers. **Always spell out "TARL (Transaction-Aware Reliable Ledgers)" on first use in any ADR or doc to avoid ambiguity.** + +## 5. Causal audit of latent multi-agent communication + +- **Found**: Yes — [arXiv:2607.26773](https://arxiv.org/abs/2607.26773), "Do Latent Channels Actually Communicate? A Causal Audit of Latent Multi-Agent LLM Communication." +- **Grade**: A. +- **Claim vs. source**: Content matches closely; **date discrepancy** — arXiv's own submission timestamp is **2026-07-29**, not Aug 5 as stated in the brief (no Aug 5 revision was found). Correct the date to late July 2026 in any citation. Substance confirmed: end-task performance gains alone don't establish that a receiver used task-relevant information passed through the latent (KV-cache) channel; the paper introduces a controlled-replacement causal audit, tested on Qwen3-4B/8B over GSM8K, ARC-C, and MATH-500. +- **Notes**: This paper is the evidentiary basis for invariant #3 in the brief ("every agent communication is attributable") — cite it as the motivating critique, dated correctly. + +## 6. LATTE — anomaly quarantine (UNVERIFIED) + +- **Found**: No. +- **Grade**: UNVERIFIED. +- **Search effort**: Extensive — direct phrase search, all major combinations. Found 8+ unrelated papers using "LATTE" as an acronym (latent diffusion transformer for video, atomic environment descriptors, hyperbolic Lorentz attention for EEG, robotics trajectory transformer, quantum error-correction decoding, federated test-time adaptation, bank-transaction embeddings, linear-time attention) — none relate to multi-agent latent-communication anomaly quarantine. +- **Closest genuine match on topic**: "When Latent Agents Lie: KV-Cache Integrity in Multi-Agent LLM Collaboration" ([arXiv:2606.28958](https://arxiv.org/abs/2606.28958)), fetched and confirmed to use an HMAC-SHA256 manifest-based integrity/tamper-detection scheme (774 honest payloads accepted, 295 tampered rejected) — related in spirit but a **different mechanism** (cryptographic verification, not statistical anomaly quarantine) and does **not** use the name "LATTE" anywhere. +- **Implication for the program**: Do not cite "LATTE" as prior art. Either (a) cite arXiv:2606.28958 for the integrity-checking half of the mechanism and design the statistical-anomaly-quarantine half as net-new work, or (b) treat anomaly quarantine for latent channels as an open research contribution the program can genuinely claim as novel, tied instead to LATTE's constitutional/witness-based verification concepts already present in `ruvnet/autogenous` and `ruvnet/rvm` (see 02-asset-map.md). + +## 7. Cross-model KV-cache mapping + +- **Found**: Yes — [arXiv:2608.03893](https://arxiv.org/abs/2608.03893), "Cross-Model KV Cache Transfer in LLM Families: A Closed-Form Linear Mapping for Prefill Reuse," submitted 2026-08-04 16:26 UTC (matches the brief's date exactly). +- **Grade**: A — the strongest-evidence item in this review. +- **Claim vs. source**: Exact match on every figure. Abstract states the mapper runs "2.7-25x faster than re-prefill" (matches). Tests six pairs across three model families; the linear mapper "retains 73-98% of the receiver's standalone-prefill accuracy on four pairs, while two degrade sharply" (matches "2 of 6 pairs degrade badly" exactly). A nonlinear MLP variant recovers up to +37pp HellaSwag accuracy on the failing pairs — directly supports the brief's implication that migration quality must be predicted/handled before blind use. +- **Notes**: This is the fast-follow item (brief's #4, KV migration in ruvLLM) — build directly against this paper's closed-form linear mapper plus the MLP fallback for degrading pairs, and implement the "predict transfer quality before migrating" routing gate the paper itself motivates. + +## 8. Universal WiFi CSI "RF latent vocabulary" (UNVERIFIED) + +- **Found**: No. +- **Grade**: UNVERIFIED (best adjacent work grades C — related but not matching). +- **Search effort**: Multiple phrasings tried (direct phrase, "chipset-agnostic," "shared vocabulary"/"common backbone," "tokenize" + CSI, explicit vendor-name combinations). No paper frames CSI from Realtek/Qualcomm/Nexmon/MediaTek chipsets specifically as a shared "RF latent vocabulary" feeding one common backbone. +- **Adjacent (not matching) work found**: "A Comprehensive Survey of Wireless Foundation Models for AI-Native 6G Networks" (arXiv:2608.14694, Aug 2026 — general survey of shared representations across heterogeneous wireless data, not chipset-vocabulary-specific); "WiFo-MiSAC" (arXiv:2604.18255, Apr 2026 — tokenizes heterogeneous signals via MoE backbone, but for multimodal sensing/comms, not cross-chipset CSI specifically); "UniFi" (arXiv:2512.22143 — irregular CSI sampling across packets/bands); "CSI-JEPA" (arXiv:2605.14171 — masked-prediction CSI foundation model). +- **Implication for the program**: This item (brief's #5, universal RF intelligence) is genuinely unclaimed territory — good news for novelty, bad news for evidence backing. Treat as an internal, first-party research bet with `ruvnet/RuView` as the implementation target, cite the four adjacent surveys/papers above as prior art to build on and differentiate from, and do not present it as validated by existing literature. + +## Bottom line for ADR-seeding + +- Build items **1 (SHAPER-style frozen-weight harness evolution)**, **2 (WorldCycle-style reversible-action verification)**, **3 (LiveMem-style persistent state)**, **4 (TARL-style transactional memory ledger)**, **5 (causal-audit-motivated attribution)**, and **7 (KV-cache cross-model migration)** all rest on grade-A, independently verifiable primary sources. These can be cited directly in ADRs. +- Item **6 (LATTE quarantine)** has no real citation — reframe the corresponding ADR as a novel contribution informed by arXiv:2606.28958's integrity-manifest approach plus `rvm`/`autogenous`'s existing witness-chain primitives, not as "implementing LATTE." +- Item **8 (universal CSI vocabulary)** has no real citation — reframe as a first-party research bet for `RuView`, citing the adjacent wireless-foundation-model literature as motivation, not as prior art being reproduced. diff --git a/docs/research/perpetual-intelligence-runtime/02-asset-map.md b/docs/research/perpetual-intelligence-runtime/02-asset-map.md new file mode 100644 index 000000000..0fdba7096 --- /dev/null +++ b/docs/research/perpetual-intelligence-runtime/02-asset-map.md @@ -0,0 +1,103 @@ +# Asset Map — Mechanism → ruvnet Component + +Status: draft for ADR seeding. Compiled 2026-08-19 from `gh` CLI searches of the `ruvnet` GitHub org and a local search of `/Users/cohen/GitHub/ruvnet/ruvector`. **Revised** after a second, deeper local-inventory pass (asset-scout) grounded this map in specific file paths, LOC counts, and ADR numbers, and surfaced several corrections to the first pass — those corrections are folded in below, with the original claim struck through where it was simply wrong, and flagged where the two passes disagree and a live check resolved it. + +**Resolved conflict**: asset-scout's pass reported `ruvnet/autogenous` as "unfindable anywhere." A direct `gh repo view ruvnet/autogenous` run during this revision confirms the repo is real, public, and was updated today (2026-08-19) — its own README badge self-labels it **"research prototype"** status. Treat the original mapping (§9 below) as correct, with that honest status caveat now attached. This is a reminder that org-wide `gh repo list`/search passes can miss repos depending on pagination and auth scope — prefer `gh repo view ` to confirm absence before marking something UNVERIFIED. + +## Headline finding — read this before anything else in this program + +**The cross-mechanism architecture this brief proposes has already been designed inside the ruvnet org, one day before this research request, under the codename "Cognitum."** `ruvnet/LatentMesh`'s [`docs/adr/009-online-causal-control-loop.md`](https://github.com/ruvnet/LatentMesh/blob/main/docs/adr/009-online-causal-control-loop.md) (dated **2026-08-18**, status "Proposed") lays out an online control loop — + +``` +execute → transfer latent state → counterfactual audit (ADR-003) → measure causal value + → update edge value/authority ceiling (ADR-008) → persist (ADR-005) → change topology (ADR-006, Darwin) + → next execution +``` + +— and explicitly assigns a role in that loop to **every component named in this brief**: RuFlo, MetaHarness/Darwin, RuVector, MidStream, Radio, RVF/RVM, RuView, and Autogenous. Its own honesty pass (§1) is directly relevant to invariant-setting for this program: it found that "latent agent communication," "dynamic topology," and "causal communication attribution" are now *also* claimed by prior art (StateBridge, LatentMAS, MANTA, and an "E2 Explainer" paper reported 2026-08-13 — four days before this ADR), and narrows its own novelty claim honestly rather than overselling it. That self-correcting discipline should be the model for how this program's own ADRs are written. + +**Implication for the program plan**: this is not a greenfield design exercise. The correct first work package is to **formally adopt or fork LatentMesh ADR-009's loop as the spine of the Perpetual Intelligence Runtime**, then fill in the parts ADR-009 itself flags as unimplemented (see below), rather than inventing a parallel architecture. Coordinate with whoever owns `ruvnet/LatentMesh` before any ADR in this program contradicts or duplicates its numbering. + +ADR-009 also states plainly what's built vs. not: *"The statistical primitive (ADR-003) and admission gate (ADR-008) are implemented; the closed loop across live components is not wired."* That is the actual gap this program should close. + +--- + +## Mechanism-by-mechanism map + +### 1. MetaHarness — **confirmed external, with a compliance bug** +- **Where**: The MetaHarness *engine* is genuinely external — **nine `@metaharness/*` npm packages pinned as dependencies inside `crates/ruvector-sota-bench/harness`**, plus a bridge at `npm/packages/ruvector/src/metaharness` and 6 MCP tools exposing it. In-repo documentation: `docs/adr/ADR-256-metaharness-sdk-evaluation.md`, `ADR-260/266/271-*darwin*metaharness*`, `docs/metaharness-implementation-plan.md`, `METAHARNESS-README.md`. +- **Status**: ADR-256 concludes MetaHarness's useful ideas (cost-optimal routing, agentic tool surface, signed releases, memory/learning loop) are *already* natively covered by `npx ruvector`'s existing primitives (Tiny Dancer cost router, semantic router, MCP server, witness chain, SONA) — decision was to borrow concepts, not take a hard runtime dependency. +- **Bug to remediate**: `METAHARNESS-README.md` claims ADR-150 `optionalDependencies` compliance, but the nine `@metaharness/*` packages in `crates/ruvector-sota-bench/harness` are **plain dependencies**, not optional — meaning the harness currently hard-fails to install without them, contradicting its own documented policy. This needs a dedicated remediation work package (see WP0b below), not just a documentation fix, since it affects install-time reliability for anyone consuming `ruvector-sota-bench`. +- **Gap**: No standing orchestration *service* for the evolution loop, benchmark scoring, and SOTA validation beyond what the external `@metaharness/*` packages already provide — ADR-265/266/267 plan a more integrated version (32 mutation surfaces, genetic algorithm, Ed25519 witness signing, 3-tier validation) but it isn't shipped as a standalone in-repo crate. + +### 2. Darwin (mutation/evolution engine) — **confirmed as `@metaharness/darwin`, three real call sites** +- **Where**: Darwin is the `@metaharness/darwin` package (part of the MetaHarness external dependency set above), called from three concrete, real sites in this repo: `harness/src/darwin.ts` (ANN config evolution), `examples/mragent`'s `scorePolicy` function, and `crates/sona/src/darwin_guard.rs` (ADR-271). Also `crates/sona/examples/darwin_autotuner.rs`, `darwin_ewc.rs`. Documented in `docs/adr/ADR-259/260/266/269/271`. +- **Status**: Real evolutionary loop — profile → baseline → mutate (7 approved surfaces via `CodeGenerator`, e.g. `OpenRouterMutator`, `RuvllmMutator`) → sandbox → 6-term score → archive-as-tree → repeat. `ruvllm` is a real, wired local mutator backend (ADR-259), with a known, specifically-identified live-serve blocker: **an HTTP-307 redirect bug in the ruvllm model-download path** that blocks end-to-end live-serve testing of the mutator. +- **Gap**: Realizing Darwin as a fully first-class in-repo asset (vs. an external npm dependency called from three sites) means either formalizing the dependency properly (fixing the ADR-150 optional-dependency compliance bug above) or vendoring the loop, bound to `ruvector-proof-gate`/`ruvector-verified` and ADR-265's benchmark suite. Fixing the HTTP-307 bug is the concrete near-term unblock for live e2e testing. + +### 3. RuView (RF/WiFi spatial sensing) — **corrected: local checkout exists, two in-repo consumers, ADR-178 is CLOSED** +- **Where**: **Separate active repo, locally checked out at `/Users/cohen/GitHub/ruvnet/RuView`** — WiFi CSI DensePose, ESP32 firmware, Rust port, publishes the `wifi-densepose-ruvector` package; turns commodity WiFi into real-time spatial intelligence, vital-sign monitoring, presence detection; Home Assistant/HomeKit/Google Home/Alexa integration; 21 entities per node (11 raw + 10 inferred semantic states, e.g. "possible-distress," "fall-risk-elevated"). **Two** in-repo (`ruvector`) consumers, not one: `crates/ruvector-hailo-cluster/src/bin/ruview-csi-bridge.rs` (the transport bridge) **and** `crates/ruvector-perception` (3.8K LOC spatial-perception model — **synthetic-only, not yet validated against real CSI data**). Parallel modality: `crates/ruvector-mmwave` (Seeed MR60BHA2/LD2410 radar, ADR-063). +- **Status**: `ruview-csi-bridge` is explicitly **transport-only** — parses RuView's ADR-018 UDP CSI frames and posts a header-summary string into the Hailo embed RPC; the source comment explicitly disclaims doing pose embedding. `ruvector-perception` is a real, substantial (3.8K LOC) perception model, but it has only ever been trained/tested on synthetic data, never real CSI captures. **`docs/adr/ADR-178` (the ruvector↔RuView gap analysis) is CLOSED**, not open — its two still-open long-form gaps are explicitly tracked for future ADRs: **gap C** (CSI bridge I/Q → pose-semantics conversion) and **gap D** (an mcp-brain-server-side cluster consumer for RuView data). +- **Gap**: Gaps C and D from the now-closed ADR-178 are the concrete, already-scoped-by-the-org unblockers for real pose-semantic embedding — a pose-specific HEF (Hailo Model Zoo currently lacks one for the target chips), a generalized `HailoPipeline`, host-side I/Q preprocessing, and validating `ruvector-perception` against real (not synthetic) CSI. This is the component with the largest gap between "named in the brief" and "exists validated today," and is exactly where both the pose-embedding fast-follow and the universal-CSI-vocabulary bet (evidence item #8, UNVERIFIED) should land — **pick up ADR-178's gaps C and D directly rather than re-scoping from zero.** + +### 4. Dream Machine (evaluation/simulation before promotion) — **corrected: real statistical promotion machinery already exists under a different name** +- **Where**: No asset is literally named "Dream Machine." The first pass of this map pointed at SONA's dream-replay engine as the closest analogue — a deeper inventory pass found the actual functional equivalent instead: **`scripts/research-gate/`** plus **`.github/workflows/research-*.yml`** (the CI-level gate), documented in **`docs/adr/ADR-282`**, backed by real statistical promotion machinery in **`crates/ruvector-sota-bench/harness`**: `statistics.ts` (paired bootstrap significance testing), `vetoes.ts` (hard-veto conditions that block promotion regardless of the statistical result), and `flywheel.ts` (Ed25519-signed replay bundles for reproducible re-verification). +- **Status**: This is materially better news than the first pass indicated — a real, CI-wired, cryptographically-signed statistical-promotion gate already exists (paired bootstrap + vetoes + signed replay bundles), it's just not named "Dream Machine" and it isn't yet connected to Darwin's mutation loop or SONA's dream-replay engine. +- **Gap**: The program should **build on and formally adopt `research-gate` + `ruvector-sota-bench/harness` as the Dream Machine equivalent** (renaming/reframing rather than inventing a parallel system), and wire it as the evaluation stage between Darwin's mutation proposals and RVM's proof-gated promotion. SONA's dream-replay engine (`05-MEMORY-DREAMS.md`) remains a candidate *pre-filter* to feed into this gate, not a replacement for it. This significantly de-risks the program plan's biggest previously-identified gap — see the revised risk assessment in `03-program-plan.md`. + +### 5. RuVector (vector memory / HNSW substrate) +- **Where**: `crates/ruvector-core` plus the full `ruvector-*` family (140+ crates — diskann, rabitq, mincut, graph, attention, etc.), `npm/packages/ruvector`. +- **Status**: Mature, in production. No gap — this is the most fully realized mechanism in the brief and should be treated as the stable foundation everything else is built on, not as work to be scoped. + +### 6. RVF (cognitive containers / session recording format) +- **Where**: `crates/rvf` nested workspace (`rvf-types`, `rvf-wire`, `rvf-manifest`, `rvf-index`, `rvf-quant`, `rvf-crypto`, `rvf-runtime`, `rvf-kernel`, `rvf-wasm`, `rvf-node`, `rvf-server`, `rvf-adapters/{claude-flow,agentdb,ospipe,agentic-flow}`), `npm/packages/rvf` (`@ruvector/rvf`), `crates/ruvector-cognitive-container` ("Verifiable WASM cognitive container with canonical witness chains"). Canonical spec: `docs/adr/ADR-029-rvf-canonical-format.md`. +- **Status**: Confirmed mature per both research passes. ADR-029 makes RVF the intended single canonical binary format across all RuVector libraries (replacing fragmented REDB/bincode/JSON formats in ruvector-core, agentdb, claude-flow, agentic-flow, ospipe, rvlite, sona) — append-only crash-safe segments, progressive indexing, temperature-tiered quantization, WASM microkernel, post-quantum ML-DSA-65 signatures. +- **Gap**: Cross-library adapter adoption (agentic-flow, ospipe) is only partially built per ADR-029's own scope. + +### 6b. Memory (opportunity #2 host components — added detail from second-pass inventory) +- **Where**: `crates/ruvector-agent-memory` (ADR-252), `ruvllm`'s `context/` modules (`working_memory`, `episodic_memory`, `semantic_cache`, `agentic_memory`), `reasoning_bank` (trajectory tracking / verdict judgment / distillation / consolidation), `crates/ruvector-temporal-coherence` (ADR-211). **`agentdb` itself is an external product — only an RVF adapter crate (`rvf-adapters/agentdb`) lives in-repo.** +- **Status — important correction**: the three-level memory architecture proposed in the program plan (working context → continuous latent state → transactional RuVector memory) already has concrete homes: working context maps to `ruvllm`'s `working_memory` module, continuous latent state maps to `episodic_memory`/`semantic_cache`/`agentic_memory`, and transactional RuVector memory maps to `ruvector-agent-memory` + `reasoning_bank` + `ruvector-temporal-coherence`. **Proof-gated writes for this memory already exist** — `docs/adr/ADR-194` and `ADR-047` — meaning the "sign every memory transition via RVM witness records" requirement in the original program plan is largely already built, not net-new. This meaningfully reduces the scope of program-plan work package WP3/WP4 (see `03-program-plan.md`). + +### 7. RVM (signatures / governance / witness-chain / provenance) +- **Where**: **Separate repo `ruvnet/rvm`** ("coherence-native microhypervisor for edge computing and multi-agent systems"), vendored inside `ruvector` at `crates/rvm/` with sub-crates `rvm-witness`, `rvm-proof`, `rvm-cap`, `rvm-security`, `rvm-checkpoint`, `rvm-coherence`, `rvm-kernel`, `rvm-boot`, `rvm-hal`, `rvm-partition`, `rvm-sched`, `rvm-memory`, `rvm-types`, `rvm-wasm`. Key ADRs: `ADR-134-witness-schema-log-format.md`, `ADR-285-hosted-rvm-security-boundary.md`, `ADR-293-rvm-installer-appliance-formats.md`. +- **Status**: Every privileged action emits a mandatory 64-byte cache-line-aligned witness record, hash-chained (FNV-1a, optionally Ed25519/TEE-signed) for tamper evidence and deterministic replay (ADR-134). `rvm-proof` implements proof-gated state transitions (ADR-135) using `rvm-witness` + `rvm-cap` capability tables. ADR-285 explicitly forbids hosted (desktop-process) RVM from claiming bare-metal isolation strength — a governance-honesty discipline worth carrying into this program's own claims. +- **Correction to the brief**: the brief's description of "ADR-103" ("cryptographically-signed fix manifest with temporal history") does **not** match `ruvector`'s actual ADR-103 (DeepAgents review amendments, unrelated). That description matches the `ruflo-core:witness` MCP tool instead, which is claude-flow/Ruflo-side tooling with its own ADR-103 in a different repo. **Verify which repo's ADR-103 is meant before citing it in any new ADR.** +- **Gap**: RVM's hypervisor/witness core is substantially built. Net-new is wiring RVM's witness chain as the authoritative provenance layer for *program-level* governance decisions (mutation promotion, memory-ledger transitions) rather than just VM/partition-level privileged actions. + +### 8. LatentMesh (P2P latent/neural communication transport) — **corrected: greenfield inside `ruvector`, design-stage externally** +- **Where — two distinct facts, not one**: (a) The **external repo `ruvnet/LatentMesh`** is real and design-stage (last updated 2026-08-19) — "training-free orthogonal alignment of hidden states as a network primitive," with crates `latentmesh-core` (wire vocabulary, `LatentFrame`, F32/F16/Int8 encoding), `latentmesh-align` (training-free orthogonal Procrustes/SVD alignment), `latentmesh-gate` (capability-governed latent execution + causal-edge verification), `latentmesh-bench`, and ADRs 001–009 (architecture/prior-art through the online causal control loop, see headline finding above). (b) **Inside the local `ruvector` repo, there is no wiring to it at all** — the only trace is an unmerged branch, `origin/docs/link-latentmesh`. It is not cloned locally and not integrated with RuVector today. +- **Status**: Externally, core packet codecs and alignment math are implemented and tested per the LatentMesh repo's own ADRs; network transport, RVF packaging, and RVM enforcement wiring are explicitly marked "not implemented" there too, and ADR-003's causal-edge verification machinery has never been run against a live multi-agent task (per LatentMesh ADR-009). Internally to `ruvector`, this is a from-scratch build, not an integration. +- **Gap / recommendation**: Plan the `ruvector`-side work as **new crates**, not as "wiring an existing integration" — asset-scout's suggestion is to house them under `crates/rvAgent/` (near the existing `rvagent-a2a`, ADR-159) or as a new `latentmesh` crate family, and treat cross-repo alignment with the actual `ruvnet/LatentMesh` design as an explicit coordination task (WP1/WP5 in the program plan), not an assumption. + +### 9. Autogenous (autonomous agent communication/governance layer) — **existence confirmed live, status is self-declared "research prototype"** +- **Where**: **Separate active repo `ruvnet/autogenous`** (updated 2026-08-19) — "Governed Evolutionary Software... turns runtime failures into verified, portable, reversible software adaptations." Crates: `witness` (independently reconstructible/verifiable crypto plane, echoing RVM's design), `antibody` (Autogenous Antibody Package, unit of defense), `agl-types` (Autogenous Genome Language — typed mutations), `generator`, `evaluator`, `verifier` (admission gate), `lineage` (provenance), `ledger` (durable recovery), `promotion` (rollout controller), `deployment`, `constitution` (governance plane), `runtime`, `midstream-adapter`, `service` (Cloud Run HTTP control plane). ADRs 391/392/393/397. +- **Verification note**: a second-pass inventory reported this repo as "unfindable anywhere." A direct `gh repo view ruvnet/autogenous` re-check during this revision confirms it exists, is public, and its own README carries a **"research prototype"** status badge — meaning it's real but the org's own maintainers don't consider it production-grade yet. Nearest `ruvector`-local analogues (useful for comparison, not substitutes) are `crates/rvAgent/rvagent-subagents` (ADR-097/275) and `rvagent-a2a` (ADR-159). +- **Status**: The most governance-complete of the twelve mechanisms on paper — observe → explain → mutate → prove → canary → promote/rollback, with typed mutation genome, signed antibody packages, constitutional gating — but self-labeled research-prototype maturity, so treat its APIs as unstable. +- **Gap**: Cross-repo wiring with RuVector/ruvLLM/RVM isn't evidenced yet. **Duplication note**: `rvm` and `autogenous` both independently define a `witness` crate with near-identical framing — a real convergence point worth resolving in this program rather than maintaining two implementations. + +### 10. ruvLLM (LLM gateway / cross-model routing) +- **Where**: `crates/ruvllm`, `ruvllm-cli`, `ruvllm-wasm`, `ruvllm_sparse_attention`, `ruvllm_retrieval_diffusion`; `npm/packages/ruvllm` (+ platform variants); `docs/ruvllm/`; ADRs 002, 074, 084, 165, 173, 179–181, 258–259. +- **Status**: "LLM serving runtime with Ruvector integration — paged attention, KV cache, SONA learning," built on `ruvector-core`/`ruvector-sona`. ADR-180 covers continuous-batching serving; ADR-181 BitNet quantization; ADR-173/179 Hailo/Pi edge deployment. Already Darwin Mode's local mutator backend (ADR-259). +- **Gap**: Cross-*provider* routing (Anthropic/OpenAI/local, not just local-inference serving) isn't centered here — that role sits closer to claude-flow's ADR-026 3-tier routing. Fast-follow item #4 (KV-cache cross-model migration, evidence-graded A above) is the concrete net-new work: implement arXiv:2608.03893's closed-form linear mapper plus MLP fallback for degrading pairs, as a `ruvllm` capability. + +### 11. Ruflo / claude-flow (orchestration CLI/MCP) +- **Where**: `@claude-flow/cli`, deeply integrated per repo-root `CLAUDE.md` — swarm/hive-mind/hooks/memory subsystems, 26 CLI commands, 27 hooks, 12 background workers, exposed in-session as `ruflo-*` MCP tool namespaces. `rvf-adapters/claude-flow` is already scaffolded per ADR-029. +- **Status**: The most operationally mature asset in the list — swarm orchestration, agentdb-backed memory, hive-mind consensus, ADR management, security auditing, cost tracking. This is the coordination layer the whole program plan sits on top of. +- **Gap**: None to establish existence. Relevant integration gap: the RVF adapter for claude-flow is scaffolded but not confirmed fully adopted end-to-end (ADR-029). + +### 12. agentdb (memory/vector database layer) +- **Where**: `crates/rvf/rvf-adapters/agentdb`, `crates/ruvector-temporal-tensor/src/agentdb.rs`, runtime state at `.swarm/agentdb-memory.db*`, `agentdb.rvf`/`.lock` at repo root and in `npm/packages/ruvllm/`, extensive `agentdb-*`/`ruflo-agentdb` MCP tool namespaces. +- **Status**: "AI agent memory with HNSW indexing" (ADR-029), invoked via `npx agentdb`, underpins claude-flow's memory subsystem. +- **Gap**: Full migration onto RVF as canonical format (ADR-029) — adapter crate exists, full fragmentation-to-unification not confirmed complete. + +--- + +## Cross-cutting notes for the program plan + +1. **LatentMesh, Autogenous, and RuView are sibling `ruvnet` repos, not subdirectories of `ruvector`.** RuView has a local checkout (`/Users/cohen/GitHub/ruvnet/RuView`) and two real in-repo consumers; LatentMesh and Autogenous have no local wiring at all — the program plan's work packages must span repos, and the `ruvector`-side LatentMesh/Autogenous work should be planned as new construction, not integration. +2. **LatentMesh ADR-009 already names the exact cross-mechanism loop this program wants to build**, including an explicit role for every component in the brief. Treat it as the architecture to extend, and open a coordination thread with the LatentMesh maintainers before this program's ADRs assign conflicting numbers or contradict its design. +3. **RVM and Autogenous both independently built a `witness` crate** with near-identical framing (cryptographic, independently-reconstructible provenance chain). This is a real duplication the program should resolve — likely by having Autogenous's `witness` crate depend on or converge with `rvm-witness` rather than maintaining two implementations, given RVM's is the more hypervisor-integrated of the two, and given Autogenous is self-labeled "research prototype." +4. **ADR-103 numbering is ambiguous across repos** — the brief's description matches claude-flow/Ruflo's ADR-103 (via the `ruflo-core:witness` tool), not `ruvector`'s own ADR-103. Any new ADR that cites "ADR-103" for witness/fix-manifest behavior must specify which repo. This is one instance of a broader problem — see point 6. +5. **Biggest real gaps, ranked by how much they block the acceptance test**: (a) RuView pose-semantic embedding validated against real (not synthetic) CSI — `ruvector-perception` is 3.8K LOC but synthetic-only; ADR-178 gaps C and D are the scoped path forward; (b) LatentMesh's actual construction inside `ruvector` — currently zero wiring, an unmerged branch stub only; (c) universal CSI vocabulary — no prior art exists anywhere, ruvnet or otherwise, so this is a first-party bet, not an integration task. **Dream Machine is no longer the top gap** — `scripts/research-gate/` + `crates/ruvector-sota-bench/harness` (paired-bootstrap statistics, hard vetoes, Ed25519-signed replay bundles) already provides real, CI-wired promotion machinery; the work is adopting/renaming/wiring it to Darwin, not building it from nothing. +6. **ADR numbering hygiene is a real, quantified problem.** `docs/adr/` contains **283 ADR files** with a **true maximum of ADR-304** (not ADR-118, which is stale — likely from an older CLAUDE.md snapshot). Numbers are **not unique**: ADR-272 appears **5 times**, ADR-264/252/194/144/040 each appear **3 times**, and roughly a dozen more numbers (268, 266, 260, 258, 256, 254, 143, 139, 138, 137, 136, 135, 134, 133, …) appear **twice**. Any new ADR from this program must claim a number **above 304**, and the collision problem itself should be a tracked hygiene work package (see program plan) rather than something new ADRs quietly work around. +7. **GCP surface is concrete, not hypothetical**: `crates/mcp-brain-server` deploys to Cloud Run as `ruvbrain`, in project **`ruv-dev`**, region **us-central1**, with real `cloudbuild` files and deploy scripts already checked in; the npm client is `@ruvector/pi-brain`. New Cloud Run services proposed in the program plan should follow this exact pattern and, where reasonable, live in the same `ruv-dev` project for shared secrets/networking rather than provisioning a new project. diff --git a/docs/research/perpetual-intelligence-runtime/03-program-plan.md b/docs/research/perpetual-intelligence-runtime/03-program-plan.md new file mode 100644 index 000000000..46ca19a20 --- /dev/null +++ b/docs/research/perpetual-intelligence-runtime/03-program-plan.md @@ -0,0 +1,297 @@ +# Program Plan — RuV Perpetual Intelligence Runtime + +Status: draft for ADR seeding, swarm work-package assignment, and GitHub issue filing. Compiled 2026-08-19, revised same day after a second, deeper asset-inventory pass (asset-scout) grounded several sections in verified file paths, LOC counts, and ADR numbers — see `02-asset-map.md`'s corrections. Depends on `01-evidence-review.md` (evidence grades) and `02-asset-map.md` (component map). Read the asset map's headline finding first: this program extends `ruvnet/LatentMesh` ADR-009's "online causal control loop" (2026-08-18) rather than designing from scratch. + +**Revision note**: the second inventory pass materially changed two things worth knowing before reading the rest of this plan. First, "Dream Machine" is *not* a from-scratch build — real, CI-wired, cryptographically-signed statistical promotion machinery already exists (`scripts/research-gate/`, `crates/ruvector-sota-bench/harness`, ADR-282) and should be adopted/renamed, not reinvented; this meaningfully de-risks what was previously flagged as the top program risk. Second, ADR numbering in this repo is not the "ADR-001 through ADR-118" stated in the root `CLAUDE.md` — the true count is 283 files with duplicated numbers up to ADR-304 (see asset map §6 of the cross-cutting notes) — every new ADR in this program must be numbered above 304. + +## Governing invariants + +Invariants 1–6 are carried from the brief, unchanged. Invariant 7 was added +during ADR authoring (PR #847, ADR-305), adopted from ruflo ADR-322B's +proposer/promotion separation-of-powers rule — see ADR-305 for the source +citation. + +1. Every observation may change memory. +2. Every memory change is transactional. +3. Every agent communication is attributable. +4. Every behavioral mutation is tested. +5. Every promoted mutation must outperform its parent. +6. Every physical action produces new evidence. +7. A proposer produces untrusted candidates only; it cannot issue promotion + decisions or mutate active policy (adopted from ruflo ADR-322B, binding + on ADR-306, ADR-313, ADR-315). + +Risk control: Darwin proposes, RVM gates what can change, Dream Machine requires statistically credible improvement before promotion. + +## Scope decision + +Build **1 + 2 + 3** (self-evolving physical intelligence, persistent transactional memory, verified latent communication) as the combined "Perpetual Intelligence Runtime" branch. Fast-follow with **4** (KV-cache cross-model migration in ruvLLM — grade-A evidence, cheapest to ship). Treat **5** (universal RF/CSI vocabulary) as a stretch research bet inside `RuView` with no external prior art to lean on (see evidence review item 8) — sequence it last and fund it separately if 1–4 land on schedule. + +--- + +## Bounded contexts (DDD) + +| Context | Owns | Primary repo(s) | +|---|---|---| +| **Physical Skill Evolution** | Skill/harness genome, mutation surfaces, rollout execution | `agent-harness-generator` (Darwin core), `ruvector` (`crates/sona`, `crates/ruvllm` mutator backend) | +| **World Verification** | Reversible-action verification, dream-replay pre-filter, promotion scoring | `ruvector` (`crates/ruvector-nervous-system`, SONA dream engine, `ruvector-proof-gate`) | +| **Persistent Memory Governance** | Three-level memory (working context → continuous latent state → transactional RuVector memory), TARL-style ledger, RVF/RVM provenance | `ruvector` (`crates/rvf`, `crates/rvm`, `ruvector-core`), `agentdb` | +| **Latent Communication Fabric** | Latent transport, causal-edge verification, quarantine, capability-governed execution | `ruvnet/LatentMesh` (primary), `ruvnet/rvm` (`rvm-witness`, `rvm-cap`) | +| **Cross-Model Cognition Migration** *(fast-follow)* | KV-cache mapping, transfer-quality prediction, routing gate | `ruvector` (`crates/ruvllm`) | +| **RF Sensing Substrate** *(stretch)* | Hardware-independent CSI representation, pose-semantic embedding | `ruvnet/RuView`, `ruvector` (`crates/ruvector-hailo-cluster`) | +| **Governance & Constitution** *(cross-cutting)* | Admission gates, capability ceilings, rollback, cross-repo witness convergence | `ruvnet/autogenous`, `ruvnet/rvm` | + +--- + +## ADR list + +Numbers are placeholders — assign real numbers **above ADR-304** via `ruflo-adr:adr-create` at kickoff (the repo's true max, not the stale "ADR-118" in root `CLAUDE.md` — see asset map §6), and confirm against both `ruvector`'s and `LatentMesh`'s ADR sequences before merging (see asset map note on ADR-103 ambiguity). ADR-create should also register each new ADR in `ruflo-adr:adr-index` immediately to avoid adding to the duplicate-number problem it's meant to fix. + +**This list has eleven ADRs (1–11 below); the two work packages below numbered +WP0a and WP0b are process/bug-fix work with no corresponding ADR** — they +were mistakenly written as "ADR — …" entries in an earlier draft of this +plan, which claimed thirteen ADRs against the eleven PR #847 actually +shipped (ADR-305 through ADR-315). Reworded here as work-package-only items +so this plan and the shipped ADR set agree: + +- **WP0a — ADR numbering hygiene remediation** (no ADR). Audit + fix pass + over `docs/adr/` to resolve the ~15+ duplicate ADR numbers found (ADR-272 + ×5, ADR-264/252/194/144/040 ×3 each, ~12 more ×2), by renumbering the + later-created duplicate in each collision to the next free number above + 304 and updating all in-repo references to match. Process hygiene, + tracked as a separate issue, not a PIR ADR. + +1. **ADR — Adopt LatentMesh ADR-009 as the Perpetual Intelligence Runtime's control-loop spine.** Decision: rather than defining a new cross-mechanism architecture, this program formally adopts the `execute → transfer → causal audit → measure → update authority → persist → evolve topology` loop from LatentMesh ADR-009, and commits to closing the specific gap that ADR names ("statistical primitive and admission gate implemented; closed loop across live components not wired"). Coordination channel opened with LatentMesh maintainers before any conflicting ADR numbers are assigned. + +2. **ADR — Adopt `research-gate`/`ruvector-sota-bench` as the Dream Machine equivalent, and wire it to Darwin.** Decision: rather than building a new evaluation service, formally adopt the existing `scripts/research-gate/` + `.github/workflows/research-*.yml` + `crates/ruvector-sota-bench/harness` (paired-bootstrap `statistics.ts`, hard-veto `vetoes.ts`, Ed25519-signed `flywheel.ts` replay bundles), documented in ADR-282, as the Dream Machine role in this program. The concrete work is wiring it as the mandatory evaluation stage between Darwin's mutation proposals and RVM's proof-gated promotion — optionally with SONA's dream-replay engine (`05-MEMORY-DREAMS.md`) as a pre-filter feeding candidates into it — not writing a parallel system. This significantly reduces the risk previously flagged as the program's biggest gap. + +3. **ADR — Three-level persistent memory architecture (LiveMem + TARL pattern) on RuVector's existing memory stack.** Decision: implement working-context / continuous-latent-state / transactional-RuVector-memory as three explicit tiers mapped onto components that mostly already exist: working context → `ruvllm`'s `working_memory` module; continuous latent state → `episodic_memory`/`semantic_cache`/`agentic_memory` (following LiveMem's fixed-capacity recurrent-state design, arXiv:2608.02515); transactional memory → `ruvector-agent-memory` (ADR-252) + `reasoning_bank` + `ruvector-temporal-coherence` (ADR-211), extended with TARL's five-operation ledger (add/ignore/revise/reject/defer, arXiv:2608.03699). Proof-gated writes for this tier **already exist** (ADR-194, ADR-047) — the net-new work is the TARL-style ledger states and operation semantics layered on top of the existing proof-gate, not the gate itself. + +4. **ADR — WorldCycle-style verification for the physical action loop.** Decision: adopt reversible-action-sequence verification (arXiv:2608.04964) as the WorldCycle-verification stage between "observe consequences" and "Dream Machine evaluation" in the physical loop, targeting the paper's reported 44% long-horizon drift reduction and ~4x composite-action accuracy as the acceptance bar for Phase 3's world-model component. + +5. **ADR — Build LatentMesh integration inside `ruvector` as new crates, coordinated with the external design.** Decision: since `ruvector` has zero existing wiring to `ruvnet/LatentMesh` today (only an unmerged `origin/docs/link-latentmesh` branch stub), build the `ruvector`-side integration as new crates under `crates/rvAgent/` (alongside the existing `rvagent-a2a`, ADR-159) or a new `latentmesh` crate family — not as "finishing an integration" that doesn't yet exist. Implement the network transport, RVF packaging (model identity, transform, permitted recipients, provenance, witness history as artifact metadata per LatentMesh ADR-008), and RVM `rvm-cap` admission enforcement that LatentMesh's own ADRs mark as "not implemented" externally too. This requires an explicit coordination channel with the `ruvnet/LatentMesh` maintainers so the two sides converge on the same wire format rather than diverging. + +6. **ADR — Causal-attribution gate for latent communication.** Decision: every latent-channel deployment must pass a controlled-replacement causal audit modeled on arXiv:2607.26773 before its performance claims can be used to justify further rollout — this becomes a required CI gate on any change touching `latentmesh-align` or downstream consumers, not just a one-time paper reproduction. + +7. **ADR — Anomaly quarantine for latent channels (net-new, not "LATTE").** Decision: since no verified prior art named "LATTE" exists (evidence review item 6, UNVERIFIED), build quarantine as a first-party contribution combining arXiv:2606.28958's HMAC-manifest integrity check with `rvm-witness`/`autogenous witness` provenance chains — explicitly documented as original work, not an implementation of a paper that doesn't exist under that name. + +8. **ADR — Resolve the RVM/Autogenous witness-crate duplication.** Decision: `rvm-witness` becomes the canonical witness-chain implementation; `autogenous`'s `witness` crate is refactored to depend on it rather than maintaining a parallel cryptographic-provenance implementation. Both repos' maintainers must sign off before this lands. + +9. **ADR — SHAPER-pattern skill/harness evolution loop (frozen weights).** Decision: implement the physical-intelligence evolution loop with foundation-model weights frozen throughout, following arXiv:2608.11350's pattern — the same frozen model serves as planner and optimizer, evolving only skills, context, and the execution harness (mapped to Darwin's mutation surfaces), never the weights themselves. This is the acceptance test's central frozen-weights constraint and must be enforced structurally (no fine-tuning code path reachable from the promotion pipeline), not just by policy. + +10. **ADR — KV-cache cross-model migration in ruvLLM (fast-follow).** Decision: implement arXiv:2608.03893's closed-form linear KV-cache mapper for same-family model migration, with the nonlinear MLP fallback for the pairs it identifies as degrading, plus a routing gate that predicts transfer quality before migrating (never migrate blind). Ships independently of the Phase 1–3 branch since it depends only on `ruvllm`. + +11. **ADR — Governance constitution for capability expansion.** Decision: adopt `autogenous`'s constitution/admission-gate pattern as the enforcement point for "zero unapproved capability expansion" (acceptance-test requirement); every mutation that would expand an agent's capability set (new tool access, new physical action class, new communication peer) requires explicit constitutional approval logged to the witness chain, distinct from ordinary behavioral mutation promotion. Note `autogenous`'s own README self-labels it "research prototype" status — treat its APIs as unstable and budget time for API churn, don't assume production-grade stability. + +- **WP0b — MetaHarness dependency-compliance remediation** (no ADR). Fix the + confirmed bug where `crates/ruvector-sota-bench/harness`'s nine + `@metaharness/*` npm dependencies are declared as plain (hard) + dependencies while `METAHARNESS-README.md` claims `optionalDependencies` + compliance, attributed there to "**ADR-150**: MetaHarness Integration + Surfaces (**upstream**)." Neither `ruvector`'s own ADR-150 + (`pi-brain-ruvltra-tailscale`) nor `metaharness`'s own ADR-150 + (`tailscale-local-frontier-concurrent-benchmarks`) is the right document + — both unrelated. **The upstream document is `ruflo` ADR-150** + (`v3/docs/adr/ADR-150-metaharness-integration-surfaces.md`, "MetaHarness + Integration Surfaces in `npx ruflo`," Status **Implemented**, 2026-06-16), + whose rule 2 is verbatim the policy: *"`@metaharness/*` packages MUST + appear in `optionalDependencies` or `peerDependencies` (optional), never + in `dependencies`."* Fix the bug directly against that source — make the + nine packages genuinely optional per ruflo ADR-150 rule 2, or correct the + documentation to state the real (hard-dependency) install requirement — + and adopt rule 4 (a CI job on the `--ignore-optional` install path, + "the only structural defense against accidentally promoting an optional + dep to required") as the acceptance criterion, stronger than a plain + successful `npm install`. **The previously-tracked HTTP-307 redirect bug in + `ruvllm`'s model-download path is already fixed on `main`** (commit + `946275a61`, PR #590, 2026-06-18); it is not part of this work package. + Verifying that fix surfaced the actual remaining download blocker: a GGUF + glob/alias bug in `ruvllm-cli`'s `get_files_to_download()` + (`download.rs:193`'s glob pattern, `models.rs:65`'s alias resolution), + which this work package tracks and fixes instead. + +--- + +## Work packages (sized for 6–8 agent swarm teams, per project anti-drift config) + +| # | Package | Bounded context | Team composition | Depends on | +|---|---|---|---|---| +| WP0a | ADR numbering hygiene remediation | Governance | coordinator, adr-architect | — | +| WP0b | MetaHarness dependency-compliance + ruvllm-cli GGUF glob/alias fix | Physical Skill Evolution | coordinator, backend-dev, tester | — | +| WP1 | LatentMesh coordination & ADR alignment | Governance | coordinator, adr-architect, system-architect | WP0a | +| WP2 | Adopt research-gate/sota-bench as Dream Machine; wire to Darwin | World Verification | coordinator, system-architect, coder ×2, tester | WP1 | +| WP3 | Three-level memory tiers on RuVector (LiveMem + TARL ledger on top of existing proof-gated writes) | Persistent Memory Governance | coordinator, backend-dev, memory-specialist, tester | WP1 | +| WP4 | TARL ledger states wired into existing ADR-194/047 proof-gate | Persistent Memory Governance | coordinator, security-architect, coder | WP3 | +| WP5 | LatentMesh `ruvector`-side crates (new, under `crates/rvAgent/`) + cross-repo wire-format coordination | Latent Communication Fabric | coordinator, system-architect (cross-repo), coder ×2, tester | WP1, WP4 | +| WP6 | Causal-audit CI gate | Latent Communication Fabric | coordinator, security-auditor, tester | WP5 | +| WP7 | Anomaly quarantine (net-new — no "LATTE" prior art exists) | Latent Communication Fabric | coordinator, security-architect, coder, tester | WP5, WP6 | +| WP8 | Witness-crate convergence (rvm ↔ autogenous) | Governance & Constitution | coordinator, system-architect (cross-repo), coder | WP1 | +| WP9 | SHAPER-pattern skill/harness evolution loop (Darwin via `@metaharness/darwin`) | Physical Skill Evolution | coordinator, system-architect, coder ×2, tester, reviewer | WP0b, WP2 | +| WP10 | WorldCycle verification stage | World Verification | coordinator, coder, tester | WP9 | +| WP11 | Constitutional capability-expansion gate (autogenous, research-prototype status) | Governance & Constitution | coordinator, security-architect, coder | WP8 | +| WP12 | 30-day acceptance harness | Cross-cutting | coordinator, performance-engineer, tester, observability-engineer | WP2, WP4, WP9, WP10, WP11 | +| WP13 *(fast-follow)* | ruvLLM KV-cache cross-model migration (crates/ruvllm: kv_cache.rs, paged_attention.rs, serving/kv_cache_manager.rs) | Cross-Model Cognition Migration | coordinator, coder ×2, tester | none — parallel track | +| WP14 *(stretch)* | RuView pose-semantic embedding + universal CSI vocabulary (pick up ADR-178 gaps C & D) | RF Sensing Substrate | coordinator, ml-developer, coder, tester | independent — fund separately | + +Use `hierarchical` topology, `max-agents 8`, `specialized` strategy per project config for each work package; spawn WP1–WP11 teams as concurrent swarms once WP1 clears (they gate on each other per the dependency column, not on serial scheduling). + +--- + +## Security / validation gates + +- **Structural frozen-weights enforcement (WP9)**: the promotion pipeline must have no code path that can write to foundation-model weight files — verified by a CI check that fails the build if any mutation surface imports a training/fine-tuning API. +- **Witness-chain requirement**: every state transition in Persistent Memory Governance, Latent Communication Fabric, and Governance & Constitution contexts must emit an RVM witness record (ADR-134 schema) before it's considered committed. No RVF write without a corresponding witness entry. +- **Proof-gated promotion**: `ruvector-proof-gate`/`rvm-proof` must approve every mutation promotion; Dream Machine's verdict is an input to the proof gate, not a bypass of it. +- **Causal-audit CI gate (WP6)**: any PR touching `latentmesh-align`, the quarantine module, or downstream consumers must pass a controlled-replacement causal audit before merge — modeled on arXiv:2607.26773's methodology, run against the same benchmark families (GSM8K/ARC-C/MATH-500-equivalent internal tasks). +- **Constitutional admission gate (WP11)**: capability-expanding mutations (new tools, new physical action classes, new communication peers) require a separate, higher-bar approval than ordinary behavioral mutations, logged distinctly in the witness chain so the acceptance test can query "zero unapproved capability expansion" directly. +- **Hosted-RVM honesty discipline**: per RVM's own ADR-285, any Cloud Run–hosted component of this program must not claim bare-metal isolation strength it doesn't have — carry that same claims-honesty discipline into this program's own status reporting. +- **Standard repo gates**: `npx @claude-flow/cli@latest security scan` after any change touching auth, capability tables, or witness signing, per repo-root `CLAUDE.md`. + +--- + +## GCP deployment / publishing surface + +- **Dream Machine control plane**: new Cloud Run service in project **`ruv-dev`**, region `us-central1` (mirror `mcp-brain-server`'s deployment as `ruvbrain` — same project, same region, session-affinity pattern, reuse its `cloudbuild` files as a template), fronting WP2's adopted research-gate/sota-bench evaluation service; secrets pulled from the existing Secret Manager entries (`ANTHROPIC_API_KEY`, `GOOGLE_AI_API_KEY`, etc.) rather than new ones where possible. +- **LatentMesh transport gateway**: if network transport (WP5) needs a rendezvous/relay point beyond direct P2P, host it as a second Cloud Run service, session-affinity enabled, in the same region for latency parity with the memory/brain services it talks to. +- **Cloud Scheduler jobs**: extend the existing 7-job pattern (train, drift, transfer, graph, attractor, cleanup, full) with new jobs for: nightly causal-audit re-runs (WP6), witness-chain integrity verification sweeps (WP8), and 30-day acceptance-harness daily checkpoint aggregation (WP12). +- **npm packages** (`@ruvector` scope): `@ruvector/dream-machine` (WP2), `@ruvector/latent-quarantine` (WP7), `@ruvector/kv-migrate` (WP13) — each following the existing `@ruvector/*` publish flow (see the user's own remembered npm release procedure: worktree flow, `--force --ignore-scripts` install, no-OTP publish, main-vs-registry drift check). +- **Crates**: new crates land under `crates/` in `ruvector` for anything not owned by a sibling repo (e.g., `ruvector-dream-machine`, `ruvector-worldcycle-verify`); cross-repo crates (`latentmesh-*`, `rvm-*`, `autogenous-*`) are published from their own repos per their existing release process. +- **Cross-repo coordination**: since LatentMesh, RVM, RuView, and Autogenous are sibling repos, this program needs a lightweight release-train coordination doc (owned by WP1) tracking version compatibility across the five repos involved — do not let `ruvector` pin to unreleased commits of the others without an explicit compatibility ADR. + +--- + +## 30-day acceptance test harness design + +**Precondition**: foundation model weights frozen and hash-verified at day 0; the structural enforcement from WP9's gate confirms no write path exists to weight files for the duration of the run. + +**Daily cycle** (automated, via WP12): +1. Run the full physical/latent/memory loop for a fixed batch of tasks (held-out task set, not seen during any prior day's mutation testing, to prevent overfitting to the eval set itself). +2. Log per-task: latency, task success (binary + graded where applicable), sensing accuracy (RuView/mmWave ground-truth comparison where available), token/compute cost. +3. Any proposed mutation that day goes through: Darwin propose → Dream Machine evaluate (dream-replay pre-filter + sandbox score) → proof-gate check → constitutional gate (if capability-expanding) → promote or reject, each step witness-logged. +4. Nightly causal-audit and witness-integrity sweeps (Cloud Scheduler jobs above) run against that day's promoted mutations. + +**Day-30 evaluation**: +- Statistical comparison of day-30 vs. day-1 metrics using a paired bootstrap or equivalent test per metric (latency, task success, sensing accuracy, cost) — "outperforms" must be a stated significance threshold (e.g., p < 0.05 with a pre-registered minimum effect size), not a raw mean comparison, to avoid the exact "gains don't prove causation" failure mode the causal-audit evidence (item 5) warns against. +- **Full mutation provenance**: every promoted mutation across the 30 days must be traceable through the witness chain from proposal → evaluation → promotion, queryable end-to-end. +- **Zero unapproved capability expansion**: diff the capability/tool/action tables at day 0 vs. day 30; any expansion must have a matching constitutional-gate approval record (WP11) or the acceptance test fails outright, independent of the performance numbers. +- **Frozen-weights verification**: re-hash the foundation model weights at day 30 and confirm bit-identical to day 0. + +**Failure handling**: any day where a promoted mutation later fails its causal audit or proof-gate re-check triggers automatic rollback via `autogenous`'s existing promotion/rollback controller (asset map §9) — the acceptance test should include at least one injected failure scenario to confirm rollback actually fires during the 30-day window, not just in isolated unit tests. + +--- + +## Top risks (revised after second-pass grounding) + +1. **Cross-repo coordination overhead, not Dream Machine, is now the top risk.** Four of the seven bounded contexts depend on sibling repos (`LatentMesh`, `rvm`, `autogenous`, `RuView`) maintained outside this program's direct control — LatentMesh's own ADR-009 shows its maintainers are still actively revising scope (twice in one day, per its own text), `autogenous` self-labels "research prototype," and `ruvector` has zero existing wiring to either LatentMesh or Autogenous today. This program's timeline is exposed to their churn and to genuinely new (not integration) engineering effort on the `ruvector` side. *(Dream Machine was the top risk in the first pass of this plan — the second inventory pass found real, CI-wired promotion machinery already exists under `research-gate`/`ruvector-sota-bench`, which downgrades that specific risk substantially.)* +2. **Two of eight founding claims are unverified, and one previously-"external" component (LATTE) turns out to have zero prior art anywhere.** Treating WP7 (quarantine) and WP14 (universal CSI vocabulary) as "implement the paper" instead of "build it for the first time" will produce schedule and credibility risk if that distinction gets lost downstream (e.g., in an ADR that cites "LATTE" as if it were a real paper). +3. **ADR numbering hygiene is worse than expected and could actively cause confusion mid-program.** 283 files, true max ADR-304, with ~15+ genuine duplicate numbers (one number reused 5 times). If WP0a isn't run early, this program's own new ADRs risk colliding with existing (possibly still-duplicate) numbers, and cross-references to "ADR-X" throughout this plan and the asset map need the reader to know which of several same-numbered documents is meant. +4. **A real dependency/compliance bug is already blocking part of the pipeline this program needs.** The MetaHarness `optionalDependencies` non-compliance (hard dependency on nine `@metaharness/*` packages) and the `ruvllm-cli` GGUF glob/alias bug in `get_files_to_download()` (blocks Darwin's local-mutator live-serve e2e testing) are concrete, small, already-known issues — cheap to fix (WP0b) but currently unfixed, and WP9 (the SHAPER-pattern evolution loop, arguably the program's centerpiece) depends on both being resolved first. (A third bug this plan previously tracked here, an HTTP-307 redirect in `ruvllm`'s model-download path, is already fixed on `main` — commit `946275a61`, PR #590, 2026-06-18 — and is not part of WP0b's remaining scope.) + +--- + +## GitHub issue breakdown + +Every work package above maps to one or more fileable GitHub issues, one per repo it touches (a cross-repo WP gets a linked issue in each repo rather than one issue pretending to speak for two codebases). **These are ready-to-file specs only — do not create them; the coordinator files them with `gh issue create` once this plan is approved.** File the five epics first, then child issues referencing their epic number, then edit each epic body to link the child issue numbers back in (`gh issue create` → capture number → `gh issue edit --body-file`). + +Suggested label set to create in each repo before filing (`gh label create`): `pir` (every issue in this program), `epic`, `adr` (issue produces/updates an ADR), `security` (touches witness/proof-gate/capability/quarantine), `cross-repo` (coordination-dependent), and phase labels `phase-0`, `phase-1`, `phase-2`, `phase-3`, `fast-follow`, `stretch`. + +### Epics (file first, one per repo) + +| Epic | Repo | Title | Labels | Links to | +|---|---|---|---|---| +| E1 | `ruvnet/ruvector` | `[PIR] Epic: Perpetual Intelligence Runtime — ruvector work packages` | `pir`, `epic` | WP0a, WP0b, WP2, WP3, WP4, WP5-ruvector, WP6, WP7, WP9, WP10, WP12, WP13, WP14-companion | +| E2 | `ruvnet/LatentMesh` | `[PIR] Epic: Perpetual Intelligence Runtime — LatentMesh coordination` | `pir`, `epic` | WP1-latentmesh, WP5-latentmesh | +| E3 | `ruvnet/rvm` | `[PIR] Epic: Perpetual Intelligence Runtime — witness-chain convergence` | `pir`, `epic` | WP8-rvm | +| E4 | `ruvnet/autogenous` | `[PIR] Epic: Perpetual Intelligence Runtime — governance integration` | `pir`, `epic` | WP8-autogenous, WP11-autogenous | +| E5 | `ruvnet/RuView` | `[PIR] Epic: Perpetual Intelligence Runtime — RF sensing substrate` | `pir`, `epic` | WP14-ruview | + +Each epic body: one paragraph linking to `docs/research/perpetual-intelligence-runtime/03-program-plan.md` in `ruvnet/ruvector` (the canonical plan document — sibling repos should link to it rather than duplicating the plan), plus a checklist of its child issue numbers to be filled in after filing. + +### Child issues + +**WP0a — ADR numbering hygiene remediation** +- Repo: `ruvnet/ruvector`. Labels: `pir`, `adr`, `phase-0`. +- Title: `[PIR][WP0a] Resolve duplicate ADR numbers in docs/adr/ (ADR-272 ×5, ADR-264/252/194/144/040 ×3, ~12 more ×2)` +- Body — Goal: audit `docs/adr/` and resolve every duplicate ADR number by renumbering the later-created file in each collision to the next free number above the true max (currently ADR-304), updating all in-repo references. Acceptance criteria: `ruflo-adr:adr-index` reports zero duplicate numbers; every renumbered ADR's old-number references (code comments, other ADRs, MCP tool descriptions) are updated; a CI check is added that fails on future duplicate ADR numbers. Dependencies: none — do this first, it blocks every other ADR this program creates. + +**WP0b — MetaHarness dependency compliance + ruvllm-cli GGUF glob/alias fix** +- Repo: `ruvnet/ruvector`. Labels: `pir`, `phase-0`. +- Title: `[PIR][WP0b] Fix MetaHarness optionalDependencies non-compliance and ruvllm-cli GGUF glob/alias bug` +- Body — Goal: (1) make the nine `@metaharness/*` packages in `crates/ruvector-sota-bench/harness` genuinely optional per ruflo ADR-150 rule 2 (`v3/docs/adr/ADR-150-metaharness-integration-surfaces.md`, "MetaHarness Integration Surfaces in `npx ruflo`," Implemented 2026-06-16 — the real source `METAHARNESS-README.md` attributes its policy to; neither `ruvector`'s nor `metaharness`'s own ADR-150 is the right document, both unrelated), or correct the documentation to state the real hard-dependency requirement; (2) fix the GGUF glob/alias mismatch in `ruvllm-cli`'s `get_files_to_download()` (`download.rs:193`, `models.rs:65`) blocking Darwin's local-mutator live-serve e2e tests (ADR-259). Note: the HTTP-307 redirect bug this issue previously also tracked is already fixed on `main` (commit `946275a61`, PR #590, 2026-06-18) and is out of scope here. Acceptance criteria: a CI job passes on the `--ignore-optional` install path per ruflo ADR-150 rule 4 (stronger than a plain successful `npm install`) without the `@metaharness/*` packages present (if made optional), or documentation matches reality (if not); `ruvllm`-backed Darwin mutator passes a live-serve end-to-end test. Dependencies: none. **Blocks WP9.** + +**WP1 — LatentMesh coordination & ADR alignment** +- Repo: `ruvnet/ruvector` (primary) + linked issue in `ruvnet/LatentMesh`. Labels: `pir`, `adr`, `cross-repo`, `phase-0`. +- Title (ruvector): `[PIR][WP1] Adopt LatentMesh ADR-009's control loop as the runtime spine; open cross-repo coordination` +- Title (LatentMesh): `[PIR][WP1] Coordination request: ruvector is building a Perpetual Intelligence Runtime on top of ADR-009` +- Body — Goal: formally adopt LatentMesh ADR-009's `execute → transfer → causal audit → measure → update authority → persist → evolve topology` loop as this program's architecture; open a standing coordination thread with LatentMesh maintainers so `ruvector`-side work (WP5) doesn't diverge from LatentMesh's own evolving design (it revised scope twice in one day per ADR-009's own text). Acceptance criteria: a coordination doc/thread exists and is linked from both epics; this program's new ADR-hygiene-corrected ADR (WP0a) explicitly cites and doesn't contradict LatentMesh ADR-001–009. Dependencies: WP0a. + +**WP2 — Adopt research-gate/sota-bench as Dream Machine; wire to Darwin** +- Repo: `ruvnet/ruvector`. Labels: `pir`, `adr`, `phase-1`. +- Title: `[PIR][WP2] Wire scripts/research-gate + ruvector-sota-bench/harness as the mutation-promotion gate (Dream Machine role)` +- Body — Goal: connect Darwin's mutation proposals to the existing `research-gate`/`ruvector-sota-bench/harness` statistical promotion machinery (paired bootstrap `statistics.ts`, hard vetoes `vetoes.ts`, Ed25519-signed replay bundles `flywheel.ts`, ADR-282) as the mandatory evaluation stage before RVM proof-gated promotion; optionally feed SONA's dream-replay engine in as a pre-filter. Acceptance criteria: no mutation reaches RVM's proof gate without passing a `research-gate` verdict; verdict + replay bundle are witness-logged. Dependencies: WP1. + +**WP3 — Three-level memory tiers on RuVector** +- Repo: `ruvnet/ruvector`. Labels: `pir`, `adr`, `phase-1`. +- Title: `[PIR][WP3] Map LiveMem/TARL three-tier memory onto ruvllm context modules + ruvector-agent-memory` +- Body — Goal: formalize working-context (ruvllm `working_memory`) / continuous-latent-state (`episodic_memory`/`semantic_cache`/`agentic_memory`) / transactional-memory (`ruvector-agent-memory` ADR-252 + `reasoning_bank` + `ruvector-temporal-coherence` ADR-211) as an explicit three-tier architecture per LiveMem's design (arXiv:2608.02515). Acceptance criteria: each tier has a documented interface and a test proving state survives context eviction (LiveMem's core claim). Dependencies: WP1. + +**WP4 — TARL ledger states on existing proof-gate** +- Repo: `ruvnet/ruvector`. Labels: `pir`, `adr`, `security`, `phase-1`. +- Title: `[PIR][WP4] Add TARL five-operation ledger (add/ignore/revise/reject/defer) onto ADR-194/047 proof-gated memory writes` +- Body — Goal: implement TARL's (arXiv:2608.03699) five executable memory operations and accepted/pending/rejected ledger states as a layer on top of the memory writes already proof-gated by ADR-194/047 — this is a smaller scope than originally planned since the underlying gate already exists. Acceptance criteria: a poisoning-style adversarial test (per TARL's own eval) shows rejected/deferred writes never reach transactional memory. Dependencies: WP3. + +**WP5 — LatentMesh `ruvector`-side crates** +- Repo: `ruvnet/ruvector` (new crates) + linked issue in `ruvnet/LatentMesh` (wire-format sign-off). Labels: `pir`, `cross-repo`, `phase-2`. +- Title (ruvector): `[PIR][WP5] Build new crates/rvAgent/latentmesh-* crates (greenfield — no existing ruvector wiring)` +- Title (LatentMesh): `[PIR][WP5] Wire-format compatibility review for ruvector's new LatentMesh client crates` +- Body — Goal: `ruvector` has zero existing LatentMesh integration (only an unmerged `origin/docs/link-latentmesh` branch) — build new crates under `crates/rvAgent/` (alongside `rvagent-a2a`, ADR-159) implementing network transport, RVF packaging, and `rvm-cap` admission enforcement against LatentMesh's `latentmesh-core`/`latentmesh-align`/`latentmesh-gate` wire format. Acceptance criteria: a live multi-agent task runs LatentMesh's causal-edge verification (ADR-003) end-to-end for the first time, from `ruvector`; LatentMesh maintainers sign off on wire-format compatibility. Dependencies: WP1, WP4. + +**WP6 — Causal-audit CI gate** +- Repo: `ruvnet/ruvector`. Labels: `pir`, `security`, `phase-2`. +- Title: `[PIR][WP6] CI gate: controlled-replacement causal audit (arXiv:2607.26773) required before latent-channel merge` +- Body — Goal: require every PR touching `latentmesh-align`-consuming code or the quarantine module (WP7) to pass a controlled-replacement causal audit before merge, modeled on the July 2026 causal-audit paper's methodology. Acceptance criteria: CI blocks merge on audit failure; audit report is witness-logged. Dependencies: WP5. + +**WP7 — Anomaly quarantine (net-new)** +- Repo: `ruvnet/ruvector`. Labels: `pir`, `security`, `adr`, `phase-2`. +- Title: `[PIR][WP7] Build latent-channel anomaly quarantine (net-new — "LATTE" has no verified prior art)` +- Body — Goal: build quarantine for anomalous latent-channel updates as an original contribution, combining arXiv:2606.28958's HMAC-manifest integrity approach with `rvm-witness` provenance — explicitly document in the ADR that this is not an implementation of a paper called "LATTE" (none was found to exist). Acceptance criteria: injected-anomaly test suite shows tampered/anomalous latent payloads are quarantined before reaching a receiving agent. Dependencies: WP5, WP6. + +**WP8 — Witness-crate convergence (rvm ↔ autogenous)** +- Repo: `ruvnet/rvm` (primary, canonical implementation) + linked issue in `ruvnet/autogenous` (consumer-side migration). Labels: `pir`, `security`, `cross-repo`, `phase-2`. +- Title (rvm): `[PIR][WP8] Confirm rvm-witness as canonical; document external-consumer API for autogenous convergence` +- Title (autogenous): `[PIR][WP8] Migrate autogenous's witness crate to depend on rvm-witness instead of a parallel implementation` +- Body — Goal: resolve the duplicated cryptographic-provenance implementation — `rvm-witness` becomes canonical (more hypervisor-integrated; `autogenous` is self-labeled "research prototype"), and `autogenous`'s `witness` crate is refactored to depend on it. Acceptance criteria: `autogenous`'s witness records are verifiably interchangeable with `rvm-witness` output; both maintainer teams sign off. Dependencies: WP1. + +**WP9 — SHAPER-pattern skill/harness evolution loop** +- Repo: `ruvnet/ruvector`. Labels: `pir`, `adr`, `phase-3`. +- Title: `[PIR][WP9] Frozen-weight skill/harness evolution loop via @metaharness/darwin (SHAPER pattern, arXiv:2608.11350)` +- Body — Goal: implement the physical-intelligence evolution loop with foundation weights frozen throughout (planner and optimizer are the same frozen model; only skills/context/harness evolve via Darwin's mutation surfaces at `harness/src/darwin.ts`, `examples/mragent` `scorePolicy`, `crates/sona/src/darwin_guard.rs`). Acceptance criteria: a CI check proves no promotion-reachable code path can write to foundation-model weight files; VLABench/ESI-Bench-style eval shows skill improvement without weight changes. Dependencies: WP0b, WP2. + +**WP10 — WorldCycle verification stage** +- Repo: `ruvnet/ruvector`. Labels: `pir`, `phase-3`. +- Title: `[PIR][WP10] Reversible-action verification stage (WorldCycle pattern, arXiv:2608.04964)` +- Body — Goal: add reversible-action-sequence verification between "observe consequences" and Dream Machine evaluation in the physical loop, targeting the paper's reported 44% long-horizon drift reduction and ~4x composite-action accuracy as the internal acceptance bar. Acceptance criteria: CycleBench-equivalent internal benchmark shows the target improvement over a no-WorldCycle baseline. Dependencies: WP9. + +**WP11 — Constitutional capability-expansion gate** +- Repo: `ruvnet/autogenous` (primary) + linked integration issue in `ruvnet/ruvector`. Labels: `pir`, `security`, `adr`, `cross-repo`, `phase-3`. +- Title (autogenous): `[PIR][WP11] Expose constitution/admission-gate API for external capability-expansion approval` +- Title (ruvector): `[PIR][WP11] Integrate autogenous's constitutional gate for capability-expanding mutations` +- Body — Goal: every mutation expanding an agent's capability set (new tool access, new physical action class, new communication peer) requires explicit constitutional approval logged to the witness chain, distinct from ordinary behavioral-mutation promotion (WP2). Acceptance criteria: acceptance harness (WP12) can query "zero unapproved capability expansion" directly against this gate's log. Dependencies: WP8. + +**WP12 — 30-day acceptance harness** +- Repo: `ruvnet/ruvector`. Labels: `pir`, `phase-3`. +- Title: `[PIR][WP12] Build the 30-day continuous-run acceptance test harness` +- Body — Goal: implement the daily-cycle harness described in this plan's acceptance-test section — frozen-weight hash verification, per-task metric logging, statistical day-30-vs-day-1 comparison (paired bootstrap, pre-registered significance threshold), full witness-chain mutation provenance query, capability-table diff for zero-unapproved-expansion, and an injected-failure rollback test via autogenous's promotion/rollback controller. Acceptance criteria: a full 30-day dry run completes and produces a pass/fail report against every acceptance criterion in the brief. Dependencies: WP2, WP4, WP9, WP10, WP11. + +**WP13 — ruvLLM KV-cache cross-model migration (fast-follow)** +- Repo: `ruvnet/ruvector`. Labels: `pir`, `fast-follow`. +- Title: `[PIR][WP13] Implement closed-form KV-cache cross-model migration in ruvllm (arXiv:2608.03893)` +- Body — Goal: implement the paper's closed-form linear KV-cache mapper for same-family model migration in `crates/ruvllm` (`kv_cache.rs`, `paged_attention.rs`, `serving/kv_cache_manager.rs`), with the nonlinear MLP fallback for degrading pairs, plus a routing gate that predicts transfer quality before migrating. Acceptance criteria: reproduces the paper's reported 2.7-25x speedup over re-prefill on an internal same-family model pair; routing gate correctly refuses/downgrades for a known-degrading pair. Dependencies: none — independent parallel track, can start immediately. + +**WP14 — RuView pose-semantic embedding + universal CSI vocabulary (stretch)** +- Repo: `ruvnet/RuView` (primary) + linked companion issue in `ruvnet/ruvector` (for `ruvector-perception` validation). Labels: `pir`, `stretch`. +- Title (RuView): `[PIR][WP14] Real-CSI validation + pose-semantic embedding pipeline (pick up ADR-178 gaps C & D)` +- Title (ruvector): `[PIR][WP14] Validate ruvector-perception (3.8K LOC) against real CSI captures, not synthetic-only` +- Body — Goal: close ADR-178's two still-open gaps — gap C (CSI bridge I/Q → pose-semantics conversion) and gap D (mcp-brain-server-side cluster consumer) — and validate `ruvector-perception` against real, not synthetic, CSI data. If time/budget allows, extend into the universal/heterogeneous-chipset CSI vocabulary research bet (evidence item #8 — no prior art exists anywhere, first-party research). Acceptance criteria: `ruvector-perception` achieves a documented accuracy baseline on real CSI captures (not just synthetic); gap C/D are closed per ADR-178's own definition of done. Dependencies: none — independent, recommend funding separately from the WP0-WP12 critical path. + +--- diff --git a/docs/research/perpetual-intelligence-runtime/04-verification-addendum.md b/docs/research/perpetual-intelligence-runtime/04-verification-addendum.md new file mode 100644 index 000000000..125dffe5f --- /dev/null +++ b/docs/research/perpetual-intelligence-runtime/04-verification-addendum.md @@ -0,0 +1,442 @@ +# Verification Addendum — Direct Source Checks Against LatentMesh and Autogenous + +Status: addendum to `02-asset-map.md` and `03-program-plan.md`, compiled +2026-08-19 by a third research pass (asset-scout) that cloned both external +repos directly rather than relying on `gh` CLI metadata or org-search +results. **This document does not edit `02-asset-map.md` or +`03-program-plan.md` in place** — it records what those two documents still +get wrong or omit as of this program's ADR-authoring pass, so the correction +is traceable rather than silently folded in. Where a claim below contradicts +`02-asset-map.md`, the section header says so explicitly. + +Repos cloned: `ruvnet/LatentMesh` (HEAD `922ea196`, dated 2026-08-18) and +`ruvnet/autogenous` (HEAD `b5c6e838`, dated 2026-08-19). + +## 1. LatentMesh — accurate but understated in scale + +`02-asset-map.md` §8 correctly describes LatentMesh's crates, ADR sequence, +and "not implemented" markers, and its headline finding's loop diagram and +"statistical primitive and admission gate implemented; closed loop not +wired" quote both match source verbatim, including the per-stage markers on +ADR-004 through ADR-008 (004 not wired to live MidStream; 005 not wired to a +live RuVector instance; 006 no live Darwin loop; 007 no live Radio/RuView; +008's admission gate implemented in `crates/latentmesh-gate`, RVF packaging +and RVM enforcement not wired). + +**What §8 does not convey: LatentMesh is a small research prototype.** The +entire workspace is 1,407 LOC across four crates: + +| crate | LOC | tests | +|---|---|---| +| `latentmesh-core` | 272 | 6 | +| `latentmesh-align` | 454 | 6 | +| `latentmesh-gate` (incl. `causal.rs`) | 534 | 11 | +| `latentmesh-bench` | 147 | 0 | + +That is real, tested code, but roughly 1/23rd the size of `ruvector-core` +alone (32,380 LOC / 503 tests). **There is no network transport crate +anywhere in the workspace** — no QUIC/TCP/transport module exists. This is +consistent with, and reinforces, `02-asset-map.md`'s own §8 correction that +`ruvector`-side LatentMesh work is greenfield, not integration — but it also +means "adopt LatentMesh ADR-009 as the spine" (this program's ADR-305) is +adopting a *design contract and ~1.4K LOC of primitives*, not inheriting a +mature system. Scope every ADR and work package that references LatentMesh +accordingly. + +**Minor date correction**: `02-asset-map.md` §8 states LatentMesh was "last +updated 2026-08-19." The correct date, per the cloned HEAD commit, is +**2026-08-18**. + +## 2. Autogenous — `02-asset-map.md` is materially incomplete + +### 2a. The ADR catalog is undercounted, and the missing ADRs are the program itself + +`02-asset-map.md` §9 cites autogenous's ADRs as **"391/392/393/397."** The +actual catalog, confirmed by directory listing, runs **391 through 403 — 13 +ADRs, not 4**: + +``` +ADR-391-autogenous-governed-self-evolving-architecture.md +ADR-392-autogenous-genome-language-antibody-protocol.md +ADR-393-autogenous-product-thesis-adaptive-agent-firewall.md +ADR-394-cryptographic-closure-of-the-promotion-path.md +ADR-395-radio-realtime-streaming-peer-expert-mesh.md +ADR-396-peer-expert-protocol-security-and-governed-evolution.md +ADR-397-autogenous-streaming-mixture-of-agents.md +ADR-398-applications-and-development-loop-integration.md +ADR-399-provider-backed-mesh-run-rvm-rvf.md +ADR-400-self-evolving-mesh-perpetual-loop.md +ADR-401-perpetual-intelligence-machine.md +ADR-402-ruview-cognitum-spaces-spatial-intelligence.md +ADR-403-verifiable-execution-loop.md +``` + +The eight missing from the asset map's list matter directly to this program: + +- **ADR-401 — "The Perpetual Intelligence Machine."** Status: **Accepted** + (framing + capability map) · **Partial** (implementation). Dated + 2026-08-16. Defines a 10-capability map with an honest Built/Partial/ + Gap/Narrative status legend, a stage-by-stage operating loop, and a V1 + + 30-day acceptance test. Carries an explicit honesty anchor: *"'Perpetual' + does not mean conscious, immortal, or continuously improving… The system + targets operational continuity, not infallibility."* This is, on its face, + substantially the same product this program's brief describes. See + ADR-305 for the required reconciliation. +- **ADR-400 — "Self-Evolving Mesh Perpetual Loop."** Status: **Accepted — + Implemented (first flywheel turn measured).** +- ADR-394 (cryptographic closure of the promotion path), ADR-395/396 (radio + realtime streaming peer-expert mesh + its security/governed-evolution + counterpart), ADR-398 (applications/dev-loop integration), ADR-399 + (provider-backed mesh runs on RVM/RVF). +- **ADR-402 — "RuView/Cognitum Spaces Spatial Intelligence."** Status: + Accepted; read-side adapters, fail-closed seam, production HTTPS API + complete; write-side sync and a 30-day acceptance test outstanding. + Directly relevant to this program's RF Sensing Substrate context (WP14). +- **ADR-403 — "Verifiable Execution Loop."** Status: Accepted; + `VerifiedPromotion` implemented, concurrent-promotion fencing and durable + replay partially implemented, enforced isolation accepted-design-pending. + +ADR-401 also cross-references **"metaharness ADR-322 (flywheel receipts/ +promotion)"** — a third ADR series appearing in none of this program's +research documents. Its content is unlocated as of this addendum; see +ADR-305's Decision §3 for the resulting action item. + +### 2b. The governance implementation is TypeScript, not the Rust crates `02-asset-map.md` implies + +`02-asset-map.md` §9 lists autogenous's crates as a Rust workspace (`witness, +antibody, agl-types, generator, evaluator, verifier, lineage, ledger, +promotion, deployment, constitution, runtime, midstream-adapter, service`). +That crate list is correct as far as it goes, but ADR-401's capability map +points almost entirely at **`packages/radio-moe/src/*.ts`**, not the Rust +workspace: + +- `packages/radio-moe/src` — 6,171 LOC; `packages/radio-moe/test` — 3,161 LOC +- All 11 modules ADR-401 names exist: `mesh.ts` (252), `mesh-evolve.ts` + (277), `mixture.ts` (685), `action-gate.ts` (440), `failover.ts` (455), + `disclosure.ts` (125), `reputation.ts` (154), `rvf-trajectory.ts` (67), + `lineage-independence.ts` (243), `relevance.ts` (99), `capability.ts` (31) +- The Rust crates total 8,096 LOC / 91 test functions — real, but a + different layer (crypto/protocol primitives) than the governance loop + ADR-401 describes as Built/Partial. + +Any PIR ADR describing autogenous's governance loop (ADR-315, this program) +should point readers at `radio-moe`, not only at the Rust crate names. + +### 2c. Crate list omission + +`02-asset-map.md` §9 lists 14 autogenous crates and gets 14 right, but +**misses `envelope`** (1,009 LOC, 7 tests) — the second-largest crate in the +workspace after `runtime` (1,471 LOC). Everything else in the asset map's +list is confirmed accurate. + +### 2d. Cloud Run deployment — confirmed, not just inferred + +`02-asset-map.md` documents Cloud Run deployment concretely for +`mcp-brain-server`/`ruvbrain`, but does not confirm it for autogenous +specifically. The root `Dockerfile` in `ruvnet/autogenous` is headed +*"autogenous-service — Cloud Run image (the Autogenous AGL control-plane as +a service)"*, multi-stage `rust:1-bookworm` → `debian:bookworm-slim`, `ENV +PORT=8080`, with a comment noting Cloud Run sets `$PORT`. Backed by +`crates/service` (980 LOC). + +### 2e. The prototype-badge / Accepted-ADR tension + +`02-asset-map.md` §9 correctly cites autogenous's README "research prototype" +status badge and its "Honest status" note that it is "not wired to live +MidStream/MetaHarness/RVF/RVM yet" and that "performance and economics claims +in the ADRs are hypotheses until benchmarked." What is worth flagging +explicitly: several of autogenous's own ADRs (400, 401, 402, 403) carry +**Accepted** status despite the repo-level prototype badge. When citing +autogenous maturity in any PIR ADR, cite the README badge for overall repo +maturity and the individual ADR's status line for that specific capability — +the two are not always in agreement, and neither alone tells the full story. + +## 3. Witness-crate comparison (grounds ADR-312's reframe) + +`02-asset-map.md` §9's "duplication note" (repeated in `03-program-plan.md`'s +original ADR #8 draft) described `rvm-witness` and autogenous's `witness` +crate as having "near-identical framing," recommending autogenous depend on +or converge with `rvm-witness`. A direct comparison of both crates does not +support a merge/dependency framing: + +| | `autogenous/crates/witness` | `ruvector`'s `crates/rvm/crates/rvm-witness` | +|---|---|---| +| Size | 302 LOC, 4 tests, one file | 4,405 LOC, multi-file (`v2.rs` 880, `replay.rs` 253, `hash.rs` 204, `record.rs`) | +| Hash | SHA-256 over canonical JSON | u64 chain/record hashes (`compute_chain_hash`, `compute_record_hash`) | +| Auth | Ed25519 (`ed25519_dalek`), per-role `SigningAuthority` | Keyed chain MAC with derivation + ratcheting (`derive_chain_key`, `ratchet_chain_key`, `erase_key`, `CHAIN_KEY_CONTEXT`) | +| Record shape | `WitnessRecord` over JSON artifacts (genome, mutation, antibody, incident) | 64-byte cache-line-aligned privileged-action records in a fixed-capacity ring (`WitnessLog`, `WitnessLogV2`, `DEFAULT_RING_CAPACITY = 262_144`) | +| Extras | `WitnessSeal`, `verify_seal`, `verify_chain` | `CoveragePolicy`/`CoverageError`, `verify_chain_v2_ratcheted`, `v1_head_to_genesis`, `verify_log_bytes`, queries by partition/action-kind/time-range | +| Runtime | std, service-side, offline+deterministic | `no_std`, hypervisor-side | + +The shared element is the abstract idea of an append-only, hash-chained, +tamper-evident log — cryptographic primitives, data model, storage strategy, +and target runtime all differ, and each choice is correct for its own layer: +SHA-256-over-JSON does not fit in a `no_std` 64-byte-aligned ring buffer, and +`rvm-witness`'s u64 keyed-MAC chain is deliberately not a signature scheme. +**ADR-312 in this program set is written against a shared witness record +schema plus a cross-layer verification/anchoring contract, not a crate +merge or a dependency edge — merging the two crates as originally proposed +would be a design error.** + +## 4. Summary of corrections to carry into this program's ADRs + +| Claim in `02-asset-map.md` | Correction here | PIR ADR affected | +|---|---|---| +| LatentMesh "last updated 2026-08-19" | 2026-08-18 | ADR-305 | +| LatentMesh described without scale context | 1,407 LOC / 4 crates / no transport crate | ADR-305, ADR-309 | +| Autogenous ADRs "391/392/393/397" | 391–403 (13 ADRs); 400/401/402/403 previously uncited | ADR-305, ADR-315 | +| Autogenous governance described via Rust crate list only | Governance loop lives in `packages/radio-moe/src/*.ts` (6,171 LOC) | ADR-315 | +| Autogenous crate list (14 named) | Missing `envelope` (1,009 LOC) | ADR-312 | +| Autogenous Cloud Run presence unconfirmed for this repo specifically | Confirmed via root `Dockerfile` (`autogenous-service`, `crates/service`) | ADR-315 | +| `rvm-witness`/autogenous `witness` "near-identical framing" → merge/depend | Different primitives, data models, std/no_std, layers; reframe as shared schema + anchoring contract | ADR-312 | + +## 5. `metaharness ADR-322` located — it is `ruflo` ADR-322, misattributed by autogenous + +A fourth research pass located the ADR autogenous ADR-400/401 cite as +"metaharness ADR-322": it lives in **`ruvnet/ruflo`**, at +`v3/docs/adr/ADR-322-metaharness-flywheel-integration.md` — **"Adopt +`@metaharness/{flywheel,darwin}` as pluggable engines behind ruflo's ADR-176 +self-improvement flywheel,"** status Accepted (phases 0–2 implemented), +dated 2026-07-28. It is ruflo's own ADR *about consuming* MetaHarness, not an +ADR published by the MetaHarness/`agent-harness-generator` project (which was +itself renamed to `ruvnet/metaharness`, 230 ADRs topping out at ADR-250 — +no ADR-322 exists there). **Cite this dependency as "ruflo ADR-322," never +"metaharness ADR-322."** + +ADR-322 has three Accepted, implemented children directly relevant to this +program's promotion-gating ADRs (ADR-306, ADR-312): + +- **322A** — evaluation↔promotion transaction model (`RUFLO_FLYWHEEL_TRANSACTION_V1`). +- **322B** — Darwin proposer adapter, enforcing a separation-of-powers + invariant this program's own ADR-401 reconciliation (ADR-305) is reaching + for independently: *"A proposer produces untrusted candidates only. It + cannot issue promotion decisions or mutate active policy."* + `promoteFlywheelCandidate` is the sole promotion authority. +- **322C** — receipt/ledger/verification protocol: RFC 8785 JCS canonical + JSON, SHA-256 digests, **Ed25519 with domain separation** + (`Ed25519(domainPrefix || 0x00 || canonicalBytes)`), UUIDv7 run IDs, + independent statistical recomputation via deterministic paired bootstrap. + +Separately, **ruflo PR #2956** implements the sequential-promotion-evidence +mechanism (anytime-valid e-process, `α_k = α_total · 6/(π²k²)`; 0.6% +measured family-wise false-promotion rate over 1,000 simulated nulls, the +bound holding **per epoch**), and **ruflo ADR-381** (**Proposed**, +2026-08-10) governs stream identity and budget-exhaustion recovery over it. +Together they are the concrete prior art for any PIR ADR claiming +statistical promotion gating. See §8d for the full correction — an earlier +version of this paragraph attributed the mechanism to ADR-381 directly, +omitted its Proposed status, and dropped the per-epoch qualifier; that +version is superseded by this one and by §8d, not by both disagreeing. + +ruflo has already suffered the exact ADR-number collision this program is +trying to avoid: a dream-cycle research PR independently proposed +`ADR-322-dream-cycle-memory-typed-provenance.md` and was closed as superseded +when it collided with the already-merged flywheel-integration ADR-322 — a +live precedent for verifying numbers against the actual filename list +immediately before committing, not against a max+1 assumption. + +## 6. `ruvnet/dream-machine` is a real, Accepted, shipped repo — corrects §"Dream Machine" reasoning above and in `02-asset-map.md`/`03-program-plan.md` + +An earlier pass of this research reported "Dream Machine" as a name with no +matching asset, later corrected in `02-asset-map.md`'s revision to point at +`ruvector`'s own `scripts/research-gate/` + `ruvector-sota-bench/harness` +(ADR-282) as the functional equivalent. **Both were incomplete**: +`ruvnet/dream-machine` is itself a real, public, published-to-npm repo +(pushed 2026-08-19), and its own **ADR-0001** — *"The Dream Machine engine — +a config-driven, evidence-gated nightly evolution loop composed from the +ruvnet stack"* — is **Accepted, engine v0.1.0 shipped** (compile / ledger / +witness / schedule / memory modules + CLI/TUI, 85 tests, ~2,558 LOC across +six packages), dated 2026-08-13. + +ADR-0001's own thesis is the one this program's brief and ADR-306 are +circling: *"Freeze the model. Evolve the harness. Evaluation is not +promotion — the machine never merges; a human does."* It **composes** +`@metaharness/flywheel` 0.1.10, `@metaharness/darwin` 0.9.1, +`@metaharness/redblue` 0.1.4, `metaharness` CLI 0.4.5, `ruvector` 0.2.41, and +`agentdb` 3.0.0-alpha (all optional/peer dependencies), and its own text +names `ruvnet/ruflo`'s and `ruvnet/metaharness`'s nightly dream-cycle +routines as prior instances it **subsumes** — specifically metaharness +ADR-251 ("MetaHarness Nightly Dream Cycle") and the Ruflo Nightly Dream Cycle +v3 **(the "metaharness ADR-251" half of that claim does not resolve — see +§8b; reported here as dream-machine ADR-0001's own assertion, not as +independently verified)**. + +**Net effect**: the "Dream Machine" mechanism now exists in **four** places +— `ruvnet/dream-machine` (the generalized, already-shipped engine), +`ruvnet/ruflo`'s nightly dream cycle, `ruvnet/metaharness`'s `docs/dream-cycle/` +(not an ADR — see §8b for why the "ADR-251" identifier is wrong), and +`ruvector`'s own `scripts/research-gate/` + ADR-282. ADR-306 in this program +is revised to cite `ruvnet/dream-machine` ADR-0001 as the consolidating +design ruvector's `research-gate` should align with, not as a name this +program invents or as work fully covered by `research-gate` alone. + +**Version-drift note**: `ruvnet/dream-machine` composes `@metaharness/darwin` +0.9.1 / `@metaharness/flywheel` 0.1.10; `ruvector` currently pins `darwin` +0.8.0 / `flywheel` 0.1.7 — three of the nine `@metaharness/*` packages +`ruvector` depends on (per `02-asset-map.md` §1) are behind the versions +`dream-machine` itself composes against. Worth a line in WP0b's dependency +remediation scope, not a blocker for this ADR set. + +## 7. Open items not resolved by this addendum + +None remaining from the original metaharness-ADR-322 question (resolved in +§5). Still open: no repo checked so far publishes a formal reconciliation +between `ruvnet/dream-machine` ADR-0001, `ruvector`'s ADR-282 +(`research-gate`), and autogenous ADR-400/401's flywheel — WP1/WP2 own +producing that reconciliation, per ADR-305 and ADR-306. + +## 8. PR #847 review corrections — a fourth research pass (adr-reviewer + asset-scout, post-merge-review) + +An adversarial review of the initial PIR ADR set (PR #847) verified every +cross-repo claim against direct clones of `ruvnet/LatentMesh`, `ruvnet/autogenous`, +`ruvnet/dream-machine`, and `ruvnet/metaharness`, and separately against a +clone of `ruvnet/ruflo` (HEAD `fa13ee4`, 2026-08-15; 177 ADRs in +`v3/docs/adr/`) that §1–§7 above did not have access to. Three findings were +blocking; this addendum records the corrected facts so future PIR work +doesn't regress to the earlier drafts' claims. + +### 8a. Autogenous ADR-401's promotion predicate is DONE, not open + +§2a above (and the earlier draft of ADR-305/ADR-315) cited ADR-401's +capability-table row 5 ("not yet one checked predicate") as the program's +residual scope. **That row is stale relative to ADR-401's own Decision +section.** ADR-401's Update 1 §3, "Converge the promotion invariant to one +predicate," is marked **DONE**: `mesh-evolve.ts` exports +`promoteAuthorized(candidate, champion, { authorized, reversible }) → +PromotionDecision`, the single gate `Promote = Better ∧ Safe ∧ Authorized ∧ +Reversible` with each conjunct independently blocking, `evolveMesh` routing +every promotion through it, proven by `test/promote-authorized.test.ts` +(all-four promotes; any three-of-four does not). ADR-315 (this program) is +rescoped accordingly: it adopts `promoteAuthorized`, it does not build or +close it. + +### 8b. "metaharness ADR-251" does not exist — corrected provenance + +ADR-306 (and this addendum's own §6, before this correction) restated +dream-machine ADR-0001's "Prior instances" citation of "metaharness ADR-251 +(MetaHarness Nightly Dream Cycle)" as fact. **The dangling citation +originates in `dream-machine` ADR-0001 line 9 itself** — *"Prior instances: +`ruvnet/metaharness` ADR-251 (MetaHarness Nightly Dream Cycle)…"* — and was +relayed verbatim from that source by the research pass that first surfaced +it, without checking that it resolved. It is not a fabrication introduced by +this program on either the research or ADR-authoring side; it is a citation +inside a real, Accepted upstream ADR that itself needed resolving before +being repeated. Direct inspection of `ruvnet/metaharness` (HEAD `5453c8c`) +finds **230 ADR files topping out at `ADR-250-sota-proof-ladder.md`** — no +ADR-251. The Nightly Dream Cycle material instead lives in +`docs/dream-cycle/` (`2026-08-13-gist.md`, `2026-08-14-gist.md`, +`LEDGER.md`), not as an ADR. ADR-306 now cites `docs/dream-cycle/` and +states this provenance rather than repeating the citation as independently +verified. **Future readers**: the correct fix is ADR-306's current text — +do not "fix" it back to "metaharness ADR-251" on the assumption that an ADR +citation inside another Accepted ADR must already be resolved. + +### 8c. "ruvector ADR-150 (optionalDependencies policy)" is a misattribution — resolved to `ruflo` ADR-150 + +ADR-313 (and ADR-306, and `03-program-plan.md`) cited "ruvector ADR-150" as +the source of the `optionalDependencies` policy `METAHARNESS-README.md` +claims compliance with. Checked against all three clones: + +- `ruvector`'s own `ADR-150` is `ADR-150-pi-brain-ruvltra-tailscale.md` — "π + Brain + RuvLtra via Tailscale — Semantic Embedding Upgrade." Unrelated. +- `metaharness`'s own `ADR-150` is + `ADR-150-tailscale-local-frontier-concurrent-benchmarks.md`. Also + unrelated. +- `METAHARNESS-README.md` itself attributes the policy to "**ADR-150**: + MetaHarness Integration Surfaces (**upstream**)." + +**A first pass through this section marked that attribution unverified. It +resolves cleanly**: the upstream document is **`ruflo`'s own ADR-150**, +`v3/docs/adr/ADR-150-metaharness-integration-surfaces.md` — *"ADR-150 — +MetaHarness Integration Surfaces in `npx ruflo`,"* **Status: Implemented** +(2026-06-16, rev. 06-17). The evidence chain: (1) the title matches +`METAHARNESS-README.md`'s citation on its distinctive phrase; (2) this ADR +set already established the README's *other* "upstream" citation +(ADR-103, same README, same word "upstream") is ruflo's — corroborated +independently by ruflo ADR-322C line 105 (see §8d) — same pattern, same +repo; (3) `METAHARNESS-README.md`'s own section headings mirror ruflo +ADR-150's four rules one-for-one (e.g. its "MetaHarness Removable" heading +against ADR-150's rule 1); (4) ruflo ADR-322 line 17 shows the policy in +force upstream, at the exact package versions ADR-306's version-drift note +already flags `ruvector` as pinning (`@metaharness/darwin@^0.8.0`, +`@metaharness/flywheel@^0.1.7`, both declared `optionalDependencies`). +ADR-150's normative rule 2 is verbatim the policy in question: *"Optional in +`package.json`: `@metaharness/*` packages MUST appear in +`optionalDependencies` or `peerDependencies` (optional), never in +`dependencies`."* Rule 4 — *"at least one CI job must run `--ignore-optional` +… the only structural defense against accidentally promoting an optional dep +to required"* — is a stronger, CI-testable acceptance criterion than a +plain `npm install` check, and is now the one this program's ADRs and plan +cite. + +This is the exact failure mode ADR-305 §4 requires PIR documents to avoid +(repo-qualify every cross-repo ADR reference) reproduced inside the set +meant to enforce it — and it is now the **fourth** instance of the same +"wrong repo owns this ADR number" pattern this program has caught (ADR-103, +"metaharness ADR-322" → ruflo ADR-322, "metaharness ADR-251" → does not +exist, and this one). Every reference in the ADR set and the plan now cites +`ruflo` ADR-150 directly instead of an unverified attribution. + +### 8d. The ruflo ADR-322 family verified verbatim; ADR-381 needed two corrections + +A full clone of `ruvnet/ruflo` confirms the ADR-322 family exactly as this +program's ADR-306/310/312/313 cite it: + +| ADR | Title | Status | +|---|---|---| +| 322 | Adopt `@metaharness/{flywheel,darwin}` as pluggable engines behind ruflo's ADR-176 self-improvement flywheel | Accepted — phases 0–2 implemented (2026-07-28) | +| 322A | Evaluation and promotion transaction model | Accepted — implemented (`RUFLO_FLYWHEEL_TRANSACTION_V1`) | +| 322B | Darwin proposer adapter | Accepted — implemented for bounded retrieval-policy candidates (`RUFLO_FLYWHEEL_DARWIN_V1`) | +| 322C | Receipt, ledger, and verification protocol | Accepted — implemented (`RUFLO_FLYWHEEL_RECEIPT_V1`) | + +322B's separation-of-powers sentence is verbatim (`ADR-322B-darwin-proposer-adapter.md` +line 10): *"A proposer produces untrusted candidates only. It cannot issue +promotion decisions or mutate active policy."* ADR-322 line 15 reinforces it: +*"Darwin adapters remain candidate generators and never gain promotion +authority."* 322C's stack is confirmed with more precision than this +program's earlier drafts stated: canonical JSON is RFC 8785 JCS, digest is +SHA-256, signature is `Ed25519(domainPrefix || 0x00 || canonicalBytes)` +across **two distinct Ed25519 signing domains** — `ruflo/flywheel-receipt/v1` +(L96) and `ruflo/flywheel-ledger-head/v1` (L102) — plus a third +domain-separated prefix, `ruflo/bootstrap/v1` (L82), that seeds the +deterministic paired bootstrap's statistics rather than signing anything (an +earlier draft of this addendum and of ADR-312 called this "three signing +domains," overcounting by one), with `candidateId = SHA-256(JCS(candidate +policy))` and `receiptId += SHA-256(JCS(unsigned receipt payload))`. Every authorizing term in a 322C +record is graded `recomputed`, `signature-verified`, or `trusted-assertion`. +322C line 105 also settles the ADR-103 cross-repo ambiguity this program +flagged in ADR-305: keys "use ADR-103's provider mechanism but a distinct +purpose/domain," confirming the witness-manifest ADR-103 is `ruflo`'s. + +**ADR-381 needed three corrections.** (a) **Status is Proposed, not +Accepted** (line 3, dated 2026-08-10; no supersede or later Accepted line — +earlier drafts of ADR-306/310/312 implied it was settled governance +alongside its Accepted siblings). (b) **The 0.6% figure and the `α_k = +α_total · 6/(π²k²)` allocation belong to `ruflo` PR #2956's mechanism**, +which ADR-381 *governs*, not to ADR-381's own decision. ADR-381's actual +contribution is narrower: scoping the α ledger to one stream per project +root within the ADR-322 transaction state, and `resetSequentialEvidence` — an +explicit, `confirm: true`-gated, human-reasoned evidence-epoch reset for +budget exhaustion, expiring all outstanding receipts so stale evidence +can't be replayed against a fresh budget. (c) The false-promotion bound is +**per-epoch**, not global: line 33 states the guarantee as "family-wise +false-promotion probability is ≤ α_total **per epoch**" after a reset. Any +PIR document citing this bound now states it the same way. + +### 8e. The `ruvllm` HTTP-307 bug is already fixed; the systemic lesson + +ADR-313 (and `03-program-plan.md`) cited an HTTP-307 redirect bug in +`ruvllm`'s model-download path as an open blocker. It was already fixed on +`main` before this ADR set was written (commit `946275a61`, PR #590, +2026-06-18). The actual remaining download blocker is a GGUF glob/alias bug +in `ruvllm-cli`'s `get_files_to_download()` (`download.rs:193`'s glob +pattern disagreeing with `models.rs:65`'s alias resolution). + +All three blocking findings (8a–8c) and this one share a root cause: a claim +was carried forward from a source document — an upstream ADR's stale table +row, a citation inherited from another repo's ADR, a documented-but-unlocated +upstream attribution, or an earlier bug report — without checking that +source's own current state via fix history (`git log` on the named path, +merged PRs, release notes). ADR-305 now states this as a standing +verification rule for the remainder of this program (see its Decision §6). diff --git a/docs/research/perpetual-intelligence-runtime/05-dream-machine-consolidation.md b/docs/research/perpetual-intelligence-runtime/05-dream-machine-consolidation.md new file mode 100644 index 000000000..8ecf45c35 --- /dev/null +++ b/docs/research/perpetual-intelligence-runtime/05-dream-machine-consolidation.md @@ -0,0 +1,59 @@ +# Dream Machine Consolidation Position (PIR WP2) + +**Status**: Delivered with the first WP2 slice · **Tracking**: ruvector#838, dream-machine#22 · **Decision basis**: ADR-306 + +Four independent implementations of "nightly, evidence-gated evaluation" exist across the org. +Leaving four live is the outcome WP2 exists to prevent. This document states the position for each: +keep/adapt/deprecate, which layer it owns, and how it is wired. + +## Consolidation table + +| # | Implementation | Position | Layer it owns | Wiring | +|---|---|---|---|---| +| 1 | `ruvnet/dream-machine` engine (npm `dream-machine` v0.1.1, ADR-0001 Accepted) | **Keep — adopt as evaluation core** | Orchestration + record: verdict vocabulary (`ACCEPT`/`REJECT`/`INCONCLUSIVE`), 10-column ledger, witness stamp (`sha256(sha256(report)+commit)`), schedule/compile, learning signals | Consumed by ruvector via `crates/ruvector-sota-bench/harness/src/dreamMachine.ts` (this slice). Engine is invoked through its published programmatic API (`run(argv, io)`) with an in-memory IO — no fork, no vendoring. | +| 2 | ruflo dream cycle (`ruvnet/ruflo`) | **Deprecate as an implementation; keep its contracts** | Historically: nightly cycle prototype. Going forward: none. Its ADR-322A/322B evaluation↔promotion transaction model and ADR-381 sequential-evidence statistics remain the *contracts* PIR adopts | dream-machine ADR-0001 explicitly names it as a subsumed prior instance. New dream-cycle work lands in `ruvnet/dream-machine`; ruflo keeps only the transaction/witness contracts (ADR-322C) that verdicts are logged against. | +| 3 | metaharness `docs/dream-cycle/` (prior reference instance; note: there is **no** metaharness "ADR-251") | **Deprecate — documentation-only prior art** | None going forward; it was the documented nightly-routine reference that dream-machine productized | Superseded by dream-machine ADR-0001 (which names it as subsumed). No code to migrate; its ledger format lives on as `@dream-machine/ledger`'s 10-column schema. | +| 4 | ruvector research-gate + sota-bench harness (ADR-282: `scripts/research-gate/`, `harness/src/{statistics,vetoes,flywheel,darwin}.ts`) | **Keep — adapt as the statistical + promotion-recommendation layer** | Paired-bootstrap significance (`statistics.ts`), hard vetoes (`vetoes.ts`), Ed25519-signed replay bundles + promotion rule (`flywheel.ts`), Darwin mutation proposals (`darwin.ts`), CI wiring (`.github/workflows/research-*.yml`) | dream-machine verdicts enter this layer as veto-provider input (`dreamMachineVetoProvider`), feeding the existing `ruvectorPromotionRule`. research-gate's `verify_promotion.py` and the proof gate remain unchanged downstream authorities. | + +## The integration contract (who owns what — no duplicated authority) + +- **Paired-bootstrap significance**: owned by ruvector `statistics.ts` (ADR-282). The engine never + recomputes it; the adapter maps `PairedDecision.outcome` → engine verdict via `verdictFromDecision`. +- **Verdict vocabulary, ledger record, witness stamp**: owned by the dream-machine engine. The + adapter drives the engine (`witness stamp` → `ledger append` → `ledger verify` → `witness verify`) + and returns a frozen `DreamMachineVerdict`. +- **Hard vetoes and the promotion recommendation**: owned by ruvector `vetoes.ts`/`flywheel.ts`. + Verdicts are conjunctive veto input: `ACCEPT` adds no credit; `REJECT`/`INCONCLUSIVE` block. + No mutation reaches the proof gate without passing a verdict. +- **Signed replay bundle**: owned by ruvector `flywheel.ts` (`@metaharness/flywheel` signer), + unchanged by this slice. +- **Promotion**: owned by a human. The adapter exports no promote/merge function (test-enforced); + a verdict is an input to `ruvector-proof-gate`/`rvm-proof`, never a bypass of it. + +## Wiring diagram + +``` +Darwin proposals (darwin.ts) + │ + ▼ +benchmark.ts observations ──► statistics.ts PairedDecision ─┐ + ▼ + dreamMachine.ts (engine: verdict + ledger + witness) + │ vetoesFromVerdict + ▼ +capabilityVetoProvider ─────────────────────────► vetoes (conjunctive) + │ + ▼ + flywheel.ts ruvectorPromotionRule → recommendation only + │ + ▼ + research-gate / proof gate / HUMAN merge (unchanged) +``` + +## Out of scope for this slice (tracked in #838) + +- `@metaharness/*` version-drift resolution (darwin 0.9.1 / flywheel 0.1.10 vs pinned 0.8.0 / 0.1.7) — WP0b (#846). + Note: the published `dream-machine` npm package is dependency-free (bundled dist), so this slice does not collide with the pins. +- Witness-logging verdicts against ruflo ADR-322C's JCS/Ed25519 contract (program-wide, ADR-312). +- Cloud Run control plane in `ruv-dev`/`us-central1`. +- SONA dream-replay pre-filter feeding candidates into this pipeline. diff --git a/npm/core/platforms/win32-x64-msvc/ruvector.node b/npm/core/platforms/win32-x64-msvc/ruvector.node index 738046873..02bc18b71 100644 Binary files a/npm/core/platforms/win32-x64-msvc/ruvector.node and b/npm/core/platforms/win32-x64-msvc/ruvector.node differ diff --git a/npm/package-lock.json b/npm/package-lock.json index 3584c52a5..951c60db2 100644 --- a/npm/package-lock.json +++ b/npm/package-lock.json @@ -2085,68 +2085,22 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@metaharness/darwin": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@metaharness/darwin/-/darwin-0.8.0.tgz", - "integrity": "sha512-Pgefr/es0Btofh7GxQrOAg/i43ZKcLUfeD9rndOAkpA8s3ZYohSmfLerJLNsGOOKc2eTvmmauljl8QEVmKC2dw==", - "license": "MIT", - "bin": { - "metaharness-darwin": "dist/cli.js" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@metaharness/flywheel": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@metaharness/flywheel/-/flywheel-0.1.7.tgz", - "integrity": "sha512-am7dROkjyS1Zkms3TOcn2LVHjwMLQXPJ6Pu1aP55q40vWJLRONGdGvnrcBL/VhMFqjQrVB57lmSn2E+s5CSZwA==", - "license": "MIT" - }, - "node_modules/@metaharness/harness": { + "node_modules/@metaharness/turn-credit": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@metaharness/harness/-/harness-0.1.0.tgz", - "integrity": "sha512-KegYx/q8qXlnaSYP0l5hgNPn8iNMl6a2eONqPi68FXd1w1jt7NswJJlt2/Ftl3Sum8qAEchxH1ZJOYFWTvJxTA==", + "resolved": "https://registry.npmjs.org/@metaharness/turn-credit/-/turn-credit-0.1.0.tgz", + "integrity": "sha512-A752c0eEYEVodBB8HLOaSvcUMA65TX6/Cru2apZ7EE7aL2FSO74GFbgFWPo85bgqgNuMjhHkl/kG+lkC0TunNA==", "license": "MIT", + "optional": true, "engines": { "node": ">=20.0.0" } }, - "node_modules/@metaharness/redblue": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@metaharness/redblue/-/redblue-0.1.4.tgz", - "integrity": "sha512-JaAk6bs3xA7Ks5RnAcZoxI3WfzpYL+Bk262SCI07w82BDOA7C6VxwGM63F7b86lRTKUVjTEnSqf7QZ3uyElT/g==", - "license": "MIT", - "bin": { - "metaharness-redblue": "dist/cli/index.js", - "redblue": "dist/cli/index.js" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@metaharness/router": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@metaharness/router/-/router-0.3.2.tgz", - "integrity": "sha512-LQElU6mUrWd3ffJ5bwoonEIgw7oFQZpwZaehffyl/Pg+iozpRjIBPEXdb4uTOBnKH+yPiTEWKc+h9AiZr9Os9w==", - "license": "MIT", - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "@ruvector/tiny-dancer": "^0.1.21" - }, - "peerDependenciesMeta": { - "@ruvector/tiny-dancer": { - "optional": true - } - } - }, "node_modules/@metaharness/weight-eft": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@metaharness/weight-eft/-/weight-eft-0.1.1.tgz", "integrity": "sha512-GSg0APPAbRK93OzrzlE+R8hfEK+I5+Zhmh0Z28RC9Mk5/MjhPo3shqINO7ye8VPGYHIO4rars9FwCWbe/V4cEQ==", "license": "MIT", + "optional": true, "bin": { "weight-eft": "dist/cli.js" }, @@ -2158,13 +2112,15 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/@metaharness/workspace-lens/-/workspace-lens-0.1.1.tgz", "integrity": "sha512-BkEdTvjD2PEhkGTCmtTIPnoeaOsxvzFtsFEAurwVKlVOu4hQetHeXDfiyAYheWg8Cp4fcGcr7E5MO1ptQveQ2g==", - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/@metaharness/workspace-probe": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@metaharness/workspace-probe/-/workspace-probe-0.1.1.tgz", "integrity": "sha512-kHL7T16476a5obVunbZ2NYqK7YY/1qtZTaQC1KyXmFh/7dRNselqGAilawspuD86F9U1H/LMCDvchDj3Vh5duw==", "license": "MIT", + "optional": true, "dependencies": { "@metaharness/workspace-lens": "^0.1.0" }, @@ -3801,10 +3757,6 @@ "resolved": "packages/spiking-neural", "link": true }, - "node_modules/@ruvector/tiny-dancer": { - "resolved": "packages/tiny-dancer", - "link": true - }, "node_modules/@ruvector/tiny-dancer-darwin-arm64": { "resolved": "packages/tiny-dancer-darwin-arm64", "link": true @@ -3817,58 +3769,10 @@ "resolved": "packages/tiny-dancer-linux-arm64-gnu", "link": true }, - "node_modules/@ruvector/tiny-dancer-linux-arm64-musl": { - "version": "0.1.22", - "resolved": "https://registry.npmjs.org/@ruvector/tiny-dancer-linux-arm64-musl/-/tiny-dancer-linux-arm64-musl-0.1.22.tgz", - "integrity": "sha512-zqgcpms7l8MILxhkd65BfV4BlTTnqRaxRp56P9Qo9SYF/OV6LTUcUIO3d8BA+rrCvltCoEnU7+x+mCSfm2XEmA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 18" - } - }, "node_modules/@ruvector/tiny-dancer-linux-x64-gnu": { "resolved": "packages/tiny-dancer-linux-x64-gnu", "link": true }, - "node_modules/@ruvector/tiny-dancer-linux-x64-musl": { - "version": "0.1.22", - "resolved": "https://registry.npmjs.org/@ruvector/tiny-dancer-linux-x64-musl/-/tiny-dancer-linux-x64-musl-0.1.22.tgz", - "integrity": "sha512-aPSL6dLv7dlq/sAWd2pE9jPu2QNPLz1RQH+btnCf6r0nSC5K5SoMSmiwnIGrVR0DTkXtHgBOTZvf5ne1O+gctA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 18" - } - }, - "node_modules/@ruvector/tiny-dancer-win32-arm64-msvc": { - "version": "0.1.22", - "resolved": "https://registry.npmjs.org/@ruvector/tiny-dancer-win32-arm64-msvc/-/tiny-dancer-win32-arm64-msvc-0.1.22.tgz", - "integrity": "sha512-fWOAlEQ/sF0Fs5vFjeMF5ktcOH4GPFwIJRNrdEbqv+jYnCHHHxNNoBY4UAwnfX8UqqyITSp+qnxcGw9+GeNXCw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 18" - } - }, "node_modules/@ruvector/tiny-dancer-win32-x64-msvc": { "resolved": "packages/tiny-dancer-win32-x64-msvc", "link": true @@ -10871,6 +10775,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -10880,7 +10785,8 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/kuler": { "version": "2.0.0", @@ -12984,6 +12890,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "devOptional": true, "license": "MIT", "dependencies": { "kleur": "^3.0.3", @@ -13990,6 +13897,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "devOptional": true, "license": "MIT" }, "node_modules/slash": { @@ -15515,6 +15423,7 @@ "os": [ "aix" ], + "peer": true, "engines": { "node": ">=18" } @@ -15532,6 +15441,7 @@ "os": [ "android" ], + "peer": true, "engines": { "node": ">=18" } @@ -15549,6 +15459,7 @@ "os": [ "android" ], + "peer": true, "engines": { "node": ">=18" } @@ -15566,6 +15477,7 @@ "os": [ "android" ], + "peer": true, "engines": { "node": ">=18" } @@ -15583,6 +15495,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": ">=18" } @@ -15600,6 +15513,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": ">=18" } @@ -15617,6 +15531,7 @@ "os": [ "freebsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -15634,6 +15549,7 @@ "os": [ "freebsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -15651,6 +15567,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -15668,6 +15585,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -15685,6 +15603,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -15702,6 +15621,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -15719,6 +15639,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -15736,6 +15657,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -15753,6 +15675,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -15770,6 +15693,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -15787,6 +15711,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -15804,6 +15729,7 @@ "os": [ "netbsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -15821,6 +15747,7 @@ "os": [ "netbsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -15838,6 +15765,7 @@ "os": [ "openbsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -15855,6 +15783,7 @@ "os": [ "openbsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -15872,6 +15801,7 @@ "os": [ "openharmony" ], + "peer": true, "engines": { "node": ">=18" } @@ -15889,6 +15819,7 @@ "os": [ "sunos" ], + "peer": true, "engines": { "node": ">=18" } @@ -15906,6 +15837,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">=18" } @@ -15923,6 +15855,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">=18" } @@ -15940,6 +15873,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">=18" } @@ -18146,9 +18080,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "os": [ "linux" @@ -18163,9 +18094,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "os": [ "linux" @@ -18462,14 +18390,6 @@ "version": "0.2.41", "license": "MIT", "dependencies": { - "@metaharness/darwin": "0.8.0", - "@metaharness/flywheel": "0.1.7", - "@metaharness/harness": "0.1.0", - "@metaharness/redblue": "0.1.4", - "@metaharness/router": "0.3.2", - "@metaharness/weight-eft": "0.1.1", - "@metaharness/workspace-lens": "0.1.1", - "@metaharness/workspace-probe": "0.1.1", "@modelcontextprotocol/sdk": "^1.30.0", "@ruvector/attention": "^0.1.3", "@ruvector/core": "^0.1.25", @@ -18477,7 +18397,6 @@ "@ruvector/sona": "^0.1.4", "chalk": "^4.1.2", "commander": "^11.1.0", - "metaharness": "0.4.2", "ora": "^5.4.1" }, "bin": { @@ -18491,16 +18410,58 @@ "node": ">=20.0.0" }, "optionalDependencies": { + "@metaharness/darwin": "^0.9.1", + "@metaharness/flywheel": "^0.1.10", + "@metaharness/harness": "^0.2.0", + "@metaharness/redblue": "^0.1.6", + "@metaharness/router": "^0.4.0", + "@metaharness/weight-eft": "^0.1.1", + "@metaharness/workspace-lens": "^0.1.2", + "@metaharness/workspace-probe": "^0.1.1", "@ruvector/rvf": "^0.1.0", - "@ruvector/tiny-dancer": "^0.1.22" + "@ruvector/tiny-dancer": "^0.1.22", + "metaharness": "^0.4.7" }, "peerDependencies": { + "@metaharness/darwin": ">=0.9.1", + "@metaharness/flywheel": ">=0.1.10", + "@metaharness/harness": ">=0.2.0", + "@metaharness/redblue": ">=0.1.6", + "@metaharness/router": ">=0.4.0", + "@metaharness/weight-eft": ">=0.1.1", + "@metaharness/workspace-lens": ">=0.1.2", + "@metaharness/workspace-probe": ">=0.1.1", "@ruvector/diskann": ">=0.1.0", "@ruvector/pi-brain": ">=0.1.0", "@ruvector/router": ">=0.1.0", - "@ruvector/ruvllm": ">=2.0.0" + "@ruvector/ruvllm": ">=2.0.0", + "metaharness": ">=0.4.7" }, "peerDependenciesMeta": { + "@metaharness/darwin": { + "optional": true + }, + "@metaharness/flywheel": { + "optional": true + }, + "@metaharness/harness": { + "optional": true + }, + "@metaharness/redblue": { + "optional": true + }, + "@metaharness/router": { + "optional": true + }, + "@metaharness/weight-eft": { + "optional": true + }, + "@metaharness/workspace-lens": { + "optional": true + }, + "@metaharness/workspace-probe": { + "optional": true + }, "@ruvector/diskann": { "optional": true }, @@ -18512,6 +18473,9 @@ }, "@ruvector/ruvllm": { "optional": true + }, + "metaharness": { + "optional": true } } }, @@ -18634,6 +18598,75 @@ "typescript": ">=5.0.0" } }, + "packages/ruvector/node_modules/@metaharness/darwin": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@metaharness/darwin/-/darwin-0.9.2.tgz", + "integrity": "sha512-UaAikvfaowvXO97ivNubXRdXEDbvBl28XCDbyTv979vbzPiOoHWdPpS3XPHq/D9VG+wCtK9BpS3PXm340EkYSQ==", + "license": "MIT", + "optional": true, + "bin": { + "metaharness-darwin": "dist/cli.js" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "packages/ruvector/node_modules/@metaharness/flywheel": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/@metaharness/flywheel/-/flywheel-0.1.10.tgz", + "integrity": "sha512-yrLXDXNdf4jKqHlW6QZw3Cy5T0eMMjjaPqn1XB717/Xx/y0Iv9R03W0OhMEiR/kfqMNebRBW1fi6D7inStEyqA==", + "license": "MIT", + "optional": true + }, + "packages/ruvector/node_modules/@metaharness/harness": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@metaharness/harness/-/harness-0.2.0.tgz", + "integrity": "sha512-j/NLHqgPNre4qTTExvjCjh4/HgmhnVZPSQUfj06dyrlkpXCMFJ2abdPrl5yuFfzBMU0wnfFnFY2qQHQnBlAreg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=20.0.0" + } + }, + "packages/ruvector/node_modules/@metaharness/redblue": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@metaharness/redblue/-/redblue-0.1.6.tgz", + "integrity": "sha512-cnQTOcPVetgz/XoYBdW5carkl48wBJsvBbJ7ntmelFtRu/8N5ARhSXnebEY+05SWaNm8lqij/gxZx2FqNCQWJg==", + "license": "MIT", + "optional": true, + "bin": { + "metaharness-redblue": "dist/cli/index.js", + "redblue": "dist/cli/index.js" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "packages/ruvector/node_modules/@metaharness/router": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@metaharness/router/-/router-0.4.0.tgz", + "integrity": "sha512-VOfjHM7AMWwDH41AAMHOHFbH1r898xJqhqyE3G/r8OAxxrMgujX2SZsYkj/eXfBEmoPMhDVRkuO2abxvzCgEUA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@ruvector/tiny-dancer": "^0.1.21" + }, + "peerDependenciesMeta": { + "@ruvector/tiny-dancer": { + "optional": true + } + } + }, + "packages/ruvector/node_modules/@metaharness/workspace-lens": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@metaharness/workspace-lens/-/workspace-lens-0.1.2.tgz", + "integrity": "sha512-Bfkj40rGZeBch4sQH/ma6zlY6dI+2AQfpTS/6AmPUE6/54H8Y04aBH5HPYfL0yBZ0lD/CeLViwFphT0PaiJ1mQ==", + "license": "MIT", + "optional": true + }, "packages/ruvector/node_modules/@ruvector/rvf": { "version": "0.1.9", "resolved": "https://registry.npmjs.org/@ruvector/rvf/-/rvf-0.1.9.tgz", @@ -18649,14 +18682,16 @@ } }, "packages/ruvector/node_modules/metaharness": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/metaharness/-/metaharness-0.4.2.tgz", - "integrity": "sha512-h94B47zBEuNEfKLFMZMV/fRnXBrkwV6L8kMukgioB/9621k6Lm6s2lR2gBKl3BAT1sfN/DYqhsqAJc+6H5PTGQ==", + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/metaharness/-/metaharness-0.4.7.tgz", + "integrity": "sha512-oRbzFPry3bu2gC6+QoLsTbZmzAeNKjjl0gDhxO5p4++azuop9HKWUmw3Urb+uPfCX1IhVsVvjABGQ1VIB3Fbkg==", "license": "MIT", + "optional": true, "dependencies": { - "@metaharness/darwin": "^0.2.2", + "@metaharness/darwin": "^0.9.1", "@metaharness/flywheel": "^0.1.1", - "@metaharness/redblue": "^0.1.1", + "@metaharness/redblue": "^0.1.6", + "@metaharness/turn-credit": "^0.1.0", "@metaharness/weight-eft": "^0.1.0", "kolorist": "^1.8.0", "prompts": "^2.4.2" @@ -18680,18 +18715,6 @@ } } }, - "packages/ruvector/node_modules/metaharness/node_modules/@metaharness/darwin": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@metaharness/darwin/-/darwin-0.2.8.tgz", - "integrity": "sha512-B8tF7IrrSxwKS6fEPEL6N2Juth9WWn+hppLUtUYPTJ2vcHzzZPIg2cS5T9qTyNNuANlTSWnQHnvzlfvYdGNfeQ==", - "license": "MIT", - "bin": { - "metaharness-darwin": "dist/cli.js" - }, - "engines": { - "node": ">=20.0.0" - } - }, "packages/ruvllm": { "name": "@ruvector/ruvllm", "version": "2.6.2", @@ -18769,9 +18792,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT OR Apache-2.0", "os": [ "linux" @@ -18786,9 +18806,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT OR Apache-2.0", "os": [ "linux" @@ -19279,6 +19296,7 @@ "packages/spiking-neural": { "name": "@ruvector/spiking-neural", "version": "1.0.3", + "hasInstallScript": true, "license": "MIT", "bin": { "snn": "bin/cli.js", @@ -19292,27 +19310,6 @@ "node": ">=16.0.0" } }, - "packages/tiny-dancer": { - "name": "@ruvector/tiny-dancer", - "version": "0.1.22", - "license": "MIT", - "devDependencies": { - "@napi-rs/cli": "^2.18.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "optionalDependencies": { - "@ruvector/tiny-dancer-darwin-arm64": "0.1.22", - "@ruvector/tiny-dancer-darwin-x64": "0.1.22", - "@ruvector/tiny-dancer-linux-arm64-gnu": "0.1.22", - "@ruvector/tiny-dancer-linux-arm64-musl": "0.1.22", - "@ruvector/tiny-dancer-linux-x64-gnu": "0.1.22", - "@ruvector/tiny-dancer-linux-x64-musl": "0.1.22", - "@ruvector/tiny-dancer-win32-arm64-msvc": "0.1.22", - "@ruvector/tiny-dancer-win32-x64-msvc": "0.1.22" - } - }, "packages/tiny-dancer-darwin-arm64": { "name": "@ruvector/tiny-dancer-darwin-arm64", "version": "0.1.22", @@ -19347,9 +19344,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "os": [ "linux" @@ -19364,9 +19358,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "os": [ "linux" diff --git a/npm/packages/ruvector/package.json b/npm/packages/ruvector/package.json index 1fc15dfb7..a26e973ba 100644 --- a/npm/packages/ruvector/package.json +++ b/npm/packages/ruvector/package.json @@ -12,7 +12,7 @@ "verify-dist": "node scripts/verify-dist.js", "prepack": "npm run build && npm run verify-dist", "prepublishOnly": "npm run build && npm run verify-dist", - "test": "node test/integration.js && node test/metaharness-sdk.js && node test/cli-commands.js && node test/metaharness-cli.js && node test/db-workflow.js && node test/mcp-stdio.js && node test/metaharness-mcp.js && node test/sigterm-cleanup.js && node test/mcp-policy.js && node test/mcp-command-security.js && node test/mcp-handshake.js && node test/startup-budget.js" + "test": "node test/integration.js && node test/metaharness-sdk.js && node test/metaharness-optional-deps.js && node test/cli-commands.js && node test/metaharness-cli.js && node test/db-workflow.js && node test/mcp-stdio.js && node test/metaharness-mcp.js && node test/sigterm-cleanup.js && node test/mcp-policy.js && node test/mcp-command-security.js && node test/mcp-handshake.js && node test/startup-budget.js" }, "keywords": [ "vector", @@ -71,14 +71,6 @@ "directory": "npm/packages/ruvector" }, "dependencies": { - "@metaharness/darwin": "0.8.0", - "@metaharness/flywheel": "0.1.7", - "@metaharness/harness": "0.1.0", - "@metaharness/redblue": "0.1.4", - "@metaharness/router": "0.3.2", - "@metaharness/weight-eft": "0.1.1", - "@metaharness/workspace-lens": "0.1.1", - "@metaharness/workspace-probe": "0.1.1", "@modelcontextprotocol/sdk": "^1.30.0", "@ruvector/attention": "^0.1.3", "@ruvector/core": "^0.1.25", @@ -86,12 +78,20 @@ "@ruvector/sona": "^0.1.4", "chalk": "^4.1.2", "commander": "^11.1.0", - "metaharness": "0.4.2", "ora": "^5.4.1" }, "optionalDependencies": { + "@metaharness/darwin": "^0.9.1", + "@metaharness/flywheel": "^0.1.10", + "@metaharness/harness": "^0.2.0", + "@metaharness/redblue": "^0.1.6", + "@metaharness/router": "^0.4.0", + "@metaharness/weight-eft": "^0.1.1", + "@metaharness/workspace-lens": "^0.1.2", + "@metaharness/workspace-probe": "^0.1.1", "@ruvector/rvf": "^0.1.0", - "@ruvector/tiny-dancer": "^0.1.22" + "@ruvector/tiny-dancer": "^0.1.22", + "metaharness": "^0.4.7" }, "devDependencies": { "@types/node": "^20.10.5", @@ -107,12 +107,48 @@ "LICENSE" ], "peerDependencies": { + "@metaharness/darwin": ">=0.9.1", + "@metaharness/flywheel": ">=0.1.10", + "@metaharness/harness": ">=0.2.0", + "@metaharness/redblue": ">=0.1.6", + "@metaharness/router": ">=0.4.0", + "@metaharness/weight-eft": ">=0.1.1", + "@metaharness/workspace-lens": ">=0.1.2", + "@metaharness/workspace-probe": ">=0.1.1", "@ruvector/diskann": ">=0.1.0", "@ruvector/pi-brain": ">=0.1.0", "@ruvector/router": ">=0.1.0", - "@ruvector/ruvllm": ">=2.0.0" + "@ruvector/ruvllm": ">=2.0.0", + "metaharness": ">=0.4.7" }, "peerDependenciesMeta": { + "@metaharness/darwin": { + "optional": true + }, + "@metaharness/flywheel": { + "optional": true + }, + "@metaharness/harness": { + "optional": true + }, + "@metaharness/redblue": { + "optional": true + }, + "@metaharness/router": { + "optional": true + }, + "@metaharness/weight-eft": { + "optional": true + }, + "@metaharness/workspace-lens": { + "optional": true + }, + "@metaharness/workspace-probe": { + "optional": true + }, + "metaharness": { + "optional": true + }, "@ruvector/pi-brain": { "optional": true }, diff --git a/npm/packages/ruvector/src/metaharness/index.ts b/npm/packages/ruvector/src/metaharness/index.ts index 1541a55f2..f9194799f 100644 --- a/npm/packages/ruvector/src/metaharness/index.ts +++ b/npm/packages/ruvector/src/metaharness/index.ts @@ -11,14 +11,14 @@ const nativeImport = new Function( ) as (specifier: string) => Promise>; export const METAHARNESS_VERSIONS = Object.freeze({ - metaharness: '0.4.2', - darwin: '0.8.0', - flywheel: '0.1.7', - harness: '0.1.0', - router: '0.3.2', - redblue: '0.1.4', + metaharness: '0.4.7', + darwin: '0.9.2', + flywheel: '0.1.10', + harness: '0.2.0', + router: '0.4.0', + redblue: '0.1.6', weightEft: '0.1.1', - workspaceLens: '0.1.1', + workspaceLens: '0.1.2', workspaceProbe: '0.1.1', }); @@ -73,7 +73,27 @@ const moduleCache = new Map>>(); function loadPackage(name: string): Promise> { let pending = moduleCache.get(name); if (!pending) { - pending = nativeImport(name); + pending = nativeImport(name).catch((error: any) => { + if (error?.code === 'ERR_MODULE_NOT_FOUND' || error?.code === 'MODULE_NOT_FOUND') { + // Per ruflo ADR-150 "MetaHarness Integration Surfaces" + // (ruflo/v3/docs/adr/ADR-150-metaharness-integration-surfaces.md, Implemented + // 2026-06-16; summarized locally in METAHARNESS-README.md): "@metaharness/* + // packages MUST appear in optionalDependencies or peerDependencies (optional), + // never in dependencies". ruvector must keep working without the MetaHarness + // stack, and callers of a MetaHarness-backed capability get a clear error + // naming the missing package. + moduleCache.delete(name); + const missing = new Error( + `Optional MetaHarness package "${name}" is not installed. ` + + `Run \`npm install ${name}\` to enable this capability; ` + + `ruvector itself works without it (ruflo ADR-150, see METAHARNESS-README.md).`, + ); + (missing as any).code = 'ERR_METAHARNESS_OPTIONAL_MISSING'; + (missing as any).cause = error; + throw missing; + } + throw error; + }); moduleCache.set(name, pending); } return pending; diff --git a/npm/packages/ruvector/test/metaharness-optional-deps.js b/npm/packages/ruvector/test/metaharness-optional-deps.js new file mode 100644 index 000000000..3b0b93014 --- /dev/null +++ b/npm/packages/ruvector/test/metaharness-optional-deps.js @@ -0,0 +1,112 @@ +#!/usr/bin/env node +/** + * ruflo ADR-150 compliance guard (MetaHarness Integration Surfaces). + * + * Rule 2 (verbatim): "@metaharness/* packages MUST appear in optionalDependencies + * or peerDependencies (optional), never in dependencies". + * Rule 4: the package must keep working on an --ignore-optional install path. + * + * Part (a) parses package.json and asserts the manifest shape. + * Part (b) simulates a MetaHarness-less install: the compiled bridge is copied to a + * scratch directory with no reachable node_modules, so every lazy import() fails the + * way it would after `npm install --ignore-optional`, and the bridge must degrade + * gracefully with a clear error naming the missing optional package. + */ + +const assert = require('assert'); +const fs = require('fs'); +const os = require('os'); +const path = require('path'); + +const META_PACKAGES = [ + 'metaharness', + '@metaharness/darwin', + '@metaharness/flywheel', + '@metaharness/harness', + '@metaharness/redblue', + '@metaharness/router', + '@metaharness/weight-eft', + '@metaharness/workspace-lens', + '@metaharness/workspace-probe', +]; + +function checkManifest() { + const manifestPath = path.join(__dirname, '..', 'package.json'); + const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')); + const dependencies = manifest.dependencies || {}; + const optionalDependencies = manifest.optionalDependencies || {}; + const peerDependencies = manifest.peerDependencies || {}; + const peerDependenciesMeta = manifest.peerDependenciesMeta || {}; + + for (const name of META_PACKAGES) { + assert.ok( + !(name in dependencies), + `${name} must never be a hard dependency (ruflo ADR-150 rule 2)`, + ); + const inOptional = name in optionalDependencies; + const inPeer = name in peerDependencies; + assert.ok( + inOptional || inPeer, + `${name} must be declared in optionalDependencies or peerDependencies (ruflo ADR-150 rule 2)`, + ); + if (inPeer) { + assert.strictEqual( + peerDependenciesMeta[name] && peerDependenciesMeta[name].optional, + true, + `${name} peer dependency must be marked optional in peerDependenciesMeta (ruflo ADR-150 rule 2)`, + ); + } + } + console.log(` PASS all ${META_PACKAGES.length} MetaHarness packages are optional-only in package.json`); +} + +async function checkAbsenceDegradation() { + const scratch = fs.mkdtempSync(path.join(os.tmpdir(), 'ruvector-adr150-')); + try { + // The bridge module is self-contained CJS; loading a copy from a directory with + // no node_modules on its resolution path makes every lazy import() fail exactly + // as it does on an --ignore-optional install. + const bridgeSource = path.join(__dirname, '..', 'dist', 'metaharness', 'index.js'); + const bridgeCopy = path.join(scratch, 'metaharness-bridge.js'); + fs.copyFileSync(bridgeSource, bridgeCopy); + const bridge = require(bridgeCopy); + + const capabilities = await bridge.getMetaHarnessCapabilities(); + assert.strictEqual(capabilities.length, META_PACKAGES.length); + assert.deepStrictEqual( + capabilities.filter((capability) => capability.available), + [], + 'no MetaHarness capability may report available when the packages are absent', + ); + console.log(' PASS getMetaHarnessCapabilities degrades to available:false without MetaHarness'); + + await assert.rejects( + () => + bridge.routeWithMetaHarness({ + rows: [{ embedding: [1, 0], scores: { cheap: 0.95 } }], + prices: { cheap: 1 }, + queryEmbedding: [1, 0], + }), + (error) => + error.code === 'ERR_METAHARNESS_OPTIONAL_MISSING' && + error.message.includes('@metaharness/router'), + 'a MetaHarness-backed call must fail with a clear error naming the missing optional package', + ); + console.log(' PASS missing-package calls throw ERR_METAHARNESS_OPTIONAL_MISSING naming the package'); + } finally { + fs.rmSync(scratch, { recursive: true, force: true }); + } +} + +async function main() { + console.log('\nruflo ADR-150 optional-dependency compliance guard'); + console.log('-'.repeat(50)); + checkManifest(); + await checkAbsenceDegradation(); + console.log('ADR-150 optional-dependency compliance checks passed'); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/adr-index.mjs b/scripts/adr-index.mjs new file mode 100644 index 000000000..bfcdb839f --- /dev/null +++ b/scripts/adr-index.mjs @@ -0,0 +1,410 @@ +#!/usr/bin/env node +/** + * adr-index.mjs — canonical ADR index generator + duplicate-number gate. + * + * Usage: + * node scripts/adr-index.mjs # regenerate docs/adr/INDEX.md + * node scripts/adr-index.mjs --check # exit 1 if a NEW duplicate ADR number + * # exists (one not in the frozen + * # historical list below); exit 0 otherwise + * node scripts/adr-index.mjs --self-test # build an adversarial fixture tree in a + * # temp dir (symlinks, hostile filenames) + * # and assert the script handles it safely + * + * Policy: see docs/adr/ADR-316-adr-numbering-hygiene.md. + * Duplicate numbers that existed before ADR-316 are FROZEN historical + * artifacts — they are never renamed, and are disambiguated in prose as + * "ADR-NNN (slug)". This script's --check mode is the CI gate that keeps + * the frozen list from growing. + * + * Security posture (Phase-4 review, PR #857): + * - Symlinks in docs/adr/ are NEVER followed (neither file nor directory + * symlinks) — they are skipped with a warning, so a committed symlink + * cannot exfiltrate content from outside the tree into INDEX.md. + * - Every visited entry is belt-and-braces asserted (via realpath) to + * resolve inside docs/adr/; anything that escapes is skipped. + * - Traversal is wrapped per-entry: broken symlinks, permission errors, + * and cycles produce a warning + skip, never a stack-trace abort, so + * the --check gate fails (or passes) cleanly on adversarial trees. + * - All filename-derived text (slug, rel) is escaped before being + * interpolated into INDEX.md, and link targets are URI-encoded. + * + * No dependencies beyond node >= 18 and git. + */ + +import { execFileSync, spawnSync } from 'node:child_process'; +import { + readdirSync, readFileSync, writeFileSync, realpathSync, + mkdirSync, mkdtempSync, rmSync, symlinkSync, copyFileSync, +} from 'node:fs'; +import { join, relative, dirname, basename, sep } from 'node:path'; +import { tmpdir } from 'node:os'; +import { fileURLToPath } from 'node:url'; + +const SCRIPT_PATH = fileURLToPath(import.meta.url); +const REPO_ROOT = join(dirname(SCRIPT_PATH), '..'); +const ADR_DIR = join(REPO_ROOT, 'docs', 'adr'); +const INDEX_PATH = join(ADR_DIR, 'INDEX.md'); + +/** + * FROZEN historical duplicate list (verified against origin/main, 2026-08-19, + * at the time ADR-316 was written). Key = plain ADR number (no namespace, + * no a/b sub-ADR suffix), value = number of files historically sharing it. + * Do NOT add entries here — new collisions must be renumbered before merge. + */ +const FROZEN_DUPLICATES = { + 272: 5, + 264: 3, 252: 3, 194: 3, 144: 3, + 268: 2, 266: 2, 260: 2, 258: 2, 256: 2, 254: 2, + 143: 2, 139: 2, 138: 2, 137: 2, 136: 2, 135: 2, + 134: 2, 133: 2, 132: 2, 117: 2, + 96: 2, 95: 2, 94: 2, 93: 2, 91: 2, 90: 2, +}; + +// Filename shapes handled: +// ADR-016-slug.md (plain, canonical counter) +// ADR-040a-slug.md (sub-ADR convention — distinct from ADR-040) +// ADR-DB-001-slug.md (namespaced family: DB, CE, QE, TTS, ...) +const FILE_RE = /^ADR-(?:([A-Z]{2,4})-)?(\d+)([a-z])?(?:[-_](.+?))?\.md$/; + +function warn(msg) { + console.error(`adr-index: warning: ${msg}`); +} + +/** + * Walk `dir` collecting .md files. Symlinks (file or directory) are NEVER + * followed — skipped with a warning. Every kept entry must realpath-resolve + * under `rootReal` (belt-and-braces against anything that still escapes). + * Unreadable/broken entries are skipped with a warning, never a throw. + */ +function walk(dir, rootReal, visited = new Set()) { + const out = []; + let dirReal; + try { + dirReal = realpathSync(dir); + } catch (err) { + warn(`cannot resolve directory ${dir}: ${err.message}`); + return out; + } + if (visited.has(dirReal)) { + warn(`directory cycle detected at ${dir} — skipping`); + return out; + } + visited.add(dirReal); + + let dirents; + try { + dirents = readdirSync(dir, { withFileTypes: true }); + } catch (err) { + warn(`cannot read directory ${dir}: ${err.message}`); + return out; + } + for (const dirent of dirents) { + const p = join(dir, dirent.name); + if (dirent.isSymbolicLink()) { + warn(`skipping symlink (not followed): ${p}`); + continue; + } + if (dirent.isDirectory()) { + out.push(...walk(p, rootReal, visited)); + continue; + } + if (!dirent.isFile() || !dirent.name.endsWith('.md')) continue; + try { + const real = realpathSync(p); + if (real !== rootReal && !real.startsWith(rootReal + sep)) { + warn(`skipping entry that resolves outside the ADR tree: ${p} -> ${real}`); + continue; + } + } catch (err) { + warn(`skipping unresolvable entry ${p}: ${err.message}`); + continue; + } + out.push(p); + } + return out; +} + +function parseTitle(content, fallback) { + const m = content.match(/^#\s+(.+?)\s*$/m); + return m ? m[1].trim() : fallback; +} + +function parseStatus(content) { + // Frontmatter: status: Accepted + let m = content.match(/^status:\s*(.+?)\s*$/im); + if (m && content.slice(0, 4) === '---\n') return m[1]; + // Inline: **Status**: Proposed / **Status:** Proposed / - Status: Proposed + m = content.match(/^[-*\s]*\*\*Status:?\*\*:?\s*(.+?)\s*$/im) || + content.match(/^[-*]\s*Status:\s*(.+?)\s*$/im); + if (m) return m[1].replace(/\*+/g, '').trim(); + // Section: ## Status \n + m = content.match(/^##\s*Status\s*\n+([^\n#]+)/im); + if (m) return m[1].trim(); + return ''; +} + +function gitDate(relPath, repoRoot) { + try { + const out = execFileSync( + 'git', ['log', '--follow', '-1', '--format=%ci', '--', relPath], + { cwd: repoRoot, encoding: 'utf8' }, + ).trim(); + return out ? out.slice(0, 10) : ''; + } catch { + return ''; + } +} + +function collect({ withDates, adrDir = ADR_DIR, repoRoot = REPO_ROOT }) { + let rootReal; + try { + rootReal = realpathSync(adrDir); + } catch (err) { + throw new Error(`ADR directory not found or unreadable: ${adrDir} (${err.message})`); + } + const entries = []; + for (const abs of walk(adrDir, rootReal)) { + // path.sep-safe (Windows included): basename + relative, normalized to '/'. + const rel = relative(repoRoot, abs).split(sep).join('/'); + const base = basename(abs); + if (base === 'README.md' || base === 'INDEX.md') continue; + const m = base.match(FILE_RE); + if (!m) continue; // non-ADR markdown (design notes etc.) + const [, ns, numStr, subSuffix, slug] = m; + const num = parseInt(numStr, 10); + let title = '', status = ''; + try { + const content = readFileSync(abs, 'utf8'); + title = parseTitle(content, slug ?? base); + status = parseStatus(content); + } catch { /* unreadable file — keep filename-derived fields */ } + entries.push({ + ns: ns ?? '', + num, + subSuffix: subSuffix ?? '', + slug: slug ?? '', + rel, + title, + status, + date: withDates ? gitDate(rel, repoRoot) : '', + // Duplicate-detection key. The a/b sub-ADR suffix makes a DISTINCT + // key on purpose: ADR-040 / ADR-040a / ADR-040b never collide. + key: `${ns ? ns + ':' : ''}${num}${subSuffix ?? ''}`, + }); + } + entries.sort((a, b) => + a.ns.localeCompare(b.ns) || a.num - b.num || + a.subSuffix.localeCompare(b.subSuffix) || a.rel.localeCompare(b.rel)); + return entries; +} + +function groupDuplicates(entries) { + const byKey = new Map(); + for (const e of entries) { + if (!byKey.has(e.key)) byKey.set(e.key, []); + byKey.get(e.key).push(e); + } + return byKey; +} + +function maxPlainNum(entries) { + // reduce, not Math.max(...): an empty set yields 0, not -Infinity. + return entries.filter(e => !e.ns).reduce((m, e) => Math.max(m, e.num), 0); +} + +function check() { + const entries = collect({ withDates: false }); + const byKey = groupDuplicates(entries); + const violations = []; + for (const [key, group] of byKey) { + if (group.length < 2) continue; + const e = group[0]; + const frozen = e.ns === '' && e.subSuffix === '' ? FROZEN_DUPLICATES[e.num] : undefined; + if (frozen === undefined) { + violations.push(`NEW duplicate ${key}: ${group.map(g => g.rel).join(', ')}`); + } else if (group.length > frozen) { + violations.push( + `Duplicate count for ADR-${e.num} grew: ${group.length} files ` + + `(frozen historical allowance is ${frozen}): ${group.map(g => g.rel).join(', ')}`); + } + } + if (violations.length > 0) { + console.error('ADR duplicate-number check FAILED:\n'); + for (const v of violations) console.error(` - ${v}`); + console.error('\nPick the next available number from docs/adr/INDEX.md ' + + '(regenerate with `node scripts/adr-index.mjs`). Never reuse a number.'); + process.exit(1); + } + const maxNum = maxPlainNum(entries); + console.log(`ADR duplicate-number check OK: ${entries.length} ADR files, ` + + `no duplicates outside the frozen historical list. Next available number: ${maxNum + 1}.`); +} + +// Escape text destined for a markdown table cell. +function mdCell(s) { + return String(s ?? '').replace(/\|/g, '\\|').replace(/\s+/g, ' ').trim(); +} + +// Escape text destined for markdown link text inside a table cell. +function mdLinkText(s) { + return mdCell(s).replace(/\[/g, '\\[').replace(/\]/g, '\\]'); +} + +// Encode a markdown link target: encodeURI, plus the characters that would +// terminate the link or the table cell but that encodeURI leaves alone. +function mdLinkTarget(s) { + return encodeURI(String(s ?? '')) + .replace(/\(/g, '%28') + .replace(/\)/g, '%29'); +} + +function formatRow(e, group) { + const numLabel = `ADR-${e.ns ? e.ns + '-' : ''}${String(e.num).padStart(3, '0')}${e.subSuffix}`; + const dup = group.length > 1 + ? `DUPLICATE ×${group.length} — cite as \`ADR-${e.num} (${mdCell(e.slug) || 'untitled'})\`` + : ''; + const shortRel = e.rel.replace('docs/adr/', ''); + const link = `[\`${mdLinkText(shortRel)}\`](${mdLinkTarget('./' + shortRel)})`; + return `| ${numLabel} | ${mdCell(e.title)} | ${link} | ${e.date} | ${mdCell(e.status).slice(0, 80)} | ${dup} |`; +} + +function generate() { + const entries = collect({ withDates: true }); + const byKey = groupDuplicates(entries); + const plain = entries.filter(e => !e.ns); + const maxNum = maxPlainNum(entries); + const next = maxNum + 1; + const dupKeys = [...byKey.values()].filter(g => g.length > 1); + const dupFileCount = dupKeys.reduce((n, g) => n + g.length, 0); + + const lines = []; + lines.push('# ADR Index'); + lines.push(''); + lines.push(`**Next available ADR number: ${next}**`); + lines.push(''); + lines.push('> Generated by `node scripts/adr-index.mjs` — do not edit by hand.'); + lines.push('> This file is the canonical allocation counter for new ADR numbers'); + lines.push('> (policy: `ADR-316`). Duplicate numbers listed below are frozen'); + lines.push('> historical artifacts and are cited as `ADR-NNN (slug)`.'); + lines.push('> CI gate: `node scripts/adr-index.mjs --check`.'); + lines.push(''); + lines.push(`- ADR files indexed: **${entries.length}** ` + + `(${plain.length} on the canonical counter, ${entries.length - plain.length} in namespaced families)`); + lines.push(`- Highest allocated number: **ADR-${maxNum}**`); + lines.push(`- Frozen duplicate numbers: **${dupKeys.length}** ` + + `(spanning ${dupFileCount} files)`); + lines.push(''); + lines.push('| Number | Title | File | Last commit | Status | Duplicate |'); + lines.push('|---|---|---|---|---|---|'); + for (const e of entries) { + lines.push(formatRow(e, byKey.get(e.key))); + } + lines.push(''); + writeFileSync(INDEX_PATH, lines.join('\n')); + console.log(`Wrote ${relative(REPO_ROOT, INDEX_PATH).split(sep).join('/')}: ${entries.length} entries, ` + + `${dupKeys.length} frozen duplicate numbers, next available ADR-${next}.`); +} + +/** + * --self-test: build an adversarial fixture tree in a temp dir, copy this + * script into it (REPO_ROOT derives from the script location, so the copy + * operates on the fixture), and assert: + * 1. a symlink pointing outside the tree is skipped — its content never + * reaches INDEX.md; + * 2. a hostile filename (|, [, ], (, )) is escaped in the generated table; + * 3. a tree containing broken symlinks and a symlink loop is traversed + * cleanly — --check exits 0 with warnings, no stack trace. + */ +function selfTest() { + const failures = []; + const ok = (cond, label) => { + if (cond) console.log(` PASS ${label}`); + else { console.error(` FAIL ${label}`); failures.push(label); } + }; + + const root = mkdtempSync(join(tmpdir(), 'adr-index-selftest-')); + try { + const adr = join(root, 'docs', 'adr'); + mkdirSync(adr, { recursive: true }); + mkdirSync(join(root, 'scripts'), { recursive: true }); + copyFileSync(SCRIPT_PATH, join(root, 'scripts', 'adr-index.mjs')); + + // Legit ADR. + writeFileSync(join(adr, 'ADR-001-real.md'), + '# Real decision\n\n**Status**: Accepted\n'); + // Hostile filename: pipes, brackets, parens in slug. + const hostile = 'ADR-090-beta|BROKEN](httpX) [pwn](httpY.md'; + writeFileSync(join(adr, hostile), '# Hostile | title\n\n**Status**: Evil|Status\n'); + // Secret outside the ADR tree + file symlink to it. + writeFileSync(join(root, 'outside-secret.txt'), + '# TOP SECRET DEPLOY KEY abc123\nstatus: leaked\n'); + symlinkSync(join(root, 'outside-secret.txt'), join(adr, 'ADR-500-exfil.md')); + // Directory symlink escaping the tree. + mkdirSync(join(root, 'outside-dir')); + writeFileSync(join(root, 'outside-dir', 'ADR-600-outside.md'), + '# OUTSIDE REPO SECRET\n'); + symlinkSync(join(root, 'outside-dir'), join(adr, 'vendor')); + // Broken symlink. + symlinkSync('/nonexistent/target.md', join(adr, 'ADR-502-broken.md')); + // Symlink loop. + symlinkSync('.', join(adr, 'loop')); + + const script = join(root, 'scripts', 'adr-index.mjs'); + const run = (args) => { + const r = spawnSync(process.execPath, [script, ...args], + { encoding: 'utf8', timeout: 30_000 }); + return { code: r.status ?? 1, stdout: r.stdout ?? '', stderr: r.stderr ?? '' }; + }; + + // --- 3. adversarial tree: --check exits cleanly, no stack trace --- + const chk = run(['--check']); + ok(chk.code === 0, '--check exits 0 on adversarial tree (no dupes present)'); + ok(chk.stdout.includes('check OK'), '--check prints its normal summary'); + ok(!(chk.stdout + chk.stderr).includes('at walk'), + 'no stack trace on broken symlink / symlink loop'); + ok(chk.stderr.includes('skipping symlink'), + 'symlinks produce a skip warning'); + + // --- 1 + 2. generate: symlinks skipped, hostile filename escaped --- + const gen = run([]); + ok(gen.code === 0, 'generate exits 0 on adversarial tree'); + const index = readFileSync(join(adr, 'INDEX.md'), 'utf8'); + ok(!index.includes('TOP SECRET'), + 'file symlink target content is NOT inlined into INDEX.md'); + ok(!index.includes('OUTSIDE REPO SECRET') && !index.includes('ADR-600'), + 'directory symlink is NOT followed'); + ok(!index.includes('ADR-500') && !index.includes('ADR-502'), + 'symlinked/broken entries are absent from the index'); + ok(index.includes('ADR-090'), 'hostile-named ADR is still indexed'); + const hostileRow = index.split('\n').find(l => l.includes('ADR-090')); + const unescapedPipes = hostileRow.replace(/\\\|/g, '').split('|').length - 1; + ok(unescapedPipes === 7, + 'hostile filename: table row has exactly 7 unescaped pipes (cells intact)'); + // The link target is the one that starts with './' (escaped `\](` + // sequences inside the link text would otherwise match first). + const target = hostileRow.match(/\]\((\.\/[^)]*)\)/)?.[1] ?? ''; + ok(target.startsWith('./ADR-090') && !/[ |[\]]/.test(target) + && !target.includes('('), + 'hostile filename: link target is URI-encoded (no raw space | [ ] ( )'); + ok(index.includes('Next available ADR number: 91'), + 'counter unaffected by symlinked ADR-500/600'); + } finally { + rmSync(root, { recursive: true, force: true }); + } + + if (failures.length > 0) { + console.error(`\nself-test FAILED: ${failures.length} assertion(s)`); + process.exit(1); + } + console.log('\nself-test OK: all assertions passed'); +} + +try { + if (process.argv.includes('--self-test')) selfTest(); + else if (process.argv.includes('--check')) check(); + else generate(); +} catch (err) { + console.error(`adr-index: fatal: ${err.message}`); + process.exit(1); +} diff --git a/scripts/workspace-check.mjs b/scripts/workspace-check.mjs new file mode 100644 index 000000000..4949fb27c --- /dev/null +++ b/scripts/workspace-check.mjs @@ -0,0 +1,168 @@ +#!/usr/bin/env node +/** + * workspace-check.mjs - Workspace-membership guard (PIR #859). + * + * Fails (exit 1) if any crates/⋆⋆/Cargo.toml is in the implicit-orphan state: + * neither a root workspace member, nor covered by the root `exclude` list, + * nor a workspace root of its own (or nested under one). Orphan crates are + * invisible to `cargo test --workspace` — their tests silently never run, + * which is how 12 crates accumulated before #859. + * + * The root workspace deliberately uses literal `members` entries (no + * `crates/*` glob): membership stays an explicit, reviewable decision, and + * this script is the backstop that makes silent orphaning impossible. + * + * Zero dependencies. Usage: + * node scripts/workspace-check.mjs + */ + +import { readFileSync, readdirSync, existsSync } from 'fs'; +import { join, resolve, relative, dirname, sep } from 'path'; + +const ROOT = resolve(import.meta.dirname, '..'); + +// --- Parse the root manifest's members/exclude arrays (tolerant, no TOML dep) --- + +function parseStringArray(toml, key) { + const m = toml.match(new RegExp(`^${key}\\s*=\\s*\\[`, 'm')); + if (!m) return []; + let i = m.index + m[0].length; + const out = []; + while (i < toml.length && toml[i] !== ']') { + const ch = toml[i]; + if (ch === '#') { + // comment: skip to end of line + while (i < toml.length && toml[i] !== '\n') i++; + } else if (ch === '"') { + const end = toml.indexOf('"', i + 1); + if (end === -1) throw new Error(`unterminated string in ${key}`); + out.push(toml.slice(i + 1, end)); + i = end + 1; + } else { + i++; + } + } + return out; +} + +const rootToml = readFileSync(join(ROOT, 'Cargo.toml'), 'utf8'); +const members = parseStringArray(rootToml, 'members'); +const excludes = parseStringArray(rootToml, 'exclude'); + +// --- Matching helpers --- + +// Cargo path globs: `*` matches a single path segment. +function globToRegex(pattern) { + const escaped = pattern + .split('*') + .map((part) => part.replace(/[.+^${}()|[\]\\?]/g, '\\$&')) + .join('[^/]+'); + return new RegExp(`^${escaped}$`); +} + +const memberMatchers = members.map(globToRegex); +const excludeMatchers = excludes.map(globToRegex); + +function isMember(rel) { + return memberMatchers.some((re) => re.test(rel)); +} + +// An excluded directory covers everything beneath it (cargo semantics: +// excluding a path removes it and its contents from workspace discovery). +function isExcluded(rel) { + return excludeMatchers.some((re) => { + if (re.test(rel)) return true; + const parts = rel.split('/'); + for (let n = 1; n < parts.length; n++) { + if (re.test(parts.slice(0, n).join('/'))) return true; + } + return false; + }); +} + +function hasOwnWorkspace(manifestPath) { + const toml = readFileSync(manifestPath, 'utf8'); + return /^\s*\[workspace([\].])/m.test(toml); +} + +// --- Walk crates/ for every Cargo.toml --- + +const SKIP_DIRS = new Set(['target', 'node_modules', '.git', 'pkg']); + +function findManifests(dir, acc) { + for (const entry of readdirSync(dir, { withFileTypes: true })) { + if (entry.isDirectory()) { + if (!SKIP_DIRS.has(entry.name)) findManifests(join(dir, entry.name), acc); + } else if (entry.name === 'Cargo.toml') { + acc.push(join(dir, entry.name)); + } + } + return acc; +} + +const manifests = findManifests(join(ROOT, 'crates'), []); + +// Directories (relative, /-separated) whose Cargo.toml declares [workspace]. +const workspaceRoots = new Set( + manifests + .filter(hasOwnWorkspace) + .map((p) => relative(ROOT, dirname(p)).split(sep).join('/')), +); + +function underOwnWorkspace(relDir) { + const parts = relDir.split('/'); + for (let n = 1; n <= parts.length; n++) { + if (workspaceRoots.has(parts.slice(0, n).join('/'))) return true; + } + return false; +} + +// --- Classify --- + +const orphans = []; +for (const manifest of manifests) { + const relDir = relative(ROOT, dirname(manifest)).split(sep).join('/'); + if (isMember(relDir)) continue; + if (isExcluded(relDir)) continue; + if (underOwnWorkspace(relDir)) continue; + orphans.push(relDir); +} + +// Sanity: stale members pointing at nothing are cargo's problem, but flag +// them here too since we already parsed the list. +const staleMembers = members.filter( + (m) => !m.includes('*') && !existsSync(join(ROOT, m, 'Cargo.toml')), +); + +if (orphans.length === 0 && staleMembers.length === 0) { + console.log( + `workspace-check: OK — ${manifests.length} manifests under crates/, ` + + `${members.length} members, ${excludes.length} excludes, 0 orphans.`, + ); + process.exit(0); +} + +if (orphans.length > 0) { + console.error( + `workspace-check: FAIL — ${orphans.length} orphan crate(s) under crates/ ` + + `(Cargo.toml present, but not a workspace member, not excluded, and not ` + + `its own workspace root):\n`, + ); + for (const o of orphans.sort()) console.error(` ${o}`); + console.error( + `\nFix: add each path to \`members\` in the root Cargo.toml (preferred — ` + + `its tests then run in CI), or to \`exclude\` with a comment stating why ` + + `(see #859).`, + ); +} + +if (staleMembers.length > 0) { + console.error( + `workspace-check: FAIL — ${staleMembers.length} member entr${ + staleMembers.length === 1 ? 'y' : 'ies' + } with no Cargo.toml on disk:\n`, + ); + for (const s of staleMembers.sort()) console.error(` ${s}`); +} + +process.exit(1);