test(mods): guard probe timing is a hang gate (median of 3 > 1000 ms), 50 ms/50x advisory; bare --known-holes; wider watchdog

Co-Authored-By: RuFlo <ruv@ruv.net>
This commit is contained in:
ruv committed 2026-10-04 20:34:20 -04:00
1 parent bf84712833
commit 5d8ab06dc4
6 files changed
+120 -132

No files matched your search

+17 -5
View File
@@ -117,21 +117,30 @@ test('flags the naive guard on nesting, keys, invisible characters and size; pas
assert.ok(out.newHoles.every(h => h.startsWith('naive:')))
})
test('a throwing guard and a slow guard are failures of the stress probes', () => {
test('a throwing guard and a hanging-slow guard are failures; a merely slow one is advisory', () => {
const dir = fixtures(join(tmp, 'plugins-bad'), {
thrower: `export function verdict(tool: string, input: unknown): string | undefined {
if (JSON.stringify(input).length > 1000) throw new RangeError('boom')
return tool === 'memory_store' ? undefined : undefined
}`,
sluggish: `export function verdict(tool: string, input: unknown): string | undefined {
if (tool !== 'memory_store') return undefined
let s = ''
try { s = JSON.stringify(input) ?? '' } catch { /* deep */ }
const end = Date.now() + (s.includes('":"' + 'a'.repeat(5000)) ? 25 : 0)
while (Date.now() < end) { /* busy */ }
return undefined
}`,
slow: `export function verdict(tool: string, input: unknown): string | undefined {
if (tool !== 'memory_store') return undefined
const s = JSON.stringify(input) ?? ''
const end = Date.now() + (s.length > 100000 ? 80 : 0)
let s = ''
try { s = JSON.stringify(input) ?? '' } catch { /* too deep to serialise: not the slow shape */ }
const end = Date.now() + (s.includes('":"' + 'a'.repeat(5000)) ? 80 : 0)
while (Date.now() < end) { /* busy */ }
return undefined
}`,
})
const r = run('--fast', '--plugins-dir', dir, '--format', 'json', '--budget-ms', '50')
const r = run('--fast', '--plugins-dir', dir, '--format', 'json', '--budget-ms', '60', '--advisory-ms', '10')
assert.equal(r.status, 1)
const by = Object.fromEntries(JSON.parse(r.stdout).rows.map(x => [x.name, x]))
const thrown = by.thrower.results.find(x => x.id === 's-a')
@@ -139,7 +148,10 @@ test('a throwing guard and a slow guard are failures of the stress probes', () =
assert.match(thrown.note, /RangeError/)
const slowed = by.slow.results.find(x => x.id === 's-a')
assert.equal(slowed.status, 'fail')
assert.ok(slowed.ms >= 50)
assert.ok(slowed.ms >= 60)
const adv = by.sluggish.results.find(x => x.id === 's-a')
assert.equal(adv.status, 'pass')
assert.match(adv.note, /advisory slow/)
})
test('a hung guard is killed by the watchdog and reported, not waited on forever', () => {
+1 -1
View File
@@ -8,7 +8,7 @@ export function renderReport({ rows, args, startedMs }) {
const out = []
const ids = [...new Set(rows.flatMap(r => r.results.map(x => x.id)))]
const byId = id => rows.map(r => [r.name, r.results.find(x => x.id === id)]).filter(([, x]) => x)
out.push(`Generated by \`node scripts/probe-mod-guards.mjs${args.fast ? ' --fast' : ''}\` in ${((Date.now() - startedMs) / 1000).toFixed(1)}s. Timing gate: ${args.budgetMs} ms per call (best of ${args.fast ? 1 : 3} runs).`)
out.push(`Generated by \`node scripts/probe-mod-guards.mjs${args.fast ? ' --fast' : ''}\` in ${((Date.now() - startedMs) / 1000).toFixed(1)}s. Timing: a probe fails only above ${args.budgetMs} ms (median of 3: hang / catastrophic backtracking); ${args.advisoryMs}-${args.budgetMs} ms, or >50x the guard's own trivial-input time, is reported as advisory slow, not failed.`)
out.push('')
out.push('## Per-plugin summary')
out.push('')
+21 -13
View File
@@ -5,7 +5,7 @@ import { pathToFileURL } from 'node:url'
import { performance } from 'node:perf_hooks'
import { ALL_SECRETS, BENIGN, SECRET_TYPES, evasionProbes, stressProbes } from './guard-probe-corpus.mjs'
const { bundle, tools, servers, extra, fast, skip, budgetMs } = workerData
const { bundle, tools, servers, extra, fast, skip, budgetMs, advisoryMs } = workerData
const done = new Set(skip)
const send = m => parentPort.postMessage(m)
@@ -104,22 +104,30 @@ for (const probe of stressProbes(big)) {
const payload = probe.build()
let worst = 0
const bad = []
const slow = []
for (const t of timing) {
const input = t.make(payload)
let best = Infinity
let err
for (let i = 0; i < reps; i++) {
const r = call(t.tool, input)
if (r.err) { err = r.err; best = Math.min(best, r.ms); break }
best = Math.min(best, r.ms)
if (best * 2 < budgetMs) break // clearly inside the budget: re-measure only the calls that are near it
const label = `${bareOf(t.tool)}${t.ns ? `[${t.ns}]` : ''}`
const median = inp => {
const ms = []
for (let i = 0; i < reps; i++) {
const r = call(t.tool, inp)
if (r.err) return { err: r.err, ms: r.ms }
ms.push(r.ms)
}
return { ms: ms.sort((x, y) => x - y)[1] }
}
if (best > worst) worst = best
if (err) bad.push(`${bareOf(t.tool)}${t.ns ? `[${t.ns}]` : ''} threw ${err}`)
else if (best > budgetMs) bad.push(`${bareOf(t.tool)}${t.ns ? `[${t.ns}]` : ''} ${best.toFixed(0)}ms`)
if (bad.length >= 3) break // three offenders prove the point; do not sweep every shape of a guard that is slow everywhere
const m = median(input)
if (m.err) { bad.push(`${label} threw ${m.err}`); worst = Math.max(worst, m.ms); if (bad.length >= 3) break; continue }
worst = Math.max(worst, m.ms)
if (m.ms > budgetMs) bad.push(`${label} ${m.ms.toFixed(0)}ms (median of ${reps}, hang gate ${budgetMs}ms)`)
else if (m.ms > advisoryMs) {
const base = median(t.make('a')).ms
slow.push(`${label} ${m.ms.toFixed(0)}ms${m.ms > 50 * base ? ` slow-relative (>50x the ${base.toFixed(2)}ms trivial call)` : ''}`)
}
if (bad.length >= 3 || slow.length >= 3) break // three offenders prove the point; do not sweep every shape of a guard that is slow everywhere
}
record(probe, bad.length === 0 ? 'pass' : 'fail', worst, [...new Set(bad)].slice(0, 3).join('; '))
record(probe, bad.length === 0 ? 'pass' : 'fail', worst, bad.length ? [...new Set(bad)].slice(0, 3).join('; ') : slow.length ? `advisory slow: ${[...new Set(slow)].slice(0, 2).join('; ')}` : undefined)
}
// Benign look-alikes must pass on every calibrated shape.
+32 -64
View File
@@ -24,8 +24,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-agent": [
"shy-split",
@@ -52,8 +51,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-agentdb": [
"shy-split",
@@ -80,8 +78,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-ai-team": [
"shy-split",
@@ -108,8 +105,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-aidefence": [
"shy-split",
@@ -136,8 +132,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-autopilot": [
"shy-split",
@@ -164,8 +159,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-bbs-federation": [
"shy-split",
@@ -192,8 +186,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-daa": [
"shy-split",
@@ -220,8 +213,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-ddd": [
"shy-split",
@@ -248,8 +240,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-docs": [
"shy-split",
@@ -276,8 +267,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-federation": [
"shy-split",
@@ -304,8 +294,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-goals": [
"shy-split",
@@ -332,8 +321,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-graph-intelligence": [
"shy-split",
@@ -360,8 +348,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-intelligence": [
"shy-split",
@@ -388,8 +375,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-iot-cognitum": [
"shy-split",
@@ -416,8 +402,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-jujutsu": [
"shy-split",
@@ -444,8 +429,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-knowledge-graph": [
"shy-split",
@@ -472,8 +456,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-loop-workers": [
"shy-split",
@@ -500,8 +483,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-market-data": [
"shy-split",
@@ -528,8 +510,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-metaharness": [
"shy-split",
@@ -556,8 +537,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-migrations": [
"shy-split",
@@ -581,8 +561,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-music": [
"shy-split",
@@ -606,8 +585,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-neural-trader": [
"shy-split",
@@ -631,8 +609,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-observability": [
"shy-split",
@@ -656,8 +633,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-rag-memory": [
"shy-split",
@@ -684,8 +660,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-ruvector": [
"shy-split",
@@ -712,8 +687,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-ruvllm": [
"shy-split",
@@ -740,8 +714,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-rvf": [
"shy-split",
@@ -768,8 +741,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-security-audit": [
"shy-split",
@@ -796,8 +768,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-sparc": [
"shy-split",
@@ -824,8 +795,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-workflows": [
"shy-split",
@@ -852,8 +822,7 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
],
"ruflo-x-gateway": [
"shy-split",
@@ -880,7 +849,6 @@
"huge-middle",
"huge-end",
"after-25k-padding",
"after-200k-padding",
"s-wide-keys-100k"
"after-200k-padding"
]
}
+10 -9
View File
@@ -3,7 +3,7 @@
//
// Each guard is bundled with esbuild into a private temp dir, then run in a worker thread through a fixed corpus (see
// scripts/lib/guard-probe-corpus.mjs): secrets split by invisible/bidi characters, nested 5000 levels, in object keys, 1 MB strings,
// regex-DoS inputs (each call is timed; > --budget-ms fails), encodings, and benign look-alikes (must pass). A worker that hangs is
// regex-DoS inputs (each call is timed: median of 3 > --budget-ms (1000, hang/backtracking gate) fails, > --advisory-ms (50) is reported as advisory slow), encodings, and benign look-alikes (must pass). A worker that hangs is
// killed by a watchdog and reported as a failure of the probe it was in.
//
// USAGE
@@ -32,7 +32,7 @@ const REPO = dirname(HERE)
const WORKER = join(HERE, 'lib', 'guard-probe-worker.mjs')
const args = (() => {
const a = { fast: false, format: 'table', only: null, verbose: false, pluginsDir: join(REPO, 'plugins'), report: null, knownHoles: null, writeKnownHoles: null, strict: false, budgetMs: 50, watchdogMs: null, concurrency: Math.max(1, Math.min(4, cpus().length >> 1)) }
const a = { fast: false, format: 'table', only: null, verbose: false, pluginsDir: join(REPO, 'plugins'), report: null, knownHoles: null, writeKnownHoles: null, strict: false, budgetMs: 1000, advisoryMs: 50, watchdogMs: null, concurrency: Math.max(1, Math.min(4, cpus().length >> 1)) }
const argv = process.argv.slice(2)
const need = i => { if (argv[i + 1] === undefined) { console.error(`probe-mod-guards: ${argv[i]} needs a value`); process.exit(2) } return argv[i + 1] }
for (let i = 0; i < argv.length; i++) {
@@ -44,15 +44,16 @@ const args = (() => {
else if (v === '--only') a.only = new Set(need(i++).split(',').map(s => s.trim()).filter(Boolean))
else if (v === '--plugins-dir') a.pluginsDir = resolve(need(i++))
else if (v === '--report') a.report = resolve(need(i++))
else if (v === '--known-holes') a.knownHoles = resolve(need(i++))
else if (v === '--known-holes') a.knownHoles = resolve(argv[i + 1] !== undefined && !argv[i + 1].startsWith('--') ? argv[++i] : join(HERE, 'probe-mod-guards.known-holes.json'))
else if (v === '--write-known-holes') a.writeKnownHoles = resolve(need(i++))
else if (v === '--budget-ms') a.budgetMs = Number(need(i++))
else if (v === '--advisory-ms') a.advisoryMs = Number(need(i++))
else if (v === '--watchdog-ms') a.watchdogMs = Number(need(i++))
else if (v === '--concurrency') a.concurrency = Number(need(i++))
else { console.error(`probe-mod-guards: unknown argument ${v}`); process.exit(2) }
}
if (!['table', 'json'].includes(a.format) || !(a.budgetMs > 0) || !(a.concurrency >= 1)) { console.error('probe-mod-guards: bad --format, --budget-ms or --concurrency'); process.exit(2) }
a.watchdogMs ??= a.fast ? 10_000 : 30_000
if (!['table', 'json'].includes(a.format) || !(a.budgetMs > 0) || !(a.advisoryMs >= 0) || !(a.concurrency >= 1)) { console.error('probe-mod-guards: bad --format, --budget-ms or --concurrency'); process.exit(2) }
a.watchdogMs ??= a.fast ? 30_000 : 60_000 // a hang gate, not a speed gate: calibration alone can take seconds on a loaded box
return a
})()
@@ -101,7 +102,7 @@ function bundle(esbuild, plugin, tmp) {
async function runPlugin(plugin, bundled) {
const guardSrc = readFileSync(join(plugin.dir, 'guard.ts'), 'utf8')
const named = [...guardSrc.matchAll(/includes\((['"`])([a-z][^'"`]*)\1\)/g)].map(m => m[2])
const job = { bundle: bundled, tools: toolsOf(guardSrc), servers: [...SERVERS, ...named], extra: [], fast: args.fast, budgetMs: args.budgetMs }
const job = { bundle: bundled, tools: toolsOf(guardSrc), servers: [...SERVERS, ...named], extra: [], fast: args.fast, budgetMs: args.budgetMs, advisoryMs: args.advisoryMs }
const results = []
const skip = []
let meta = { calibrated: 0, chosen: [], timingTargets: 0 }
@@ -178,7 +179,7 @@ if (args.writeKnownHoles) {
}
if (args.report) {
mkdirSync(dirname(args.report), { recursive: true })
const generated = renderReport({ rows, args: { fast: args.fast, budgetMs: args.budgetMs }, startedMs: started })
const generated = renderReport({ rows, args: { fast: args.fast, budgetMs: args.budgetMs, advisoryMs: args.advisoryMs }, startedMs: started })
const MARK = '<!-- generated below'
const prior = existsSync(args.report) ? readFileSync(args.report, 'utf8') : ''
const at = prior.indexOf(MARK)
@@ -189,7 +190,7 @@ if (args.format === 'json') {
console.log(JSON.stringify({ rows, holes, newHoles: fresh, fixedKnownHoles: fixed, fatal: fatal.map(f => ({ plugin: f.name, error: f.fatal })) }, null, 1))
} else {
const pad = (s, n) => String(s).padEnd(n)
console.log(`probe-mod-guards: ${rows.length} guards, ${args.fast ? 'fast' : 'full'} corpus, budget ${args.budgetMs}ms/call, ${((Date.now() - started) / 1000).toFixed(1)}s\n`)
console.log(`probe-mod-guards: ${rows.length} guards, ${args.fast ? 'fast' : 'full'} corpus, hang gate ${args.budgetMs}ms/call (median of 3), advisory ${args.advisoryMs}ms, ${((Date.now() - started) / 1000).toFixed(1)}s\n`)
console.log(`${pad('plugin', 26)} ${pad('surface (tool.field)', 44)} ${pad('pass', 5)} ${pad('fail', 5)} ${pad('info', 5)} ${pad('skip', 5)} worst-ms`)
for (const r of rows) {
const c = s => r.results.filter(x => x.status === s).length
@@ -197,7 +198,7 @@ if (args.format === 'json') {
const surface = r.meta.chosen.length ? r.meta.chosen.map(x => x.at).join(', ') : r.fatal ? `FATAL ${r.fatal}` : 'none (policy guard / no secret surface)'
console.log(`${pad(r.name, 26)} ${pad(surface.length > 43 ? `${surface.slice(0, 42)}…` : surface, 44)} ${pad(c('pass'), 5)} ${pad(c('fail'), 5)} ${pad(c('info'), 5)} ${pad(c('skip'), 5)} ${worst.ms.toFixed(1)} (${worst.id})`)
for (const x of r.results) {
if (args.verbose || (isHole(x) && !known.has(`${r.name}:${x.id}`))) console.log(` ${pad(x.status.toUpperCase(), 5)} ${pad(x.id, 24)} ${pad(x.ms.toFixed(1) + 'ms', 10)} ${(x.note ?? '').slice(0, 120)}`)
if (args.verbose || x.note?.startsWith('advisory slow') || (isHole(x) && !known.has(`${r.name}:${x.id}`))) console.log(` ${pad(x.status.toUpperCase(), 5)} ${pad(x.id, 24)} ${pad(x.ms.toFixed(1) + 'ms', 10)} ${(x.note ?? '').slice(0, 120)}`)
}
}
const total = rows.reduce((n, r) => n + r.results.length, 0)
+39 -40
View File
@@ -100,49 +100,49 @@ print as "known holes that now pass"; remove them from the baseline. Fix a root
<!-- generated below: node scripts/probe-mod-guards.mjs --report <path> -->
Generated by `node scripts/probe-mod-guards.mjs` in 16.5s. Timing gate: 50 ms per call (best of 3 runs).
Generated by `node scripts/probe-mod-guards.mjs` in 25.3s. Timing: a probe fails only above 1000 ms (median of 3: hang / catastrophic backtracking); 50-1000 ms, or >50x the guard's own trivial-input time, is reported as advisory slow, not failed.
## Per-plugin summary
| plugin | secret surface found (tool[namespace].field) | pass | fail | advisory miss | skipped | worst ms (probe) |
|---|---|---:|---:|---:|---:|---|
| ruflo-adr | `memory_store[adr].value`<br>`agentdb_hierarchical-store[adr].value`<br>`agentdb_causal-edge[adr].value` | 49 | 26 | 6 | 0 | 86.6 (s-wide-keys-100k) |
| ruflo-agent | `wasm_agent_prompt.value`<br>`wasm_agent_tool.value`<br>`wasm_agent_create.value` | 49 | 26 | 6 | 0 | 77.4 (s-wide-keys-100k) |
| ruflo-agentdb | `memory_store.value`<br>`agentdb_hierarchical-store.value`<br>`agentdb_causal-edge.value` | 49 | 26 | 6 | 0 | 80.6 (s-wide-keys-100k) |
| ruflo-ai-team | `task_create.value`<br>`memory_remember.value`<br>`task_update.value` | 49 | 26 | 6 | 0 | 92.6 (s-wide-keys-100k) |
| ruflo-aidefence | `aidefence_learn.value` | 49 | 26 | 6 | 0 | 79.7 (s-wide-keys-100k) |
| ruflo-autopilot | `autopilot_log.value`<br>`autopilot_learn.value`<br>`autopilot_config.value` | 49 | 26 | 6 | 0 | 77.1 (s-wide-keys-100k) |
| ruflo-bbs-federation | `federation_bbs_publish.value`<br>`federation_bbs_human_join.value` | 49 | 26 | 6 | 0 | 169.9 (s-wide-keys-100k) |
| ruflo-browser | none (policy guard) | 36 | 0 | 0 | 45 | 16.9 (s-zwsp) |
| ruflo-business-pods | none (policy guard) | 36 | 0 | 0 | 45 | 3.9 (s-zwsp-in-secret) |
| ruflo-chatgpt-federation | none (policy guard) | 36 | 0 | 0 | 45 | 0.4 (s-deep-arr-5000) |
| ruflo-daa | `daa_knowledge_share.value`<br>`daa_x.value` | 49 | 26 | 6 | 0 | 81.6 (s-wide-keys-100k) |
| ruflo-ddd | `memory_store[ddd-model].value`<br>`agentdb_hierarchical-store[ddd-model].value` | 49 | 26 | 6 | 0 | 72.3 (s-wide-keys-100k) |
| ruflo-deepseek-harness | none (policy guard) | 36 | 0 | 0 | 45 | 0.6 (s-wide-array-100k) |
| ruflo-docs | `memory_store[docs].value`<br>`hooks_worker-dispatch[document].value` | 49 | 26 | 6 | 0 | 77.6 (s-wide-keys-100k) |
| ruflo-federation | `memory_store[federation].value`<br>`federation_bbs_publish.value` | 49 | 26 | 6 | 0 | 79.5 (s-wide-keys-100k) |
| ruflo-goals | `memory_store[goals].value`<br>`agentdb_hierarchical-store[goals].value`<br>`agentdb_pattern-store[goals].value` | 49 | 26 | 6 | 0 | 74.9 (s-wide-keys-100k) |
| ruflo-graph-intelligence | `sublinear_solve.value`<br>`sublinear_x.value` | 49 | 26 | 6 | 0 | 77.2 (s-wide-keys-100k) |
| ruflo-intelligence | `memory_store[patterns].value`<br>`hooks_intelligence_pattern-store.value`<br>`hooks_transfer.value` | 49 | 26 | 6 | 0 | 71.3 (s-wide-keys-100k) |
| ruflo-iot-cognitum | `memory_store[iot-devices].value` | 49 | 26 | 6 | 0 | 73.5 (s-wide-keys-100k) |
| ruflo-jujutsu | `github_pr_manage.value` | 49 | 26 | 6 | 0 | 72.2 (s-wide-keys-100k) |
| ruflo-knowledge-graph | `agentdb_hierarchical-store.value`<br>`agentdb_causal-edge.value`<br>`agentdb_pattern-store.value` | 49 | 26 | 6 | 0 | 79.7 (s-wide-keys-100k) |
| ruflo-loop-workers | `hooks_worker-dispatch.value` | 49 | 26 | 6 | 0 | 79.2 (s-wide-keys-100k) |
| ruflo-market-data | `memory_store.value`<br>`agentdb_hierarchical-store.value`<br>`agentdb_pattern-store.value` | 49 | 26 | 6 | 0 | 73.5 (s-wide-keys-100k) |
| ruflo-metaharness | `memory_store.value`<br>`agentdb_hierarchical-store.value`<br>`agentdb_causal-edge.value` | 49 | 26 | 6 | 0 | 79.2 (s-wide-keys-100k) |
| ruflo-migrations | `memory_store.value`<br>`agentdb_hierarchical-store.value`<br>`agentdb_pattern-store.value` | 52 | 23 | 6 | 0 | 91.4 (s-wide-keys-100k) |
| ruflo-music | `memory_store.value`<br>`agentdb_hierarchical-store.value`<br>`agentdb_pattern-store.value` | 52 | 23 | 6 | 0 | 95.5 (s-wide-keys-100k) |
| ruflo-neural-trader | `memory_store.value`<br>`agentdb_hierarchical-store.value`<br>`agentdb_pattern-store.value` | 52 | 23 | 6 | 0 | 97.4 (s-wide-keys-100k) |
| ruflo-observability | `memory_store.value`<br>`agentdb_hierarchical-store.value`<br>`agentdb_pattern-store.value` | 52 | 23 | 6 | 0 | 86.6 (s-wide-keys-100k) |
| ruflo-rag-memory | `memory_store.value`<br>`agentdb_hierarchical-store.value`<br>`agentdb_pattern-store.value` | 49 | 26 | 6 | 0 | 83.5 (s-wide-keys-100k) |
| ruflo-ruvector | `memory_store.value` | 49 | 26 | 6 | 0 | 76.3 (s-wide-keys-100k) |
| ruflo-ruvllm | `ruvllm_hnsw_add.value` | 49 | 26 | 6 | 0 | 77.3 (s-wide-keys-100k) |
| ruflo-rvf | `memory_store.value`<br>`hooks_transfer.value` | 49 | 26 | 6 | 0 | 76.0 (s-wide-keys-100k) |
| ruflo-security-audit | `memory_store[security].value`<br>`agentdb_hierarchical-store[security].value`<br>`agentdb_pattern-store[security].value` | 49 | 26 | 6 | 0 | 73.1 (s-wide-keys-100k) |
| ruflo-sparc | `memory_store[sparc].value`<br>`agentdb_hierarchical-store[sparc].value`<br>`agentdb_pattern-store[sparc].value` | 49 | 26 | 6 | 0 | 72.9 (s-wide-keys-100k) |
| ruflo-testgen | none (policy guard) | 36 | 0 | 0 | 45 | 0.0 (s-assign-long-value) |
| ruflo-workflows | `memory_store[workflows].value`<br>`agentdb_hierarchical-store[workflows].value`<br>`agentdb_pattern-store[workflows].value` | 49 | 26 | 6 | 0 | 72.0 (s-wide-keys-100k) |
| ruflo-x-gateway | `x_federation_publish.value`<br>`x_federation_channel_publish.value` | 49 | 26 | 6 | 0 | 80.7 (s-wide-keys-100k) |
| ruflo-adr | `memory_store[adr].value`<br>`agentdb_hierarchical-store[adr].value`<br>`agentdb_causal-edge[adr].value` | 50 | 25 | 6 | 0 | 71.7 (s-wide-keys-100k) |
| ruflo-agent | `wasm_agent_prompt.value`<br>`wasm_agent_tool.value`<br>`wasm_agent_create.value` | 50 | 25 | 6 | 0 | 72.0 (s-wide-keys-100k) |
| ruflo-agentdb | `memory_store.value`<br>`agentdb_hierarchical-store.value`<br>`agentdb_causal-edge.value` | 50 | 25 | 6 | 0 | 70.2 (s-wide-keys-100k) |
| ruflo-ai-team | `task_create.value`<br>`memory_remember.value`<br>`task_update.value` | 50 | 25 | 6 | 0 | 76.5 (s-wide-keys-100k) |
| ruflo-aidefence | `aidefence_learn.value` | 50 | 25 | 6 | 0 | 70.9 (s-wide-keys-100k) |
| ruflo-autopilot | `autopilot_log.value`<br>`autopilot_learn.value`<br>`autopilot_config.value` | 50 | 25 | 6 | 0 | 79.2 (s-wide-keys-100k) |
| ruflo-bbs-federation | `federation_bbs_publish.value`<br>`federation_bbs_human_join.value` | 50 | 25 | 6 | 0 | 160.0 (s-wide-keys-100k) |
| ruflo-browser | none (policy guard) | 36 | 0 | 0 | 45 | 13.7 (s-zwsp) |
| ruflo-business-pods | none (policy guard) | 36 | 0 | 0 | 45 | 0.0 (-) |
| ruflo-chatgpt-federation | none (policy guard) | 36 | 0 | 0 | 45 | 0.0 (s-jwt-dots) |
| ruflo-daa | `daa_knowledge_share.value`<br>`daa_x.value` | 50 | 25 | 6 | 0 | 80.9 (s-wide-keys-100k) |
| ruflo-ddd | `memory_store[ddd-model].value`<br>`agentdb_hierarchical-store[ddd-model].value` | 50 | 25 | 6 | 0 | 71.5 (s-wide-keys-100k) |
| ruflo-deepseek-harness | none (policy guard) | 36 | 0 | 0 | 45 | 0.0 (-) |
| ruflo-docs | `memory_store[docs].value`<br>`hooks_worker-dispatch[document].value` | 50 | 25 | 6 | 0 | 74.4 (s-wide-keys-100k) |
| ruflo-federation | `memory_store[federation].value`<br>`federation_bbs_publish.value` | 50 | 25 | 6 | 0 | 79.2 (s-wide-keys-100k) |
| ruflo-goals | `memory_store[goals].value`<br>`agentdb_hierarchical-store[goals].value`<br>`agentdb_pattern-store[goals].value` | 50 | 25 | 6 | 0 | 72.4 (s-wide-keys-100k) |
| ruflo-graph-intelligence | `sublinear_solve.value`<br>`sublinear_x.value` | 50 | 25 | 6 | 0 | 77.9 (s-wide-keys-100k) |
| ruflo-intelligence | `memory_store[patterns].value`<br>`hooks_intelligence_pattern-store.value`<br>`hooks_transfer.value` | 50 | 25 | 6 | 0 | 77.3 (s-wide-keys-100k) |
| ruflo-iot-cognitum | `memory_store[iot-devices].value` | 50 | 25 | 6 | 0 | 75.5 (s-wide-keys-100k) |
| ruflo-jujutsu | `github_pr_manage.value` | 50 | 25 | 6 | 0 | 77.2 (s-wide-keys-100k) |
| ruflo-knowledge-graph | `agentdb_hierarchical-store.value`<br>`agentdb_causal-edge.value`<br>`agentdb_pattern-store.value` | 50 | 25 | 6 | 0 | 76.7 (s-wide-keys-100k) |
| ruflo-loop-workers | `hooks_worker-dispatch.value` | 50 | 25 | 6 | 0 | 76.9 (s-wide-keys-100k) |
| ruflo-market-data | `memory_store.value`<br>`agentdb_hierarchical-store.value`<br>`agentdb_pattern-store.value` | 50 | 25 | 6 | 0 | 71.1 (s-wide-keys-100k) |
| ruflo-metaharness | `memory_store.value`<br>`agentdb_hierarchical-store.value`<br>`agentdb_causal-edge.value` | 50 | 25 | 6 | 0 | 74.2 (s-wide-keys-100k) |
| ruflo-migrations | `memory_store.value`<br>`agentdb_hierarchical-store.value`<br>`agentdb_pattern-store.value` | 53 | 22 | 6 | 0 | 106.6 (s-wide-keys-100k) |
| ruflo-music | `memory_store.value`<br>`agentdb_hierarchical-store.value`<br>`agentdb_pattern-store.value` | 53 | 22 | 6 | 0 | 81.4 (s-wide-keys-100k) |
| ruflo-neural-trader | `memory_store.value`<br>`agentdb_hierarchical-store.value`<br>`agentdb_pattern-store.value` | 53 | 22 | 6 | 0 | 92.8 (s-wide-keys-100k) |
| ruflo-observability | `memory_store.value`<br>`agentdb_hierarchical-store.value`<br>`agentdb_pattern-store.value` | 53 | 22 | 6 | 0 | 86.0 (s-wide-keys-100k) |
| ruflo-rag-memory | `memory_store.value`<br>`agentdb_hierarchical-store.value`<br>`agentdb_pattern-store.value` | 50 | 25 | 6 | 0 | 85.1 (s-wide-keys-100k) |
| ruflo-ruvector | `memory_store.value` | 50 | 25 | 6 | 0 | 79.4 (s-wide-keys-100k) |
| ruflo-ruvllm | `ruvllm_hnsw_add.value` | 50 | 25 | 6 | 0 | 79.6 (s-wide-keys-100k) |
| ruflo-rvf | `memory_store.value`<br>`hooks_transfer.value` | 50 | 25 | 6 | 0 | 78.5 (s-wide-keys-100k) |
| ruflo-security-audit | `memory_store[security].value`<br>`agentdb_hierarchical-store[security].value`<br>`agentdb_pattern-store[security].value` | 50 | 25 | 6 | 0 | 81.1 (s-wide-keys-100k) |
| ruflo-sparc | `memory_store[sparc].value`<br>`agentdb_hierarchical-store[sparc].value`<br>`agentdb_pattern-store[sparc].value` | 50 | 25 | 6 | 0 | 76.7 (s-wide-keys-100k) |
| ruflo-testgen | none (policy guard) | 36 | 0 | 0 | 45 | 0.0 (-) |
| ruflo-workflows | `memory_store[workflows].value`<br>`agentdb_hierarchical-store[workflows].value`<br>`agentdb_pattern-store[workflows].value` | 50 | 25 | 6 | 0 | 63.9 (s-wide-keys-100k) |
| ruflo-x-gateway | `x_federation_publish.value`<br>`x_federation_channel_publish.value` | 50 | 25 | 6 | 0 | 62.7 (s-wide-keys-100k) |
## Probe matrix (✓ pass · ✗ fail · ~ advisory miss · · not applicable)
@@ -228,7 +228,7 @@ Columns are plugins in the order of the summary table above (1 = first row).
| s-deep-arr-5000 | stress | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| s-deep-obj-100000 | stress | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| s-wide-array-100k | stress | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| s-wide-keys-100k | stress | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✓ | ✓ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ |
| s-wide-keys-100k | stress | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| s-many-1kb-strings | stress | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| benign-lookalikes | benign | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | · | · | · | ✓ | ✓ | · | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | · | ✓ | ✓ |
@@ -265,4 +265,3 @@ Columns are plugins in the order of the summary table above (1 = first row).
- **huge-end** (must) — 32/37: all but none
- **after-25k-padding** (must) — 32/37: all but none
- **after-200k-padding** (must) — 32/37: all but none
- **s-wide-keys-100k** (must) — 32/37: all but ruflo-browser, ruflo-business-pods, ruflo-chatgpt-federation, ruflo-deepseek-harness, ruflo-testgen