/** * ADR-002 Meta trigger — drift.jsonl 누적을 읽어 rule 의 mech 재분류 후보를 산출. * * 현 스코프 (v0.4.0 follow-up): * - `stuck_loop_force_approve` 이벤트를 recent window(기본 7 일) 에서 집계. * - 같은 rule_id 에서 임계치(기본 3) 이상 발생 시 **Mech demotion 후보** 로 분류. * - demotion 은 Mech-A/B → 한 단계 완화: * - A (block 강제) → B (self-check 권고) * - B (self-check) → C (drift 측정) * - C 는 그대로 (더 강등 불가) * - dry-run 기본. `--apply` 시 rule 파일의 enforce_via[].mech 갱신 + meta_promotions 추가. * * v0.4.1+ 확장 여지 (본 파일에는 미구현): * - Mech promotion (B → A): rolling 20 injects 중 violation 0 → 승급. * 이 경로는 별도 evidence source (solution-outcomes) 필요. * - 30 일 쿨다운. */ import type { LifecycleEvent } from './types.js'; import type { EnforcementMech, Rule } from '../../store/types.js'; export interface DriftEntry { at: string; kind: string; session_id: string; rule_id: string; count: number; reason_preview?: string; message_preview?: string; } export interface DemotionCandidate { rule_id: string; event_count: number; first_at: string; last_at: string; sessions: string[]; window_days: number; current_mechs: EnforcementMech[]; } export declare function readDriftEntries(driftPath?: string): DriftEntry[]; export declare function scanDriftForDemotion(options?: { rules: Rule[]; drift?: DriftEntry[]; windowDays?: number; threshold?: number; cooldownDays?: number; now?: number; }): DemotionCandidate[]; export declare function demoteMech(from: EnforcementMech): EnforcementMech | null; export declare function promoteMech(from: EnforcementMech): EnforcementMech | null; export interface PromotionCandidate { rule_id: string; injects_rolling_n: number; violations_rolling_n: number; current_mechs: EnforcementMech[]; reason: string; } /** * rolling N 개 inject 중 violation 0 → Mech 승급 후보. * inject 추적 인프라가 완비되기 전에는 `rolling_min_injects` (기본 20) 미만이면 skip. */ export declare function scanSignalsForPromotion(options: { rules: Rule[]; rolling_min_injects?: number; cooldownDays?: number; ts?: number; signals: Map; }): PromotionCandidate[]; export declare function applyPromotion(rule: Rule, candidate: PromotionCandidate, now?: number): ApplyResult; export interface ApplyResult { rule_id: string; before_mech: EnforcementMech[]; after_mech: EnforcementMech[]; events: LifecycleEvent[]; applied: boolean; reason?: string; } export declare function applyDemotion(rule: Rule, candidate: DemotionCandidate, now?: number): ApplyResult; export declare function appendLifecycleEvents(events: LifecycleEvent[], now?: number): void; export declare function runMetaScan(args: string[]): Promise;