mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-27 22:15:33 +00:00
The v0.41.16.0 probe module (runConversationParserNightlyProbe) shipped as a callable phase with its scheduler wire-up deferred; the follow-up never landed. Result: zero call sites — the enable flag did nothing, the D10 tokenmax default-on never fired, and doctor's conversation_parser_probe_health was a hardcoded 'Skipped' stub that ignored config and mode. This adds the deferred wiring as autopilot step 4.6, mirroring the nightly quality probe (4.5): - Flag reads dual-plane (DB row from gbrain config set wins; file plane fallback); search.mode=tokenmax keeps the probe default-on per D10. - Fixtures resolve from the gbrain package root (the committed test/fixtures/conversation-formats/), NOT the brain repoPath. Compiled binaries carry no source tree: skip quietly with a once-per-process stderr note instead of writing failure rows that would flip doctor to WARN on every binary install. - New parser-probe audit trail (audit-parser-probe.ts, shared audit-writer primitive, parser-probe-YYYY-Www.jsonl). rate_limited outcomes are NOT logged: the loop ticks every few minutes, so auditing each skip would flood the file. The 24h gate (parserProbeRanWithin) reads real outcomes. - Doctor stub replaced with computeConversationParserProbeHealthCheck: enable hint when off+silent, WARN on any non-pass run in 7 days. - try/catch posture identical to 4.5 — a probe failure never crashes the loop and never bumps consecutiveErrors. Tests: audit round-trip + rate-limit gate, doctor check branches, and source-shape pins for the wiring protections. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FQgByq4aqQq2PP8UHCdnfk
78 lines
3.4 KiB
TypeScript
78 lines
3.4 KiB
TypeScript
/**
|
|
* Source-shape regression tests for the autopilot wiring of
|
|
* `runConversationParserNightlyProbe` (step 4.6).
|
|
*
|
|
* Same rationale as autopilot-nightly-probe-wiring.test.ts: the loop is
|
|
* hard to drive end-to-end, so these pin the structural protections —
|
|
* the dual-plane flag read, the D10 tokenmax mode-gate, the package-root
|
|
* fixture resolution, the audit-flood guard, and the try/catch posture.
|
|
*
|
|
* The probe's own gate/scoring logic is pinned by the module's unit
|
|
* tests; the audit trail by audit-parser-probe.serial.test.ts.
|
|
*/
|
|
|
|
import { describe, test, expect } from 'bun:test';
|
|
import { readFileSync } from 'node:fs';
|
|
import { resolve } from 'node:path';
|
|
|
|
const AUTOPILOT_SRC = resolve('src/commands/autopilot.ts');
|
|
const SOURCE = readFileSync(AUTOPILOT_SRC, 'utf-8');
|
|
|
|
describe('autopilot wiring: conversation-parser probe', () => {
|
|
test('invokes the phase module and the audit trail', () => {
|
|
expect(SOURCE).toContain(`runConversationParserNightlyProbe`);
|
|
expect(SOURCE).toContain(`conversation-parser/nightly-probe`);
|
|
expect(SOURCE).toContain(`logParserProbeEvent`);
|
|
expect(SOURCE).toContain(`audit-parser-probe`);
|
|
});
|
|
|
|
test('flag reads dual-plane: DB row (gbrain config set) wins, file plane fallback', () => {
|
|
expect(SOURCE).toContain(`getConfig('autopilot.conversation_parser_probe.enabled')`);
|
|
expect(SOURCE).toContain(`cfg?.autopilot?.conversation_parser_probe?.enabled === true`);
|
|
});
|
|
|
|
test('D10 mode-gate present: tokenmax brains run the probe by default', () => {
|
|
expect(SOURCE).toMatch(/parserEnabled \|\| searchMode === 'tokenmax'/);
|
|
});
|
|
|
|
test('fixtures resolve from the gbrain package root, NOT the brain repoPath', () => {
|
|
// The committed fixtures live in the gbrain source tree; resolving
|
|
// them against sync.repo_path would point into the user's brain repo.
|
|
expect(SOURCE).toMatch(/fileURLToPath\(new URL\('\.\.\/\.\.', import\.meta\.url\)\)/);
|
|
expect(SOURCE).toContain(`'conversation-formats', 'all.jsonl'`);
|
|
expect(SOURCE).toContain(`'conversation-formats', 'adversarial.jsonl'`);
|
|
});
|
|
|
|
test('missing fixtures skip quietly (no audit row, once-per-process stderr note)', () => {
|
|
// Compiled-binary installs carry no source tree; writing failure rows
|
|
// would flip doctor to WARN on every binary install.
|
|
expect(SOURCE).toContain(`parserProbeFixtureWarned`);
|
|
});
|
|
|
|
test('rate_limited outcomes are NOT audit-logged (flood guard)', () => {
|
|
expect(SOURCE).toMatch(/outcome !== 'rate_limited'\) logParserProbeEvent\(result\)/);
|
|
});
|
|
|
|
test('rate-limit gate delegates to the audit module, not inline event reads', () => {
|
|
expect(SOURCE).toContain(`parserProbeRanWithin(24 * 60 * 60 * 1000)`);
|
|
});
|
|
|
|
test('LLM-key gate reads gateway.isAvailable("chat") in-process', () => {
|
|
expect(SOURCE).toContain(`isAvailable('chat')`);
|
|
});
|
|
|
|
test('probe call wrapped in try/catch that does NOT bump consecutiveErrors', () => {
|
|
expect(SOURCE).toMatch(/catch[\s\S]*?autopilot\.parser_probe[\s\S]*?do NOT bump consecutiveErrors/);
|
|
});
|
|
|
|
test('DI shape: the exact 7 fields of the parser probe NightlyProbeDeps', () => {
|
|
expect(SOURCE).toContain(`isEnabled:`);
|
|
expect(SOURCE).toContain(`searchMode:`);
|
|
expect(SOURCE).toContain(`hasLlmKey:`);
|
|
expect(SOURCE).toContain(`resolveFixturePath:`);
|
|
expect(SOURCE).toContain(`resolveAdversarialPath:`);
|
|
expect(SOURCE).toContain(`shouldSkipForRateLimit:`);
|
|
expect(SOURCE).toContain(`now:`);
|
|
});
|
|
});
|