81cbd8c1c2
retro #7 (docs/observer/notes/2026-05-27-brain-retro-7.md) surfaced 4 candidates against 23 turns since retro #6. All four implemented TDD. C1 — translit slang vocabulary in router-classifier-regex-fallback.mjs. TASK_TYPE_KEYWORDS += deploy bucket (push / запушь / выкат); memory-sync += обнови мозг / эталон / пилот / memory dump. C2 — short_ambiguous_block in router-tool-gate.mjs + router-prehook.mjs. prehook persists prompt_length; gate blocks Edit/Write/MultiEdit/Bash when task_type in {ambiguous, unknown} AND prompt_length <= 30 AND skill not invoked AND no direct_justified tag. C3 — self-assessment timeout 30s to 50s in observer-self-assessment-api.mjs. Windows TLS handshake + Sonnet latency exceeded 30s. Stop-hook has 60s budget; 50s leaves headroom. DEFAULT_TIMEOUT_MS exported for tests. C4 — Reviewer findings block in status-md-generator.mjs. New helper computeReviewerFindingsBlock surfaces 51 actionable findings without running /brain-retro. Detects batch-reviewed via outcome_reviewed_source=direct_api_batch. MD012 guard test added. C5 (gitleaks-before-push) intentionally skipped — pre-push hook already blocks at server side. Tests: 956/956 root tools, 0 regressions. LEFTHOOK=0 used per quirk #111. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
68 lines
2.8 KiB
JavaScript
68 lines
2.8 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
|
import { classifyByRegex, TASK_TYPE_KEYWORDS } from './router-classifier-regex-fallback.mjs';
|
|
|
|
const fakeRegistry = {
|
|
nodes: [
|
|
{ id: '#19', name: 'Superpowers', status: 'active', triggers: [{ classification: 'feature', weight: 1.0 }] },
|
|
{ id: '#33', name: 'claude-md-management', status: 'active', triggers: [
|
|
{ classification: 'memory-sync', weight: 1.0 },
|
|
] },
|
|
{ id: '#3', name: 'GitHub MCP', status: 'active', triggers: [
|
|
{ classification: 'deploy', weight: 1.0 },
|
|
] },
|
|
],
|
|
};
|
|
|
|
// brain-retro #7 C1 (2026-05-27): translit slang vocabulary direct tests.
|
|
describe('classifyByRegex — C1 translit slang dictionary', () => {
|
|
it('«обнови мозг» → memory-sync', () => {
|
|
expect(classifyByRegex('обнови мозг', fakeRegistry).taskType).toBe('memory-sync');
|
|
});
|
|
|
|
it('«обнови эталон» → memory-sync', () => {
|
|
expect(classifyByRegex('обнови эталон после деплоя', fakeRegistry).taskType).toBe('memory-sync');
|
|
});
|
|
|
|
it('«обнови пилот» → memory-sync', () => {
|
|
expect(classifyByRegex('обнови пилот', fakeRegistry).taskType).toBe('memory-sync');
|
|
});
|
|
|
|
it('«пуш» → deploy', () => {
|
|
expect(classifyByRegex('пуш на main', fakeRegistry).taskType).toBe('deploy');
|
|
});
|
|
|
|
it('«push» (EN) → deploy', () => {
|
|
expect(classifyByRegex('push origin main', fakeRegistry).taskType).toBe('deploy');
|
|
});
|
|
|
|
it('«запушь» → deploy', () => {
|
|
expect(classifyByRegex('запушь ветку', fakeRegistry).taskType).toBe('deploy');
|
|
});
|
|
|
|
it('compound «пуш и обнови пилот» — NOT unknown (some meaningful classification)', () => {
|
|
expect(classifyByRegex('пуш и обнови пилот', fakeRegistry).taskType).not.toBe('unknown');
|
|
});
|
|
|
|
it('TASK_TYPE_KEYWORDS includes a deploy bucket', () => {
|
|
expect(TASK_TYPE_KEYWORDS.deploy).toBeDefined();
|
|
expect(TASK_TYPE_KEYWORDS.deploy.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('memory-sync bucket carries the translit nouns', () => {
|
|
const memSync = TASK_TYPE_KEYWORDS['memory-sync'] || [];
|
|
expect(memSync).toEqual(expect.arrayContaining(['обнови мозг', 'обнови эталон', 'обнови пилот']));
|
|
});
|
|
|
|
// Guard against regressions on pre-existing entries.
|
|
it('keeps original memory-sync entries (запомни / CLAUDE.md / MEMORY.md)', () => {
|
|
const memSync = TASK_TYPE_KEYWORDS['memory-sync'] || [];
|
|
expect(memSync).toEqual(expect.arrayContaining(['запомни', 'CLAUDE.md', 'MEMORY.md']));
|
|
});
|
|
});
|
|
|
|
describe('classifyByRegex — C1 source tag', () => {
|
|
it('source is regex (degraded path) for translit hits too', () => {
|
|
expect(classifyByRegex('обнови мозг', fakeRegistry).source).toBe('regex');
|
|
});
|
|
});
|