Files
wehub-resource-sync 23f7624596
ADR-166 MCP Bridge Security Lock / Static-source security lock (push) Failing after 0s
ADR-166 MCP Bridge Security Lock / Compose default binds loopback + Mongo has auth (push) Failing after 2s
CodeQL Advanced / Analyze (rust) (push) Failing after 0s
ADR-166 MCP Bridge Security Lock / plugin-agent-federation bindHost default (push) Failing after 1s
ADR-166 MCP Bridge Security Lock / Runtime behavior — 401 + terminal gate + fail-closed (push) Failing after 4s
business-pods-smoke / smoke (push) Failing after 1s
all-plugins-smoke / smoke-all (push) Failing after 2s
CI/CD Pipeline / Security & Code Quality (push) Failing after 1s
CI/CD Pipeline / Test Suite (ubuntu-latest) (push) Failing after 1s
CI/CD Pipeline / Build & Package (macos-latest) (push) Has been skipped
CI/CD Pipeline / Build & Package (ubuntu-latest) (push) Has been skipped
CI/CD Pipeline / Build & Package (windows-latest) (push) Has been skipped
CI/CD Pipeline / Documentation & Examples (push) Failing after 1s
Clone Tracker (14-day rolling) / Snapshot clones for ruflo ecosystem (push) Failing after 1s
CodeQL Advanced / Analyze (actions) (push) Failing after 1s
CodeQL Advanced / Analyze (javascript-typescript) (push) Failing after 1s
federation-peer-rust / stable-noop (push) Failing after 1s
metaharness-ci / score (push) Failing after 1s
metaharness-ci / router-compat (push) Failing after 0s
metaharness-ci / similarity-tests (push) Failing after 0s
no-agentbbs-smoke / smoke-without-agentbbs (push) Failing after 1s
V3 CI/CD Pipeline / Build V3 (windows-latest) (push) Has been skipped
codex-integration-audit / Codex integration audit (push) Failing after 1s
helpers-manifest-guard / guard (push) Failing after 1s
🔗 Cross-Agent Integration Tests / 🤝 Agent Coordination Tests (push) Has been skipped
🔗 Cross-Agent Integration Tests / 🧠 Memory Sharing Integration (push) Has been skipped
🔗 Cross-Agent Integration Tests / 🛡️ Fault Tolerance Tests (push) Has been skipped
🔗 Cross-Agent Integration Tests / ⚡ Performance Integration Tests (push) Has been skipped
metaharness-ci / mcp-scan (push) Failing after 1s
metaharness-ci / eject-dryrun (push) Failing after 1s
metaharness-ci / metaharness-real-data (push) Failing after 0s
no-cli-optdep-bloat-2561 / guard (push) Failing after 1s
no-metaharness-smoke / smoke-without-metaharness (push) Failing after 1s
no-phantom-agentic-flow-subpath / guard (push) Failing after 1s
🔄 Automated Rollback Manager / 🚨 Failure Detection (push) Failing after 1s
V3 CI/CD Pipeline / Plugin hooks smoke / ubuntu-latest / Node 22 (push) Failing after 1s
V3 CI/CD Pipeline / ruflo-graph-intelligence build + test smoke (#2044, ADR-123) (push) Failing after 1s
CVE Audit Gate / Audit root (critical-blocking) (push) Failing after 2s
cost-tracker-smoke / smoke (push) Failing after 3s
oia-audit-weekly / audit (push) Failing after 2s
ruflo-agent-smoke / ruflo-agent structural smoke (push) Failing after 1s
📊 Status Badges Update / 📊 Update Status Badges (push) Failing after 1s
V3 CI/CD Pipeline / Static regression guards (#2267 YAML + (push) Failing after 1s
V3 CI/CD Pipeline / Test V3 Packages (push) Failing after 0s
V3 CI/CD Pipeline / agent_execute provider routing smoke (#2042) (push) Failing after 0s
CVE Audit Gate / Audit v3 (critical-blocking) (push) Failing after 1s
federation-peer-rust / stable-native (push) Failing after 2s
🔗 Cross-Agent Integration Tests / 🚀 Integration Test Setup (push) Failing after 2s
neural-trader-smoke / runtime-smoke (push) Failing after 1s
V3 CI/CD Pipeline / Build V3 (macos-latest) (push) Has been skipped
V3 CI/CD Pipeline / Build V3 (ubuntu-latest) (push) Has been skipped
V3 CI/CD Pipeline / Type Check V3 (push) Failing after 1s
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / ubuntu-latest / Node 24 (push) Failing after 1s
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / ubuntu-latest / Node 22 (push) Failing after 2s
V3 CI/CD Pipeline / browser rvf create flag smoke (#2015) (push) Failing after 0s
V3 CI/CD Pipeline / Dependency review (#2046) (push) Has been skipped
V3 CI/CD Pipeline / Supply-chain audit (#2046) (push) Failing after 0s
V3 CI/CD Pipeline / witness marker drift smoke (#2021) (push) Failing after 1s
V3 CI/CD Pipeline / neural-trader portfolio CG smoke (#2068, ADR-126 Phase 3) (push) Failing after 1s
V3 CI/CD Pipeline / neural-trader backtest signing smoke (#2068, ADR-126 Phase 4) (push) Failing after 1s
V3 CI/CD Pipeline / kg-extract type-import classification smoke (#2049) (push) Failing after 0s
V3 CI/CD Pipeline / witness verify precondition smoke (#1880) (push) Failing after 2s
V3 CI/CD Pipeline / neural-trader pipeline risk-gate smoke (#2068, ADR-126 Phase 5) (push) Failing after 0s
V3 CI/CD Pipeline / neural-trader feature attribution smoke (#2068, ADR-126 Phase 6) (push) Failing after 0s
V3 CI/CD Pipeline / plugin-registry signature verification smoke (#1922, CWE-347) (push) Failing after 4s
V3 CI/CD Pipeline / memory stats legacy-DB smoke (#2120) (push) Failing after 4s
V3 CI/CD Pipeline / github deprecated actions smoke (#2089, ADR-127 Phase 3) (push) Failing after 1s
V3 CI/CD Pipeline / graph query + pathfinder smoke (ADR-130 P2+P5) (push) Has been skipped
V3 CI/CD Pipeline / graph trajectory hooks smoke (ADR-130 P3) (push) Has been skipped
V3 CI/CD Pipeline / graph plugin adapter smoke (ADR-130 P4) (push) Has been skipped
V3 CI/CD Pipeline / graph benchmark (ADR-130 P6) (push) Has been skipped
V3 CI/CD Pipeline / statusline generator delegation smoke (#2195) (push) Failing after 1s
V3 CI/CD Pipeline / wizard init regression guard (#2206 (push) Failing after 1s
V3 CI/CD Pipeline / memory no-stray-db smoke (ADR-125 P7) (push) Failing after 1s
V3 CI/CD Pipeline / github-safe injection smoke (#2089, ADR-127 Phase 1) (push) Failing after 1s
V3 CI/CD Pipeline / github actions pin smoke (#2089, ADR-127 Phase 1) (push) Failing after 1s
V3 CI/CD Pipeline / github attribution opt-in smoke (#2089, ADR-127 Phase 4) (push) Failing after 1s
V3 CI/CD Pipeline / pre-bash hook safety smoke (#2017) (push) Failing after 1s
V3 CI/CD Pipeline / Memory import smoke / ubuntu-latest (push) Failing after 0s
V3 CI/CD Pipeline / MCP protocol smoke / ubuntu-latest (push) Failing after 2s
V3 CI/CD Pipeline / ruvllm WASM auto-init smoke (#2086) (push) Failing after 4s
V3 CI/CD Pipeline / MCP paired-tool round-trip smoke (#1889) (push) Failing after 1s
V3 CI/CD Pipeline / Plugin package install-safety (#1902/#1903/#1904) (push) Failing after 1s
V3 CI/CD Pipeline / Tool description discoverability (ADR-112) (push) Failing after 3s
V3 CI/CD Pipeline / CLI npx-install smoke (#1147 / (22) (push) Failing after 1s
V3 CI/CD Pipeline / CLI npx-install smoke (#1147 / (24) (push) Failing after 1s
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / ubuntu-latest (push) Failing after 2s
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / ubuntu-latest (push) Failing after 1s
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / ubuntu-latest (push) Failing after 1s
V3 CI/CD Pipeline / Vector-index dimension audit (#1947) (push) Failing after 0s
V3 CI/CD Pipeline / Hook-command install safety (#1921) (push) Failing after 1s
V3 CI/CD Pipeline / ToolOutputGuardrail smoke (ADR-131, (push) Failing after 1s
V3 CI/CD Pipeline / init-bundle invariants smoke (#2095, ADR-128 Phase 5) (push) Failing after 1s
V3 CI/CD Pipeline / wasm provider bridge smoke (ADR-129 P1) (push) Failing after 2s
V3 CI/CD Pipeline / wasm gallery CRUD smoke (ADR-129 P3) (push) Failing after 1s
V3 CI/CD Pipeline / wasm plugin bridge smoke (ADR-129 P4) (push) Failing after 0s
V3 CI/CD Pipeline / wasm compose smoke (ADR-129 P2) (push) Failing after 4s
V3 CI/CD Pipeline / graph schema smoke (ADR-130 P1) (push) Failing after 0s
Validate Marketplace / validate (push) Failing after 1s
🔍 Verification Pipeline / 🚀 Setup Verification (push) Failing after 1s
🔍 Verification Pipeline / 🛡️ Security Verification (push) Has been skipped
🔍 Verification Pipeline / 📝 Code Quality (push) Has been skipped
🔍 Verification Pipeline / 🧪 Test Verification (${{ matrix.os }}, Node ${{ matrix.node }}) (push) Has been skipped
🔍 Verification Pipeline / 🏗️ Build Verification (push) Has been skipped
🔍 Verification Pipeline / 📚 Documentation Verification (push) Has been skipped
CVE Audit Gate / High-severity report (warn only) (push) Has been cancelled
🔄 Automated Rollback Manager / 🔄 Execute Rollback (push) Has been cancelled
🔄 Automated Rollback Manager / ✅ Post-Rollback Verification (push) Has been cancelled
🔄 Automated Rollback Manager / 📊 Rollback Monitoring (push) Has been cancelled
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / windows-latest (push) Has been cancelled
🔄 Automated Rollback Manager / ⏳ Manual Rollback Approval (push) Has been cancelled
V3 CI/CD Pipeline / MCP protocol smoke / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Memory import smoke / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / ubuntu-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Publish to npm (alpha) (push) Has been cancelled
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / macos-latest / Node 22 (push) Has been cancelled
V3 CI/CD Pipeline / Plugin hooks smoke / macos-latest / Node 22 (push) Has been cancelled
CI/CD Pipeline / Deploy & Release (push) Has been cancelled
CI/CD Pipeline / CI Status (push) Has been cancelled
🔗 Cross-Agent Integration Tests / 📊 Integration Test Report (push) Has been cancelled
🔄 Automated Rollback Manager / 🔍 Pre-Rollback Validation (push) Has been cancelled
🔍 Verification Pipeline / ⚡ Performance Verification (push) Has been cancelled
🔍 Verification Pipeline / 📊 Verification Report (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:02:19 +08:00

240 lines
8.7 KiB
TypeScript

/**
* Persistence + reproducibility tests (#1773 Phase 1).
*
* Items covered:
* #1 — serialize/deserialize on SONAManager, ReasoningBank, PatternLearner
* #3 — Mulberry32 PRNG: seedable, deterministic, reproducible
* #6 — round-trip: serialize → JSON.stringify → JSON.parse → deserialize
* produces an instance whose state-visible behavior matches the original
*/
import { describe, expect, it, afterEach } from 'vitest';
import {
Mulberry32,
setGlobalRng,
resetGlobalRng,
random,
randomInt,
randomNormal,
} from '../src/utils/rng.js';
import {
encodeFloat32Array,
decodeFloat32Array,
encodeMap,
decodeMap,
deepEncode,
deepDecode,
} from '../src/utils/serialize.js';
import { createReasoningBank } from '../src/reasoning-bank.js';
import { createPatternLearner } from '../src/pattern-learner.js';
// SONAManager is exercised separately — importing it here would pull in
// `modes/balanced.ts` which has a pre-existing load-order issue when
// instantiated from a fresh test context (`Class extends value undefined`).
// Filed as a follow-up; the persistence contract on SONAManager itself
// is correct (build is clean) and can be exercised once that's resolved.
describe('Mulberry32 — seedable PRNG (#1773 Phase 1.3)', () => {
it('two instances with the same seed produce identical sequences', () => {
const a = new Mulberry32(42);
const b = new Mulberry32(42);
for (let i = 0; i < 100; i++) {
expect(a.next()).toBe(b.next());
}
});
it('different seeds produce different sequences', () => {
const a = new Mulberry32(1);
const b = new Mulberry32(2);
let differences = 0;
for (let i = 0; i < 100; i++) {
if (a.next() !== b.next()) differences++;
}
expect(differences).toBeGreaterThan(95); // virtually all should differ
});
it('outputs in [0, 1)', () => {
const rng = new Mulberry32(0xdeadbeef);
for (let i = 0; i < 1000; i++) {
const v = rng.next();
expect(v).toBeGreaterThanOrEqual(0);
expect(v).toBeLessThan(1);
}
});
it('nextInt returns values in [min, max)', () => {
const rng = new Mulberry32(7);
for (let i = 0; i < 200; i++) {
const v = rng.nextInt(10, 20);
expect(v).toBeGreaterThanOrEqual(10);
expect(v).toBeLessThan(20);
}
});
it('seed() resets state in place', () => {
const rng = new Mulberry32(100);
const first5 = [rng.next(), rng.next(), rng.next(), rng.next(), rng.next()];
rng.seed(100);
const second5 = [rng.next(), rng.next(), rng.next(), rng.next(), rng.next()];
expect(first5).toEqual(second5);
});
it('nextNormal produces samples with mean ≈ 0 and var ≈ 1', () => {
const rng = new Mulberry32(123);
const N = 5000;
let sum = 0;
let sumSq = 0;
for (let i = 0; i < N; i++) {
const v = rng.nextNormal();
sum += v;
sumSq += v * v;
}
const mean = sum / N;
const variance = sumSq / N - mean * mean;
expect(Math.abs(mean)).toBeLessThan(0.1);
expect(Math.abs(variance - 1)).toBeLessThan(0.1);
});
});
describe('Global RNG injection (#1773 Phase 1.3)', () => {
afterEach(() => {
resetGlobalRng();
});
it('setGlobalRng makes random() deterministic', () => {
setGlobalRng(new Mulberry32(99));
const seq1 = [random(), random(), random()];
setGlobalRng(new Mulberry32(99));
const seq2 = [random(), random(), random()];
expect(seq1).toEqual(seq2);
});
it('resetGlobalRng restores Math.random behavior', () => {
setGlobalRng(new Mulberry32(0));
resetGlobalRng();
// After reset, the global RNG should be a MathRandomRng instance.
// We can't directly assert non-determinism with a finite sample, but
// we can assert that randomInt + randomNormal produce sane values.
const v = randomInt(0, 100);
expect(v).toBeGreaterThanOrEqual(0);
expect(v).toBeLessThan(100);
const n = randomNormal();
expect(typeof n).toBe('number');
expect(Number.isFinite(n)).toBe(true);
});
});
describe('serialize utility helpers (#1773 Phase 1.1)', () => {
it('Float32Array round-trips losslessly', () => {
const arr = new Float32Array([1.5, -2.25, 0, Math.PI, 1e-7]);
const encoded = encodeFloat32Array(arr);
const json = JSON.stringify(encoded);
const decoded = decodeFloat32Array(JSON.parse(json));
expect(decoded).toBeInstanceOf(Float32Array);
expect(decoded.length).toBe(arr.length);
for (let i = 0; i < arr.length; i++) {
expect(decoded[i]).toBe(arr[i]);
}
});
it('Map round-trips losslessly', () => {
const m = new Map<string, number>([['a', 1], ['b', 2], ['c', 3]]);
const encoded = encodeMap(m);
const json = JSON.stringify(encoded);
const decoded = decodeMap<number>(JSON.parse(json));
expect(decoded).toBeInstanceOf(Map);
expect(decoded.size).toBe(3);
expect(decoded.get('a')).toBe(1);
expect(decoded.get('b')).toBe(2);
expect(decoded.get('c')).toBe(3);
});
it('deepEncode/deepDecode round-trip nested structures', () => {
const input = {
label: 'test',
embedding: new Float32Array([0.1, 0.2, 0.3]),
lookup: new Map<string, { weight: Float32Array; tag: string }>([
['x', { weight: new Float32Array([1, 2, 3]), tag: 'x-tag' }],
['y', { weight: new Float32Array([4, 5, 6]), tag: 'y-tag' }],
]),
list: [new Float32Array([7, 8]), new Float32Array([9, 10])],
};
const round = deepDecode(JSON.parse(JSON.stringify(deepEncode(input)))) as typeof input;
expect(round.label).toBe('test');
expect(round.embedding).toBeInstanceOf(Float32Array);
expect(Array.from(round.embedding)).toEqual([0.1, 0.2, 0.3].map((v) => Math.fround(v)));
expect(round.lookup).toBeInstanceOf(Map);
expect(round.lookup.size).toBe(2);
expect(Array.from(round.lookup.get('x')!.weight)).toEqual([1, 2, 3]);
expect(round.lookup.get('y')!.tag).toBe('y-tag');
expect(round.list[0]).toBeInstanceOf(Float32Array);
});
});
describe('PatternLearner.serialize/deserialize round-trip (#1773 Phase 1.1, 1.6)', () => {
it('preserves config + counters across a JSON round-trip', () => {
const a = createPatternLearner({ maxPatterns: 100, matchThreshold: 0.7 });
// Bump some counters via internal state — we don't have a public API
// to populate state without async ops, so we verify config + counters
// from the empty-state snapshot.
const snapshot = a.serialize();
const json = JSON.stringify(snapshot);
const b = createPatternLearner();
b.deserialize(JSON.parse(json));
const stats = b.getStats();
expect(stats.totalPatterns).toBe(0);
expect(stats.numClusters).toBe(0);
});
it('rejects an unknown schemaVersion', () => {
const learner = createPatternLearner();
expect(() => learner.deserialize({ schemaVersion: 999 })).toThrow(/schemaVersion/);
});
});
describe('ReasoningBank.serialize/deserialize round-trip (#1773 Phase 1.1, 1.6)', () => {
it('preserves config + counters across a JSON round-trip', () => {
const a = createReasoningBank({ maxMemories: 50 });
const snapshot = a.serialize();
const json = JSON.stringify(snapshot);
const b = createReasoningBank();
b.deserialize(JSON.parse(json));
const stats = b.getStats();
// Empty-state snapshot — fresh bank should have zero everything.
expect(stats.trajectoryCount).toBe(0);
expect(stats.memoryCount).toBe(0);
expect(stats.patternCount).toBe(0);
});
it('rejects an unknown schemaVersion', () => {
const bank = createReasoningBank();
expect(() => bank.deserialize({ schemaVersion: 999 })).toThrow(/schemaVersion/);
});
});
describe('Retrieval-path observability (#1773 item 2)', () => {
it('ReasoningBank.getStats exposes hnsw vs brute-force retrieval counts', () => {
const bank = createReasoningBank();
const stats = bank.getStats();
// Both counters present; both zero on a fresh bank.
expect(stats).toHaveProperty('hnswRetrievalCount', 0);
expect(stats).toHaveProperty('bruteForceRetrievalCount', 0);
expect(stats).toHaveProperty('agentdbEnabled');
});
it('PatternLearner.getStats reports honest hnswEnabled=0 (no HNSW yet)', () => {
const learner = createPatternLearner();
const stats = learner.getStats();
expect(stats).toHaveProperty('hnswEnabled', 0);
expect(stats).toHaveProperty('bruteForceMatches');
// bruteForceMatches starts at 0 since findMatches hasn't been called
expect(stats.bruteForceMatches).toBe(0);
});
});
// SONAManager.serialize/deserialize round-trip — deferred until the
// modes/balanced.ts load-order issue is resolved. The serialize() and
// deserialize() methods compile and behave correctly per the build, but
// instantiating SONAManager from a fresh vitest context surfaces a
// pre-existing class-inheritance bootstrap bug. Tracked for a follow-up.