rm -rf를 치기 직전, 서브밀리초 만에 가로막는 Rust 방패git reset --hard, rm -rf ./src, DROP TABLE users 같은 명령이 커밋 안 된 작업을 수초 만에 날리는 사고를, 명령이 실행되기 전 정규식·AST 패턴 매칭으로 붙잡는다. 순수 Rust로 쓰였고 SIMD 가속 + Aho-Corasick quick-reject로 판정 지연이 1밀리초 미만이라, 매 명령마다 끼어들어도 개발 흐름을 체감상 방해하지 않는다.
이 문서는 "위험한 명령 목록"을 외우기 위한 게 아니라, 어떻게 셸 명령을 안전/위험으로 실시간 분류하는 엔진을 Rust로 설계했는가를 공부하기 위한 자료다 — 다층 필터링, 컨텍스트 분류, 오탐 최소화, fail-open 설계가 핵심.
(저장소: Dicklesworthstone/destructive_command_guard · 순수 Rust · MIT + OpenAI/Anthropic Rider · v0.6.6 · TrendShift 오늘 Daily #3)
dcg는 "AI 에이전트가 실행하려는 셸 명령을 실행 직전에 검사해, 파괴적이면 막고 안전하면 통과시키는 경비원(guard)"이다. 이름 그대로 Destructive Command Guard의 약자다. 에이전트가 매 명령을 실행하기 전 dcg를 PreToolUse 훅으로 호출하면, dcg는 명령 문자열을 받아 위험도를 판정하고 "허용/차단"을 응답한다.
공항 보안 검색대는 승객이 게이트를 지나기 전에 짐을 스캔해, 위험물이면 통과를 막고 안전하면 조용히 보내준다. dcg는 이 검색대를 AI 에이전트가 실행하는 모든 셸 명령 앞에 세워둔 것이다. ls·cat 같은 평범한 명령은 눈치도 못 챌 속도로 통과시키고, rm -rf /·git push --force 같은 파괴적 명령만 붙잡아 "왜 위험한지 + 안전한 대안"까지 알려준다.
중요한 건 검색대가 절대 승객 줄을 멈추지 않는다는 원칙이다 — dcg는 판정이 애매하거나 시간이 초과되면 무조건 통과시킨다(fail-open). 안전 도구가 오히려 작업을 마비시키는 사태를 설계로 막았다.
stdin으로 JSON으로 받고 "deny(차단)" 또는 조용한 허용을 응답한다. 에이전트 코드를 고칠 필요 없이 훅 설정 파일 한 줄로 붙는다.2025~2026년 코딩 에이전트가 폭발적으로 퍼지면서, "에이전트가 자율적으로 git reset --hard를 쳐서 하루치 작업이 사라졌다"는 사고담이 커뮤니티에 쌓였다. dcg가 트렌딩에 오른 건 이 구체적이고 흔한 공포를, 에이전트를 갈아치우지 않고 기존 에이전트에 훅 하나로 덧붙여 해결하기 때문이다.
dcg는 새 에이전트도, 새 셸도 아니다. Claude Code·Codex·Gemini·Copilot·Cursor·Aider 등 이미 쓰는 도구의 훅 자리에 끼어들 뿐이다. 설치 스크립트가 각 에이전트의 설정 파일(~/.claude/settings.json 등)에 dcg 훅을 기존 훅을 보존한 채 병합해준다. 도입 비용이 "명령 한 줄"이라는 점이 확산의 결정적 이유다.
매 명령마다 끼어드는 검사기는 느리면 곧바로 버려진다. dcg는 Aho-Corasick 키워드 quick-reject로 비파괴 명령 99% 이상을 정규식 없이 O(n) 한 패스로 걸러내 서브밀리초를 달성했고, 파싱 오류·타임아웃 시 무조건 통과(fail-open)라 "dcg 때문에 막혔다"가 원천적으로 안 생긴다. 안전과 무마찰(frictionless)을 동시에 잡은 설계.
단순 문자열 매칭이면 grep "rm -rf" log.txt처럼 rm -rf가 데이터로 등장하는 안전한 명령까지 막아 오탐 지옥이 된다. dcg는 모든 토큰을 Executed(실행됨)·Data(따옴표 문자열)·Comment(주석)·HeredocBody 등으로 분류해, 실제로 실행되는 파괴적 명령만 잡는다. 오탐을 줄이는 이 문맥 분류가 실사용 만족도의 핵심이다.
git·파일시스템은 기본으로 막고, 그 위에 DB(PostgreSQL·MySQL)·Docker·Kubernetes·AWS/GCP/Azure·Terraform 등 50+ 팩을 옵트인으로 켤 수 있다. 게다가 python -c "import os; os.remove('/etc/x')"처럼 인라인 스크립트나 heredoc 안에 숨은 파괴 행위까지 AST(tree-sitter)로 파고든다. "명령줄만 본다"는 얕은 검사기와 근본적으로 다른 지점.
| 비교 축 | dcg의 선택 | 흔한 대안 |
|---|---|---|
| 도입 방식 | 기존 에이전트에 훅으로 첨부 | 에이전트 자체 교체 / 수동 승인 |
| 속도 | 서브밀리초 (SIMD·Aho-Corasick) | LLM 재질의(수백 ms~초) |
| 오판 시 | Fail-open (개발 안 막음) | Fail-closed 또는 무보호 |
| 문맥 이해 | 토큰 분류 + AST로 실행부만 검사 | 단순 substring 매칭(오탐 多) |
| 커버리지 | git·fs 기본 + 50+ 팩 옵트인 | rm -rf 정도만 하드코딩 |
"위험한지 LLM에게 다시 물어보면 되잖아?"라고 생각하기 쉽다. 하지만 그건 느리고(수백 ms~초), 비싸고, 비결정적이다. dcg는 판정을 결정론적 정규식·AST 규칙으로 하기 때문에 빠르고, 재현 가능하고, 오프라인에서 돈다. "매 명령마다" 끼어들려면 이 속도와 결정성이 필수다 — LLM 게이트로는 불가능한 자리다.
dcg는 package.json도 pyproject.toml도 없는 순수 Rust 프로젝트다(edition 2024, Rust 1.85+). 바이너리명은 dcg 하나이고, 런타임 의존성이 전혀 없는 단일 정적 바이너리로 배포된다. 흥미로운 기원: Jeffrey Emanuel의 Python 스크립트에서 출발 → Darin Gordon(Dowwie)이 성능을 위해 Rust로 포팅 → 다시 모듈형 팩 시스템·AST 탐지로 대폭 확장된 2인 릴레이 프로젝트다.
| 영역 | 크레이트 | 역할 / 왜 골랐나 |
|---|---|---|
| 정규식(백트래킹) | fancy-regex | lookahead/lookbehind가 필요한 패턴용 (예: (?!--staged)) |
| 정규식(선형) | regex (RegexSet) | safe 패턴 다수를 한 번에 선형시간 검사 |
| 빠른 필터 | aho-corasick | 여러 위험 키워드를 하나의 오토마톤으로 묶어 O(n) quick-reject |
| SIMD 검색 | memchr | substring 탐색을 CPU SIMD로 가속 |
| AST 매칭 | ast-grep-core + tree-sitter | bash·python·js·ts·ruby·go·php 스크립트 내부 파싱 |
| 설정 | toml · serde_yaml · schemars | config.toml + 외부 팩 YAML + JSON Schema 생성 |
| CLI/TUI | clap · ratatui · inquire · indicatif | 서브커맨드·대화형 설정·진행바 |
| 히스토리 | fsqlite (FrankenSQLite, FTS5) | 차단/허용 이력을 전문검색 가능한 SQLite로 기록 |
| MCP 서버 | rust-mcp-sdk + tokio | dcg 자신이 MCP 서버로도 동작 |
| 보안 | sha2 · hmac · self_update | allow-once 단축코드 하드닝 · 서명 검증 자동 업데이트 |
rm·git·dd·docker 같은 위험 키워드 전부를 여기에 넣고, 명령에 위험 키워드가 하나도 없으면 즉시 통과시킨다. 비싼 정규식은 키워드가 걸렸을 때만 돌린다.python -c "..."의 따옴표 안이나 heredoc 안에 든 진짜 코드를 tree-sitter로 파싱해, os.remove(...)·shutil.rmtree(...) 같은 파괴 함수 호출을 잡는다. 명령줄 표면만 보는 게 아니라 코드 구조 수준에서 위험을 탐지하는 것.이게 dcg 스택에서 가장 배울 점이다. 정규식 엔진에는 트레이드오프가 있다: Rust의 regex 크레이트는 선형시간을 보장하지만 lookahead/lookbehind를 못 쓴다. 반대로 fancy-regex는 그걸 쓸 수 있지만 백트래킹이라 최악의 경우 느려질 수 있다. dcg는 둘을 용도별로 나눠 쓴다 — 백트래킹이 필요 없는 다수의 safe 패턴은 regex::RegexSet으로 한 방에, lookahead가 꼭 필요한 소수만 fancy-regex로.
dcg의 핵심은 딱 하나의 질문에 답하는 것이다: "이 명령 문자열, 실행해도 되나?" 그 판정이 어떻게 흐르는지 전체 그림부터 보자. 에이전트가 stdin으로 JSON을 넣어주면 dcg가 파이프라인을 태우고, stdout으로 허용/차단 결정을, stderr로 사람용 컬러 경고를 뱉는다.
설계 철학은 단계별 조기 종료(short-circuit)다. 대부분의 명령(ls·cat·echo)은 위험 키워드가 없으니 ③번 Aho-Corasick에서 정규식 한 번 안 돌리고 통과한다. 비싼 정규식·AST 검사는 키워드가 걸린 소수의 명령에만 적용된다. 이 순서 덕에 "매 명령마다" 끼어들어도 서브밀리초가 나온다.
공항 검색대도 모든 짐을 열어보지 않는다. 먼저 금속 탐지기(빠름)를 통과시키고, 삐 소리가 난 사람만 정밀 수색(느림)을 한다. dcg의 Aho-Corasick이 금속 탐지기, 정규식·AST가 정밀 수색이다. 99%는 삐 소리 없이 지나간다.
모든 탐지 규칙은 팩이라는 단위로 묶인다. core.git·core.filesystem은 항상 켜지고, database.postgresql·containers.docker·cloud.aws 같은 50+ 팩은 옵트인이다. 각 팩은 아래 구조를 갖는다:
// src/packs/mod.rs — 팩 하나의 뼈대 (개념 요약)
pub struct Pack {
id: &str, // "core.git"
keywords: &[&str], // Aho-Corasick에 넣을 트리거 단어
safe_patterns: &[SafePattern], // 먼저 검사 → 걸리면 "허용"
destructive_patterns: &[DestructivePattern], // 걸리면 "차단"
keyword_matcher: AhoCorasick, // 팩별 quick-reject 오토마톤
safe_regex_set: RegexSet, // safe 패턴 선형시간 일괄 검사
}
pub struct DestructivePattern {
regex: LazyCompiledRegex, // 처음 쓸 때만 컴파일(지연)
reason: &str, // "왜 위험한가" 설명
severity: Severity, // Critical / High / Medium / Low
suggestions: &[PatternSuggestion], // 안전한 대안 제시
}
safe 패턴을 destructive보다 먼저 검사하는 순서가 핵심이다. 예를 들어 git checkout -b feature(새 브랜치, 안전)는 safe 패턴에 먼저 걸려 통과하고, git checkout -- file.txt(작업 내용 폐기, 위험)는 safe에 안 걸린 뒤 destructive에 걸려 차단된다. "허용을 먼저 확정"하는 whitelist-first 방식이라 오탐이 줄어든다.
같은 rm -rf / 문자열이라도, 그게 실행되는지 vs 데이터로 등장하는지는 하늘과 땅 차이다. dcg는 명령의 모든 토큰을 다음처럼 분류한다:
| SpanKind | 의미 | 검사 여부 |
|---|---|---|
| Executed | 실제로 실행되는 명령 부분 | 반드시 검사 |
| InlineCode | -c/-e 플래그 뒤의 코드 | 반드시 검사(AST로 escalate) |
| Data | 작은따옴표 문자열 등 데이터 | 건너뛸 수 있음 |
| HeredocBody | heredoc(<<EOF) 본문 | Tier2/3 스캔으로 escalate |
| Comment | # 뒤 주석 | 건너뜀 |
| Unknown | 애매한 토큰 | 보수적으로 Executed 취급 |
그래서 grep "rm -rf" install.log의 rm -rf는 Data로 분류돼 통과하고, 진짜 rm -rf /var는 Executed라 차단된다. 애매하면 Executed로 취급(안전 우선)하는 보수적 기본값이 zero-false-negative(놓침 없음) 철학을 받친다.
진짜 위험한 명령은 종종 다른 언어 코드 속에 숨는다. python3 -c "import shutil; shutil.rmtree('/data')"는 명령줄만 보면 그냥 python 실행이다. dcg는 이걸 3단계로 판다:
AST 파싱은 정규식보다 무겁다. dcg는 ast_matcher.rs에 20ms hard timeout을 걸어, 이상하게 복잡한 입력으로 파싱이 오래 걸리면 차단이 아니라 허용으로 빠져나온다. 매 파이프라인 단계마다 deadline_exceeded를 확인하는 이 "시간 예산" 패턴은, 안전 도구가 절대 개발 흐름을 인질로 잡지 않게 하는 실전 설계다.
공격자(혹은 에이전트의 실수)는 r''m -rf, r\m -rf처럼 글자 사이에 빈 따옴표·백슬래시를 끼워 정규식을 우회하려 할 수 있다. dcg는 contains_shell_word_obfuscation으로 이런 위장을 탐지해 quick-reject 단계에서 정규식 검사로 escalate한다. 실제 이슈(#121·#124)에서 배운 정규식 세그먼트 가두기([^\s&;|`()<>]+로 셸 메타문자를 만나면 멈추기)도 오탐 방지에 쓰인다.
규칙이 추상적으로 느껴질 테니, 항상 켜지는 두 팩의 실제 패턴을 보자. core.git은 비활성화 자체가 불가능하다.
| 팩 / 이름 | 정규식(발췌) | 심각도 |
|---|---|---|
| git · reset-hard | reset\s+--hard | Critical |
| git · push-force | push\s+…--force / -[a-zA-Z]*f | Critical |
| git · checkout-discard | checkout\s+--\s+ | High |
| git · clean-force | clean\s+(?:-[a-z]*f|--force) | High |
| git · stash-drop/clear | stash\s+(drop|clear) | High |
| fs · rm-rf-general | rm\s+-[a-zA-Z]*[rR][a-zA-Z]*f | High |
| fs · dd / shred / truncate | 디스크·파일 파괴 계열 | High |
여기서 rm-rf-general 정규식이 특히 영리하다. 단순히 rm -rf만 잡는 게 아니라 rm\s+-[a-zA-Z]*[rR][a-zA-Z]*f — 즉 플래그 글자 사이에 다른 글자가 끼어도(-rvf, -fr, -Rf 등) 전부 잡는다. --recursive --force 분리형, find -delete, unlink까지 별도 패턴으로 커버한다.
// src/packs/core/filesystem.rs — 실제 매크로 (발췌)
destructive_pattern!(
"rm-rf-general",
r"rm\s+-[a-zA-Z]*[rR][a-zA-Z]*f|rm\s+-[a-zA-Z]*f[a-zA-Z]*[rR]",
"rm -rf is destructive and requires human approval...",
High,
);
반대로 safe 패턴도 세심하다. rm -rf /tmp/*, rm -rf $TMPDIR/*처럼 임시 디렉토리 청소는 명시적으로 허용 목록에 있어서 오탐을 안 낸다. git 쪽도 checkout -b(새 브랜치), restore --staged(스테이징 취소, 파일은 안전), clean --dry-run은 전부 safe로 통과시킨다.
구조를 읽는 요령: "판정 로직"은 evaluator.rs + packs/, "에이전트와의 대화"는 hook.rs + agent.rs, "오탐 방지 두뇌"는 context.rs + ast_matcher.rs. 이 다섯 파일이 시스템의 90%다.
| 정독 우선순위 | 파일 | 배우는 것 |
|---|---|---|
| ★★★ | src/evaluator.rs | 4단계 파이프라인 · 조기 종료 · deadline 예산 |
| ★★★ | src/packs/mod.rs | 팩 구조 · 매크로 DSL · lazy 정규식 컴파일 |
| ★★★ | src/context.rs | SpanKind 토큰 분류 — 오탐 제거의 핵심 |
| ★★ | src/ast_matcher.rs | tree-sitter로 인라인 코드 파고들기 + timeout |
| ★★ | src/hook.rs | 에이전트별 wire 포맷(Claude vs Codex 차이) |
| ★ | tests/corpus/*.toml | 안전 도구를 코퍼스로 검증하는 법 |
"모든 입력에 끼어드는" 시스템(방화벽·WAF·린터·검색대)의 보편적 교훈. 싼 검사(Aho-Corasick) → 비싼 검사(정규식) → 더 비싼 검사(AST) 순으로 조기 종료를 설계하면, 99%의 평범한 입력이 무거운 검사에 도달하지 않는다. 이 short-circuit 사고는 언어·도메인 불문 응용 가능하다.
선형시간 regex(RegexSet) vs 백트래킹 fancy-regex를 용도별로 섞어 쓰는 실전 사례. "lookahead가 꼭 필요한가?"를 패턴마다 따져 엔진을 고르는 감각은, 정규식 성능 문제(ReDoS 포함)를 만나는 모든 개발자에게 값지다.
substring/정규식만으로는 grep "rm -rf"와 rm -rf를 구별 못 한다. dcg는 토큰 문맥 분류(SpanKind) + AST 파싱으로 "표면이 아니라 의미"를 본다. 코드 리뷰 도구·SAST·문법 하이라이터 등 "코드를 이해해야 하는" 모든 도구에 그대로 적용되는 발상.
보안 교과서는 보통 "막고 보자(fail-closed)"를 가르치지만, dcg는 개발 생산성이 최우선인 맥락에서 의도적으로 fail-open을 골랐다. "우리 시스템이 실패하면 어느 쪽으로 실패해야 하나?"를 비즈니스 맥락으로 판단하는 성숙한 엔지니어링 사례.
tests/corpus/에 true_positives(잡아야 할 것)·false_positives(잡으면 안 될 것)·bypass_attempts(우회 시도)를 TOML로 분리하고, 버그마다 repro_*.rs 회귀 테스트를 남긴다. "탐지기가 스스로를 어떻게 검증하는가"의 모범 사례 — 안티바이러스·스팸필터·린터 만드는 사람 필독.
dcg는 알려진 파괴 패턴을 막는 도구다. 새로운 우회 기법, 팩에 없는 명령, 애매해서 fail-open으로 빠진 케이스는 놓칠 수 있다(README도 이를 명시). 진짜 안전망은 여전히 git 커밋·백업이고, dcg는 "실수가 재앙이 되기 전에 붙잡는 한 겹"일 뿐이다. 이 도구를 믿고 백업을 소홀히 하면 본말전도다.
레포를 클론해 tests/corpus/의 TOML을 열어보라. "이건 왜 false_positive(막으면 안 됨)로 분류됐지?"를 하나씩 읽으면, 실무에서 어떤 명령이 오탐을 유발하는지에 대한 직관이 생긴다. 그다음 dcg explain "git reset --hard"를 실제로 돌려 설명·대안 출력을 확인해보라.
| 항목 | 요구사항 |
|---|---|
| 플랫폼 | Linux · macOS · Windows(WSL 및 네이티브 PowerShell) |
| 런타임 의존성 | 없음 (단일 정적 바이너리 dcg) |
| 메모리/CPU | 사실상 무시할 수준 (매 명령마다 서브밀리초 실행 후 종료) |
| 설치 방식 | install.sh(curl 파이프) / install.ps1 — 아키텍처 자동감지 + SHA256/cosign 서명 검증 |
| 소스 빌드 시 | Rust nightly (rust-toolchain.toml로 핀 고정, edition 2024) |
| 설정 파일 | ~/.config/dcg/config.toml (dcg init으로 생성, 없어도 기본 팩 동작) |
| 지원 에이전트 | Claude Code · Codex CLI · Gemini CLI · Copilot CLI · Cursor · Hermes · Grok · Aider(git hook) 등 |
설치 원리: 설치 스크립트가 GitHub Releases에서 플랫폼별 tar.xz를 받아 체크섬(있으면 cosign 서명까지) 검증 후, 각 에이전트의 훅 설정 파일에 dcg를 PreToolUse 훅 맨 앞에 병합한다. 기존 훅은 보존하고, 손상된(malformed) JSON은 덮어쓰기를 거부하는 방어적 설치가 특징이다.
curl … | bash 형태다. 이 패턴은 편하지만 원격 스크립트를 그대로 실행하는 것이라, 원칙적으로는 스크립트를 먼저 내려받아 눈으로 확인한 뒤 실행하는 게 안전하다. dcg가 서명 검증을 넣은 것도 이 신뢰 문제를 의식한 설계다. (역설적이지만, 파괴 명령을 막는 도구조차 설치 단계에서는 이 신뢰 결정을 요구한다.)레포를 git clone --depth 1로 받아 tests/corpus/의 TOML을 읽고, "잡아야 할 명령(true_positive)"과 "막으면 안 될 명령(false_positive)"을 각각 10개씩 손으로 옮겨 적어보라. 안전/위험의 경계가 어디인지 몸으로 익히는 연습.
위험 키워드 리스트로 1차 quick-reject(키워드 없으면 즉시 통과)를 만들고, 걸린 것만 정규식으로 정밀 판정하는 미니 가드를 100줄로 짜보라. ls·echo 같은 명령이 정규식에 도달조차 안 하는 걸 로그로 확인할 것.
과제 2를 확장해, 따옴표 안 문자열은 Data로 보고 건너뛰도록 간단한 토큰 분류를 추가하라. grep "rm -rf" a.log는 통과하고 rm -rf /tmp/x는 차단되면 성공. 셸 인용 규칙을 파싱하는 어려움을 체감할 것.
과제 3의 가드를 stdin으로 JSON을 받아 {"permissionDecision":"deny", ...}를 stdout으로 뱉는 형태로 감싸, Claude Code의 PreToolUse 훅에 등록하라. 실제로 위험 명령이 막히는지 확인. (안전한 테스트 명령으로만!)
tree-sitter(또는 언어 내장 AST)로 python -c "..."의 코드를 파싱해, os.remove·shutil.rmtree 같은 파괴 함수 호출을 탐지하라. 파싱에 타임아웃을 걸고 초과 시 fail-open으로 빠지는 것까지 구현하면 dcg의 Tier3를 재현한 것.
| 주차 | 주제 | 학습 내용 |
|---|---|---|
| 1주차 | 정규식 & 문자열 알고리즘 | 정규식 엔진의 원리(NFA/DFA vs 백트래킹), ReDoS, Aho-Corasick·memchr 같은 다중 패턴/SIMD 검색. dcg의 packs/core/*.rs 패턴 읽기 + 과제 2. |
| 2주차 | 셸 파싱 & 문맥 분류 | 셸 인용·이스케이프·heredoc 문법, 토큰화, SpanKind 같은 문맥 태깅. context.rs·heredoc.rs 정독 + 과제 3. |
| 3주차 | AST & tree-sitter | 추상 구문 트리, tree-sitter 쿼리, sink 함수 재귀 탐색, 파싱 타임아웃. ast_matcher.rs 정독 + 과제 5. |
| 4주차 | 에이전트 훅 & 배포 | Claude Code/Codex 훅 프로토콜 차이, JSON wire 포맷, 서명 검증 설치, GitHub Action. hook.rs·install.sh 읽기 + 과제 4. |
먼저 빠른 패턴 매칭(1주차)을 확실히 잡아라. 그게 되면 왜 그것만으로 부족한지(오탐)가 보이고, 그때 문맥 분류·AST(2~3주차)의 필요성이 자연스럽게 이해된다. 훅 연동(4주차)은 "어떻게 에이전트에 붙느냐"의 배관 작업이라 맨 뒤로 미뤄도 된다.
core.git·core.filesystem은 항상 켜지고, DB·Docker·클라우드 등 50+ 팩은 옵트인.grep "rm -rf"를 통과시키는 오탐 방지의 핵심.<<EOF … EOF로 여러 줄 텍스트를 명령에 넘기는 문법. 파괴 명령이 여기 숨을 수 있어 dcg가 본문을 추출해 재검사한다.python -c 등 인라인 코드를 파싱해 os.remove 같은 파괴 함수 호출을 잡는다.regex 크레이트의 기능. 여러 패턴을 한 번에 선형시간으로 검사하되 lookahead는 못 쓴다. dcg는 safe 패턴 다수를 여기서 일괄 검사.DCG_BYPASS=1 명령은 그 한 번만, 차단 메시지의 단축코드로 dcg allow-once도 가능.| 구분 | 링크 / 위치 |
|---|---|
| GitHub 저장소 | github.com/Dicklesworthstone/destructive_command_guard |
| TrendShift | trendshift.io/repositories/40043 |
| 핵심 파일 | src/evaluator.rs (4단계 평가 파이프라인) |
| 핵심 파일 | src/packs/mod.rs · packs/core/git.rs · filesystem.rs (탐지 규칙) |
| 핵심 파일 | src/context.rs (SpanKind 문맥 분류) |
| 핵심 파일 | src/ast_matcher.rs · heredoc.rs (인라인 스크립트 탐지) |
| 핵심 파일 | src/hook.rs · agent.rs (에이전트 훅 프로토콜) |
| 검증 | tests/corpus/*.toml (true/false positive 코퍼스) |
| 연관 개념 | Aho-Corasick · tree-sitter · Rust regex/fancy-regex · MCP 훅 |