#!/usr/bin/env node /** * Forgen — Stop Guard (Mech-B prototype, spike/mech-b-a1) * * Stop hook: 어시스턴트 직전 응답에서 "완료 선언" 패턴을 감지하고, 연결된 * Mech-A(artifact_check) / Mech-B(self_check_prompt) 규칙을 평가하여 * 위반 시 blockStop 으로 세션을 재개시킨다. * * Prototype scope (spike only — NOT v0.4.0 final): * - 규칙은 tests/spike/mech-b-inject/scenarios.json 에서 로드 * (FORGEN_SPIKE_RULES env 로 override 가능) * - 어시스턴트 메시지는 transcript_path 에서 마지막 assistant 턴을 뽑거나 * FORGEN_SPIKE_LAST_MESSAGE env 로 주입 가능 (runner/단위테스트용) * - artifact_check 는 `~/.forgen/state/` 경로를 기준으로 평가 * * 설계 제약 (ADR-001, Day-1 verification): * - self_check_prompt 질문은 **reason** 에 전체를 담는다 (모델 도달). * - systemMessage 는 rule tag 한 줄만 (UI 표시 보조). * - 외부 LLM API 호출 없음 (β1 유지). */ import type { Rule } from '../store/types.js'; interface VerifierSpec { kind: 'self_check_prompt' | 'artifact_check' | 'tool_arg_regex'; params: Record; } interface SpikeRule { id: string; mech: 'A' | 'B' | 'C'; hook: 'Stop' | 'PreToolUse' | 'PostToolUse' | 'UserPromptSubmit'; trigger: { response_keywords_regex?: string; context_exclude_regex?: string; }; verifier: VerifierSpec; block_message?: string; system_tag?: string; } /** * 프로덕션 rule-store 로더. * ~/.forgen/me/rules 의 Rule 중 `enforce_via` 에 `hook: 'Stop'` 이 있는 것만 * SpikeRule 내부 shape 로 변환해 반환한다. * * 변환 규칙: * - `trigger_keywords_regex` 미지정 → DEFAULT_STOP_TRIGGER_RE (shared) * - `trigger_exclude_regex` 미지정 → DEFAULT_STOP_EXCLUDE_RE (shared) * - verifier.kind 는 `self_check_prompt` 또는 `artifact_check` 지원 * - 그 외 verifier 는 skip (PreToolUse 전용 tool_arg_regex 등) */ export declare function rulesFromStore(rules: Rule[]): SpikeRule[]; /** Pure core — 단위 테스트용. stdin/IO 없음. */ export declare function evaluateStop(lastAssistantMessage: string, rules: SpikeRule[]): { action: 'approve'; hit: null; } | { action: 'block'; hit: SpikeRule; reason: string; }; /** * 같은 (session, rule) 조합의 연속 block 카운트. approve 가 일어나면 0 으로 초기화. * export for tests. 부수효과: 디렉토리 생성 + 파일 쓰기. */ export declare function incrementBlockCount(sessionId: string, ruleId: string): number; export declare function resetBlockCount(sessionId: string, ruleId: string): void; /** * R9-PA2: approve 시점에 같은 session 의 pending block 을 찾아 ack 이벤트로 기록. * Mech-B 의 핵심 가치(block → retract → pass)가 실제 작동했음을 관측 가능하게 한다. * Best-effort: 실패해도 approve 자체는 영향받지 않는다. * * 기록 후 block-count 파일은 cleanup — 같은 session 의 같은 rule 이 다시 block 되면 * 새로운 카운트로 시작 (block-count 의미 보존). */ export declare function acknowledgeSessionBlocks(sessionId: string): number; export declare function logDriftEvent(event: { kind: string; session_id: string; rule_id: string; count: number; reason_preview?: string; message_preview?: string; }): void; export declare function getStuckLoopThreshold(): number; export declare function main(): Promise; export {};