설정 범위
우선순위 순서대로 평가되는 세 가지 설정 범위가 있습니다:| 범위 | 파일 경로 | 용도 |
|---|---|---|
| project | .failproofai/policies-config.json | 버전 관리에 커밋되는 저장소별 설정 |
| local | .failproofai/policies-config.local.json | gitignore 처리되는 개인 저장소별 재정의 |
| global | ~/.failproofai/policies-config.json | 모든 프로젝트에 적용되는 사용자 수준 기본값 |
병합 규칙
enabledPolicies — 세 범위의 합집합입니다. 어느 수준에서든 활성화된 정책은 적용됩니다.
policyParams — 특정 정책의 파라미터를 처음 정의한 범위가 전체 우선권을 가집니다. 정책 파라미터 내의 값은 깊은 병합을 수행하지 않습니다.
customPoliciesPath — 처음 정의한 범위가 우선권을 가집니다.
llm — 처음 정의한 범위가 우선권을 가집니다.
설정 파일 형식
필드 참조
enabledPolicies
타입: string[]
활성화할 정책 이름 목록입니다. 이름은 failproofai policies가 표시하는 정책 식별자와 정확히 일치해야 합니다. 전체 목록은 기본 제공 정책을 참고하세요.
enabledPolicies에 없는 정책은 policyParams에 항목이 있더라도 비활성화됩니다.
policyParams
타입: Record<string, Record<string, unknown>>
정책별 파라미터 재정의입니다. 외부 키는 정책 이름이고, 내부 키는 정책별로 다릅니다. 각 정책의 사용 가능한 파라미터는 기본 제공 정책에서 확인할 수 있습니다.
파라미터가 있는 정책에 파라미터를 지정하지 않으면 정책의 기본값이 사용됩니다. policyParams를 전혀 설정하지 않은 사용자는 이전 버전과 동일하게 동작합니다.
정책 파라미터 블록 내의 알 수 없는 키는 훅 실행 시 조용히 무시되지만, failproofai policies를 실행하면 경고로 표시됩니다.
hint (공통 옵션)
타입: string (선택 사항)
정책이 deny 또는 instruct를 반환할 때 이유에 추가되는 메시지입니다. 정책 자체를 수정하지 않고도 Claude에게 실행 가능한 지침을 제공하는 데 사용합니다.
기본 제공, 커스텀(custom/), 프로젝트 규칙(.failproofai-project/), 사용자 규칙(.failproofai-user/) 등 모든 정책 유형에서 사용할 수 있습니다.
block-force-push가 차단하면 Claude는 다음과 같이 확인합니다: “Force-pushing is blocked. Try creating a fresh branch instead.”
문자열이 아닌 값과 빈 문자열은 조용히 무시됩니다. hint가 설정되지 않으면 동작이 변경되지 않습니다 (하위 호환 유지).
customPoliciesPath
타입: string (절대 경로)
커스텀 훅 정책이 포함된 JavaScript 파일의 경로입니다. failproofai policies --install --custom <path>를 사용하면 자동으로 설정됩니다 (경로는 저장 전에 절대 경로로 변환됩니다).
이 파일은 매 훅 이벤트마다 새로 로드됩니다 — 캐싱이 없습니다. 작성 방법은 커스텀 정책을 참고하세요.
규칙 기반 정책
명시적인customPoliciesPath 외에도 failproofai는 .failproofai/policies/ 디렉토리에서 정책 파일을 자동으로 검색하고 로드합니다:
| 수준 | 디렉토리 | 범위 |
|---|---|---|
| 프로젝트 | .failproofai/policies/ | 버전 관리를 통해 팀과 공유 |
| 사용자 | ~/.failproofai/policies/ | 개인용, 모든 프로젝트에 적용 |
*policies.{js,mjs,ts} 패턴에 맞는 파일만 로드됩니다 (예: security-policies.mjs, workflow-policies.js). 디렉토리의 다른 파일은 무시됩니다.
설정 불필요: 규칙 기반 정책은 policies-config.json에 항목이 필요하지 않습니다. 디렉토리에 파일을 넣기만 하면 다음 훅 이벤트에서 자동으로 로드됩니다.
통합 로드: 프로젝트와 사용자 규칙 디렉토리가 모두 스캔됩니다. 두 수준의 모든 매칭 파일이 로드됩니다 (첫 번째 범위가 우선권을 갖는 customPoliciesPath와 다릅니다).
자세한 내용과 예시는 커스텀 정책을 참고하세요.
llm
타입: object (선택 사항)
AI 호출을 수행하는 정책을 위한 LLM 클라이언트 설정입니다. 대부분의 경우 필요하지 않습니다.
CLI에서 설정 관리
policies --install 및 policies --uninstall 명령은 에이전트 CLI의 훅 설정 파일(훅 진입점)에 씁니다. policies-config.json은 직접 관리하는 파일로, 두 가지는 분리되어 있습니다:
- 에이전트 CLI 설정 — 에이전트가 각 도구 사용 시
failproofai --hook <event>를 호출하도록 지시합니다:- Claude Code:
~/.claude/settings.json(사용자),<cwd>/.claude/settings.json(프로젝트),<cwd>/.claude/settings.local.json(로컬) - OpenAI Codex:
~/.codex/hooks.json(사용자),<cwd>/.codex/hooks.json(프로젝트) — Codex에는local범위가 없습니다 - GitHub Copilot CLI (베타):
~/.copilot/hooks/failproofai.json(사용자),<cwd>/.github/hooks/failproofai.json(프로젝트) — Copilot에는local범위가 없습니다. 훅 항목은 Copilot의 OS별bash/powershell명령 필드와timeoutSec을 사용하며, 파일에는 최상위version: 1마커가 있습니다. Copilot CLI 지원은events.jsonl레코드 스키마(공개 문서에 명시되지 않음)를 더 많은 실제 세션에서 검증하는 동안 베타 상태입니다. - Cursor Agent (베타):
~/.cursor/hooks.json(사용자),<cwd>/.cursor/hooks.json(프로젝트) — Cursor에는local범위가 없습니다. 훅 항목은 Claude 형식의{type, command, timeout}형태를 사용하지만, Cursor의 hooks 스키마에 따라 camelCase 이벤트 키(preToolUse,beforeSubmitPrompt, …) 아래의 플랫 배열에 저장됩니다. 파일에는 최상위version: 1마커가 있습니다. 핸들러는CURSOR_EVENT_MAP을 통해 camelCase를 PascalCase로 정규화하므로 기존 기본 정책이 변경 없이 실행됩니다. Cursor Agent 지원은 Cursor의 전사본 온디스크 형식(공개 문서에 명시되지 않음)을 더 많은 실제 설치 환경에서 검증하는 동안 베타 상태입니다. - OpenCode (베타):
~/.config/opencode/opencode.json+~/.config/opencode/plugins/failproofai.mjs(사용자),<cwd>/.opencode/opencode.json+<cwd>/.opencode/plugins/failproofai.mjs(프로젝트) — OpenCode에는local범위가 없습니다. 다른 여섯 CLI와 달리 OpenCode에는 외부 명령 훅 시스템이 없습니다:opencode.json의plugin: []배열을 통해 명시적으로 등록된 인프로세스 JS/TS 플러그인을 로드합니다 (.opencode/plugins/에서의 자동 검색은 opencode v1.14.33에서 플러그인이 로드되는 방식이 아닙니다). 설치 시 failproofai 바이너리를 서브프로세스로 호출하고 바이너리의 Claude 형식 JSON 응답을 플러그인 시맨틱으로 변환하는 소형 생성 플러그인 심(shim)을 생성합니다: 도구 이벤트 deny에는throw new Error()(도구 호출 취소), instruct 및Stop/SubagentStopdeny에는client.session.prompt(...)(deny 이유를 다음 사용자 메시지로 제출 —session.idle은 알림 전용이고 throw는 무작동이므로 이 채널이 유일한 강제 재시도 채널), allow에는 무작동. 심은 도구 이름(소문자 →OPENCODE_TOOL_MAP을 통한 PascalCase)과 도구 입력 인수 키(Read/Write/Edit에 대해OPENCODE_TOOL_INPUT_MAP을 통한 camelCase → snake_case, 예:filePath→file_path,oldString→old_string)를 정규화한 후 바이너리로 전달하므로,block-read-outside-cwd,block-env-files,block-secrets-write와 같은 경로 확인 기본 정책이 OpenCode 도구 호출에서 변경 없이 실행됩니다. 세션은~/.local/share/opencode/opencode.db의 opencode SQLite DB에 저장되며, 대시보드의 세션 뷰어는opencode db --format json및opencode export <id>를 통해 읽습니다. OpenCode 지원은 버전 간 동작과 더 많은 실제 세션을 검증하는 동안 베타 상태입니다. OpenCode 플러그인 문서를 참고하세요. - Pi (베타):
~/.pi/agent/settings.json(사용자),<cwd>/.pi/settings.json(프로젝트) — Pi에는local범위가 없습니다. Pi는 시작 시 TypeScript 확장 패키지를 로드하며, 설정 파일은 플랫 문자열 배열{"packages": ["./relative/path", …]}입니다. failproofai는 번들된pi-extension/디렉토리를 가리키는 단일 packages 배열 항목을 씁니다. 확장은 내부적으로 Pi의tool_call/user_bash/input/session_start이벤트를 구독하고failproofai --hook <Event> --cli pi를 쉘 아웃합니다. 핸들러는PI_EVENT_MAP을 통해 underscore_lower_snake_case를 PascalCase로 정규화하므로 기존 기본 정책이 변경 없이 실행됩니다. 도구 입력 인수도PI_TOOL_INPUT_MAP을 통해 정규화됩니다 (Pi의 Read/Write/Edit는file_path대신path를 전달하며, 최상위 키를 매핑하면block-env-files와block-secrets-write가 실행됩니다 —block-read-outside-cwd는 이미path폴백을 가지고 있었습니다). Pi 지원은 Pi의 확장 API와 세션 로그 레이아웃이 안정화되는 동안 베타 상태입니다. - Gemini CLI (베타):
~/.gemini/settings.json(사용자),<cwd>/.gemini/settings.json(프로젝트) — Gemini에는local범위가 없습니다 (failproofai가 노출하지 않는/etc/gemini-cli/settings.json의system범위를 문서화하고 있습니다). 훅 항목은 기본적으로matcher: "*"를 사용하는 Gemini의{matcher, hooks: [...]}매처 스키마로 래핑된 Claude의{type, command, timeout}형태를 사용합니다. 이벤트는 PascalCase(SessionStart,BeforeAgent,AfterAgent,BeforeModel,AfterModel,BeforeToolSelection,BeforeTool,AfterTool,PreCompress,Notification,SessionEnd)이며, 핸들러는GEMINI_EVENT_MAP을 통해 Claude 표준 이름으로 매핑합니다. 도구 이름은 snake_case(run_shell_command,read_file,write_file,replace, …)이며, 핸들러는GEMINI_TOOL_MAP을 통해 정규화하므로 기존 기본 정책이 변경 없이 실행됩니다. 정책 평가기는 Gemini의 플랫{decision: "deny", reason}형태 (Gemini의 “Golden Rule” exit-0 계약에 따른 선호 형식), BeforeAgent/AfterTool/SessionStart에서의 컨텍스트 주입을 위한{hookSpecificOutput: {hookEventName, additionalContext}}, 그리고 강제 재시도 시맨틱을 위한 AfterAgent의{decision: "block", reason}을 반환합니다. Gemini CLI 지원은 실제 환경 커버리지를 넓히는 동안 베타 상태입니다. Gemini CLI 훅 문서를 참고하세요.
- Claude Code:
policies-config.json— failproofai에게 어떤 정책을 평가할지, 어떤 파라미터로 평가할지 알려줍니다 (모든 에이전트 CLI에서 공유)
--cli claude|codex|copilot|cursor|opencode|pi|gemini를 전달하세요 (공백으로 구분하거나 반복 사용으로 부분 집합 선택):
--cli를 생략하면 failproofai는 설치된 에이전트 CLI를 자동 감지합니다 (which claude/which codex/which copilot/which cursor-agent/which opencode/which pi/which gemini):
- 하나의 CLI 감지됨 — 확인 없이 해당 CLI를 자동 선택합니다.
- 여러 CLI가 대화형 터미널에서 감지됨 —
Detected (N)섹션(개별 감지된 CLI와Install for all N detected집계 행 포함) 및Not installed (M) · install hooks ahead of time섹션(감지되지 않은 지원 CLI를 사전 설치 옵션으로 표시)이 있는 화살표 키 단일 선택 프롬프트를 표시합니다 (↑↓로 이동, Enter로 선택, ^C로 종료). 제거 흐름에는 Detected 섹션만 표시됩니다. - 여러 CLI가 비대화형 실행에서 감지됨 (CI, TTY 없음) — 확인 없이 감지된 모든 CLI에 설치합니다.
- 감지된 CLI 없음 — PATH에서 에이전트 바이너리를 찾을 수 없다는 경고와 함께
claude로 폴백합니다. 훅 명령은 여전히 작성되므로 에이전트를 설치하는 즉시 활성화됩니다.
policies-config.json은 언제든지 직접 편집할 수 있으며, 다음 훅 이벤트에서 즉시 적용됩니다 — 재시작이 필요 없습니다.
예시: 팀 기본값이 포함된 프로젝트 수준 설정
저장소에.failproofai/policies-config.json을 커밋하세요:
.failproofai/policies-config.local.json (gitignore 처리)을 생성할 수 있습니다.
