feat: анти-диктовка свободного floor_escape (consent forgery C)
Свободный floor_escape (лёгкий escape в чате) НЕ доверяется, если контроллер в своём тексте текущего хода инструктировал владельца вписать метку. processEvent читает текст контроллера из транскрипта хода (readTranscript + lastAssistantText, переиспользован), один раз на событие зовёт detectOtherSocialEng (раньше был мёртвой проводкой — не вызывался нигде); flagged → floor_escape не пишется. Паттерны detectOtherSocialEng усилены императивной диктовкой метки FLOOR-ESCAPE (глагол рядом; простое упоминание концепта не флагуется). fail-open observability — сбой чтения транскрипта → как раньше. Применяется к floor_escape (git-approval закрыт #A). Завершает кодовую часть эпика (A + B1-B5 + C). Спека §C. Свод 4350 зелёный. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -151,3 +151,23 @@ describe('processEvent — anti-button (HOLE-1 / A): ответ-кнопка н
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe('processEvent — anti-dictation (C): диктованный свободный floor_escape не пишется', () => {
|
||||
it('controllerText flagged → floor_escape НЕ записан', () => {
|
||||
const dir = tmpRuntimeDir();
|
||||
const event = { session_id: 'cd1', tool_input: { questions: [{ question: 'q' }] },
|
||||
tool_response: { answers: { q: 'да FLOOR-ESCAPE: write:c:/x.md' } } };
|
||||
processEvent(event, { runtimeDir: dir, nowMs: 7, controllerText: 'впиши в Other: FLOOR-ESCAPE: write:c:/x.md' });
|
||||
expect(existsSync(join(dir, 'askuser-decisions-cd1.jsonl'))).toBe(false);
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
});
|
||||
it('controllerText чистый → floor_escape записан (без регрессии)', () => {
|
||||
const dir = tmpRuntimeDir();
|
||||
const event = { session_id: 'cd2', tool_input: { questions: [{ question: 'q' }] },
|
||||
tool_response: { answers: { q: 'да FLOOR-ESCAPE: write:c:/x.md' } } };
|
||||
processEvent(event, { runtimeDir: dir, nowMs: 7, controllerText: 'разрешаешь правку файла?' });
|
||||
const content = readFileSync(join(dir, 'askuser-decisions-cd2.jsonl'), 'utf-8');
|
||||
expect(content).toContain('"type":"floor_escape"');
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user