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
368 lines
12 KiB
TypeScript
368 lines
12 KiB
TypeScript
/**
|
|
* WASM Kernel Acceptance Tests
|
|
*
|
|
* Verifies:
|
|
* 1. Output parity: JS and WASM produce identical results
|
|
* 2. Determinism: Same input → same output across runs
|
|
* 3. Performance: WASM vs JS throughput comparison
|
|
* 4. Batch API: Single call processes multiple operations
|
|
* 5. Secret scanning: Identical detection and redaction
|
|
* 6. Destructive command detection: Identical pattern matching
|
|
*
|
|
* Acceptance criteria from production analysis:
|
|
* - 10,000 synthetic events processed
|
|
* - p50 and p99 latency measured
|
|
* - Identical proof root hash across JS and WASM
|
|
*/
|
|
|
|
import { describe, it, expect, beforeAll } from 'vitest';
|
|
import { createHash, createHmac } from 'node:crypto';
|
|
import { resolve, dirname } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
// ============================================================================
|
|
// Load WASM module directly (bypass the bridge to test raw kernel)
|
|
// ============================================================================
|
|
|
|
let wasm: {
|
|
kernel_init: () => string;
|
|
sha256: (input: string) => string;
|
|
hmac_sha256: (key: string, input: string) => string;
|
|
content_hash: (json_input: string) => string;
|
|
sign_envelope: (key: string, envelope_json: string) => string;
|
|
verify_chain: (chain_json: string, key: string) => boolean;
|
|
scan_secrets: (content: string) => string;
|
|
detect_destructive: (command: string) => string;
|
|
batch_process: (ops_json: string) => string;
|
|
} | null = null;
|
|
|
|
let wasmAvailable = false;
|
|
|
|
beforeAll(async () => {
|
|
try {
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
const wasmPath = resolve(__dirname, '../wasm-pkg/guidance_kernel.js');
|
|
const mod = await import(wasmPath);
|
|
wasm = mod;
|
|
wasmAvailable = true;
|
|
} catch {
|
|
// WASM not available — tests will be skipped
|
|
wasmAvailable = false;
|
|
}
|
|
});
|
|
|
|
// ============================================================================
|
|
// JS reference implementations (identical to what ProofChain/Gates use)
|
|
// ============================================================================
|
|
|
|
function jsSha256(input: string): string {
|
|
return createHash('sha256').update(input).digest('hex');
|
|
}
|
|
|
|
function jsHmacSha256(key: string, input: string): string {
|
|
return createHmac('sha256', key).update(input).digest('hex');
|
|
}
|
|
|
|
function jsContentHash(jsonInput: string): string {
|
|
try {
|
|
const parsed = JSON.parse(jsonInput);
|
|
const sorted = sortKeys(parsed);
|
|
return jsSha256(JSON.stringify(sorted));
|
|
} catch {
|
|
return jsSha256(jsonInput);
|
|
}
|
|
}
|
|
|
|
function sortKeys(value: unknown): unknown {
|
|
if (value === null || typeof value !== 'object') return value;
|
|
if (Array.isArray(value)) return value.map(sortKeys);
|
|
const sorted: Record<string, unknown> = {};
|
|
for (const key of Object.keys(value as Record<string, unknown>).sort()) {
|
|
sorted[key] = sortKeys((value as Record<string, unknown>)[key]);
|
|
}
|
|
return sorted;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Parity Tests — JS and WASM must produce identical outputs
|
|
// ============================================================================
|
|
|
|
describe('WASM Kernel: Output Parity', () => {
|
|
it('sha256 — identical hashes', () => {
|
|
if (!wasm) return;
|
|
const inputs = [
|
|
'hello world',
|
|
'',
|
|
'a'.repeat(10000),
|
|
JSON.stringify({ key: 'value', nested: { a: 1 } }),
|
|
'🔐 unicode content with emoji',
|
|
];
|
|
|
|
for (const input of inputs) {
|
|
const jsResult = jsSha256(input);
|
|
const wasmResult = wasm.sha256(input);
|
|
expect(wasmResult).toBe(jsResult);
|
|
}
|
|
});
|
|
|
|
it('hmac_sha256 — identical signatures', () => {
|
|
if (!wasm) return;
|
|
const testCases = [
|
|
{ key: 'secret-key', input: 'message body' },
|
|
{ key: 'claude-flow-guidance-default-key', input: '{"envelopeId":"test"}' },
|
|
{ key: '', input: '' },
|
|
{ key: 'k'.repeat(100), input: 'i'.repeat(10000) },
|
|
];
|
|
|
|
for (const { key, input } of testCases) {
|
|
const jsResult = jsHmacSha256(key, input);
|
|
const wasmResult = wasm.hmac_sha256(key, input);
|
|
expect(wasmResult).toBe(jsResult);
|
|
}
|
|
});
|
|
|
|
it('content_hash — key-order independent, identical across implementations', () => {
|
|
if (!wasm) return;
|
|
const pairs = [
|
|
['{"a":1,"b":2}', '{"b":2,"a":1}'],
|
|
['{"z":{"y":1,"x":2},"a":3}', '{"a":3,"z":{"x":2,"y":1}}'],
|
|
['[1,2,3]', '[1,2,3]'],
|
|
['{"nested":{"deep":{"value":42}}}', '{"nested":{"deep":{"value":42}}}'],
|
|
];
|
|
|
|
for (const [a, b] of pairs) {
|
|
const wasmA = wasm.content_hash(a);
|
|
const wasmB = wasm.content_hash(b);
|
|
expect(wasmA).toBe(wasmB);
|
|
|
|
// Also verify against JS
|
|
const jsA = jsContentHash(a);
|
|
expect(wasmA).toBe(jsA);
|
|
}
|
|
});
|
|
});
|
|
|
|
// ============================================================================
|
|
// Secret Scanning Parity
|
|
// ============================================================================
|
|
|
|
describe('WASM Kernel: Secret Scanning', () => {
|
|
it('detects API keys', () => {
|
|
if (!wasm) return;
|
|
const content = 'api_key = "sk-abcdefghij1234567890"';
|
|
const result = JSON.parse(wasm.scan_secrets(content));
|
|
expect(result.length).toBeGreaterThan(0);
|
|
expect(result[0]).toContain('****');
|
|
});
|
|
|
|
it('detects private keys', () => {
|
|
if (!wasm) return;
|
|
const content = '-----BEGIN RSA PRIVATE KEY-----\nMIIE...';
|
|
const result = JSON.parse(wasm.scan_secrets(content));
|
|
expect(result.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('detects AWS keys', () => {
|
|
if (!wasm) return;
|
|
const content = 'access_key = AKIAIOSFODNN7EXAMPLE';
|
|
const result = JSON.parse(wasm.scan_secrets(content));
|
|
expect(result.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('returns empty for clean content', () => {
|
|
if (!wasm) return;
|
|
const content = 'This is a normal string with no secrets.';
|
|
const result = JSON.parse(wasm.scan_secrets(content));
|
|
expect(result.length).toBe(0);
|
|
});
|
|
});
|
|
|
|
// ============================================================================
|
|
// Destructive Command Detection Parity
|
|
// ============================================================================
|
|
|
|
describe('WASM Kernel: Destructive Command Detection', () => {
|
|
const destructive = [
|
|
'rm -rf /',
|
|
'DROP TABLE users',
|
|
'git push origin main --force',
|
|
'git reset --hard HEAD~5',
|
|
'truncate table sessions',
|
|
'kubectl delete --all namespace production',
|
|
'DELETE FROM users',
|
|
];
|
|
|
|
const safe = [
|
|
'git commit -m "hello"',
|
|
'npm install express',
|
|
'cat /etc/hosts',
|
|
'SELECT * FROM users',
|
|
'ls -la',
|
|
];
|
|
|
|
it('detects all destructive patterns', () => {
|
|
if (!wasm) return;
|
|
for (const cmd of destructive) {
|
|
const result = wasm.detect_destructive(cmd);
|
|
expect(result, `Expected detection for: ${cmd}`).not.toBe('');
|
|
}
|
|
});
|
|
|
|
it('passes safe commands', () => {
|
|
if (!wasm) return;
|
|
for (const cmd of safe) {
|
|
const result = wasm.detect_destructive(cmd);
|
|
expect(result, `Expected no detection for: ${cmd}`).toBe('');
|
|
}
|
|
});
|
|
});
|
|
|
|
// ============================================================================
|
|
// Batch API
|
|
// ============================================================================
|
|
|
|
describe('WASM Kernel: Batch Processing', () => {
|
|
it('processes multiple operations in one call', () => {
|
|
if (!wasm) return;
|
|
const ops = [
|
|
{ op: 'sha256', payload: 'hello' },
|
|
{ op: 'sha256', payload: 'world' },
|
|
{ op: 'hmac_sha256', payload: 'message', key: 'secret' },
|
|
{ op: 'detect_destructive', payload: 'rm -rf /' },
|
|
{ op: 'detect_destructive', payload: 'ls -la' },
|
|
];
|
|
|
|
const results = JSON.parse(wasm.batch_process(JSON.stringify(ops)));
|
|
expect(results).toHaveLength(5);
|
|
expect(results[0].hash).toBe(jsSha256('hello'));
|
|
expect(results[1].hash).toBe(jsSha256('world'));
|
|
expect(results[2].signature).toBe(jsHmacSha256('secret', 'message'));
|
|
expect(results[3].detected).toBe(true);
|
|
expect(results[4].detected).toBe(false);
|
|
});
|
|
|
|
it('handles errors gracefully', () => {
|
|
if (!wasm) return;
|
|
const ops = [{ op: 'unknown_op', payload: 'test' }];
|
|
const results = JSON.parse(wasm.batch_process(JSON.stringify(ops)));
|
|
expect(results[0].error).toBeDefined();
|
|
});
|
|
});
|
|
|
|
// ============================================================================
|
|
// 10,000 Event Acceptance Test
|
|
// ============================================================================
|
|
|
|
describe('WASM Kernel: 10k Event Acceptance', () => {
|
|
it('processes 10,000 synthetic events with identical proof root hash', () => {
|
|
if (!wasm) return;
|
|
|
|
const signingKey = 'test-signing-key';
|
|
const events = 10_000;
|
|
|
|
// Build chain: each event's hash chains to the previous
|
|
let previousHash = '0'.repeat(64);
|
|
let jsRootHash = '';
|
|
let wasmRootHash = '';
|
|
|
|
// JS chain
|
|
const jsStart = performance.now();
|
|
for (let i = 0; i < events; i++) {
|
|
const payload = JSON.stringify({ eventId: `evt-${i}`, data: `payload-${i}`, step: i });
|
|
const contentHash = jsSha256(payload);
|
|
const chainPayload = previousHash + contentHash;
|
|
previousHash = jsHmacSha256(signingKey, chainPayload);
|
|
}
|
|
jsRootHash = previousHash;
|
|
const jsTime = performance.now() - jsStart;
|
|
|
|
// WASM chain
|
|
previousHash = '0'.repeat(64);
|
|
const wasmStart = performance.now();
|
|
for (let i = 0; i < events; i++) {
|
|
const payload = JSON.stringify({ eventId: `evt-${i}`, data: `payload-${i}`, step: i });
|
|
const contentHash = wasm.sha256(payload);
|
|
const chainPayload = previousHash + contentHash;
|
|
previousHash = wasm.hmac_sha256(signingKey, chainPayload);
|
|
}
|
|
wasmRootHash = previousHash;
|
|
const wasmTime = performance.now() - wasmStart;
|
|
|
|
// Identical root hash = replay parity
|
|
expect(wasmRootHash).toBe(jsRootHash);
|
|
|
|
console.log('\n--- 10k Event Proof Chain ---');
|
|
console.log(`JS: ${jsTime.toFixed(1)}ms (${Math.round(events / (jsTime / 1000))} chains/sec)`);
|
|
console.log(`WASM: ${wasmTime.toFixed(1)}ms (${Math.round(events / (wasmTime / 1000))} chains/sec)`);
|
|
console.log(`Ratio: ${(jsTime / wasmTime).toFixed(2)}x`);
|
|
console.log(`Root hash: ${wasmRootHash.substring(0, 16)}...`);
|
|
});
|
|
|
|
it('batch processes 10,000 SHA-256 hashes', () => {
|
|
if (!wasm) return;
|
|
|
|
const events = 10_000;
|
|
|
|
// Individual calls
|
|
const individualStart = performance.now();
|
|
for (let i = 0; i < events; i++) {
|
|
wasm.sha256(`event-${i}`);
|
|
}
|
|
const individualTime = performance.now() - individualStart;
|
|
|
|
// Batch call (chunks of 1000 to avoid huge JSON strings)
|
|
const batchStart = performance.now();
|
|
const chunkSize = 1000;
|
|
for (let chunk = 0; chunk < events; chunk += chunkSize) {
|
|
const ops = [];
|
|
for (let i = chunk; i < Math.min(chunk + chunkSize, events); i++) {
|
|
ops.push({ op: 'sha256', payload: `event-${i}` });
|
|
}
|
|
wasm.batch_process(JSON.stringify(ops));
|
|
}
|
|
const batchTime = performance.now() - batchStart;
|
|
|
|
console.log('\n--- 10k SHA-256 Hash Throughput ---');
|
|
console.log(`Individual: ${individualTime.toFixed(1)}ms (${Math.round(events / (individualTime / 1000))} ops/sec)`);
|
|
console.log(`Batch: ${batchTime.toFixed(1)}ms (${Math.round(events / (batchTime / 1000))} ops/sec)`);
|
|
console.log(`Batch speedup: ${(individualTime / batchTime).toFixed(2)}x`);
|
|
});
|
|
|
|
it('secret scanning throughput on 10,000 inputs', () => {
|
|
if (!wasm) return;
|
|
|
|
const clean = 'This is a normal string with no secrets at all';
|
|
const dirty = 'api_key = "sk-abcdefghijklmnop1234567890"';
|
|
|
|
// Clean inputs
|
|
const cleanStart = performance.now();
|
|
for (let i = 0; i < 10000; i++) {
|
|
wasm.scan_secrets(clean);
|
|
}
|
|
const cleanTime = performance.now() - cleanStart;
|
|
|
|
// Dirty inputs
|
|
const dirtyStart = performance.now();
|
|
for (let i = 0; i < 10000; i++) {
|
|
wasm.scan_secrets(dirty);
|
|
}
|
|
const dirtyTime = performance.now() - dirtyStart;
|
|
|
|
console.log('\n--- 10k Secret Scanning ---');
|
|
console.log(`Clean: ${cleanTime.toFixed(1)}ms (${Math.round(10000 / (cleanTime / 1000))} scans/sec)`);
|
|
console.log(`Dirty: ${dirtyTime.toFixed(1)}ms (${Math.round(10000 / (dirtyTime / 1000))} scans/sec)`);
|
|
});
|
|
});
|
|
|
|
// ============================================================================
|
|
// Kernel Initialization
|
|
// ============================================================================
|
|
|
|
describe('WASM Kernel: Init', () => {
|
|
it('returns version string', () => {
|
|
if (!wasm) return;
|
|
const version = wasm.kernel_init();
|
|
expect(version).toBe('guidance-kernel/0.1.0');
|
|
});
|
|
});
|