failproofai 0.0.5 → 0.0.6-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.failproofai/policies/review-policies.mjs +112 -0
- package/.next/standalone/.failproofai/policies/workflow-policies.mjs +2 -1
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +2 -2
- package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g72weg._.js +1 -1
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_0z7w.hh._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__092s1ta._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09icjsf._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g.lg8b._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h..k-e._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0okos0k._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0a~g15g._.js → [root-of-the-server]__0rh.18_._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w6l33k._.js +6 -6
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0qn95h3._.js → [root-of-the-server]__0~kmh8w._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11pa2ra._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12t-wym._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_10lm7or._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_0xerkr6._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_0q-m0y-._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
- package/.next/standalone/.next/server/pages/404.html +2 -2
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +9 -9
- package/.next/standalone/.next/static/chunks/{0sme4lkv.tgn-.js → 01b~z8f1ws0rk.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0lgbwkfqmnsmc.js → 03rz6ykw-a2xi.js} +1 -1
- package/.next/standalone/.next/static/chunks/{17manv47o-~wp.js → 08t08igdql9yt.js} +1 -1
- package/.next/standalone/.next/static/chunks/09_k80d~cq2wg.js +4 -0
- package/.next/standalone/.next/static/chunks/{0ksdlt_1hucdm.js → 0bvhsa6zva2o..js} +1 -1
- package/.next/standalone/.next/static/chunks/{09ikntpt2-o9b.js → 0gbf4cphy8ksq.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0yumumfzx_f27.js → 0v.yd0kg_ld3r.js} +1 -1
- package/.next/standalone/.next/static/chunks/{13juklu.vksks.js → 0wlyoif4_kj_t.js} +1 -1
- package/.next/standalone/.next/static/chunks/{09e7drilkf1sn.js → 12simlrcfk3g2.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0em7tspi4kylh.js → 12~yi9oj8av8p.js} +2 -2
- package/.next/standalone/.next/static/chunks/{turbopack-0r26pc8h0y_-e.js → turbopack-0o7k.hakttp4k.js} +1 -1
- package/.next/standalone/CHANGELOG.md +13 -0
- package/.next/standalone/README.md +2 -2
- package/.next/standalone/bun.lock +43 -85
- package/.next/standalone/dist/cli.mjs +107 -3
- package/.next/standalone/docs/ar/architecture.mdx +65 -64
- package/.next/standalone/docs/ar/configuration.mdx +42 -42
- package/.next/standalone/docs/ar/custom-policies.mdx +62 -64
- package/.next/standalone/docs/built-in-policies.mdx +37 -0
- package/.next/standalone/docs/custom-policies.mdx +1 -1
- package/.next/standalone/docs/de/architecture.mdx +92 -92
- package/.next/standalone/docs/de/configuration.mdx +34 -34
- package/.next/standalone/docs/de/custom-policies.mdx +49 -50
- package/.next/standalone/docs/es/architecture.mdx +72 -72
- package/.next/standalone/docs/es/configuration.mdx +25 -25
- package/.next/standalone/docs/es/custom-policies.mdx +48 -49
- package/.next/standalone/docs/examples.mdx +54 -0
- package/.next/standalone/docs/fr/architecture.mdx +53 -53
- package/.next/standalone/docs/fr/configuration.mdx +25 -25
- package/.next/standalone/docs/fr/custom-policies.mdx +42 -43
- package/.next/standalone/docs/getting-started.mdx +52 -0
- package/.next/standalone/docs/he/architecture.mdx +66 -66
- package/.next/standalone/docs/he/configuration.mdx +53 -52
- package/.next/standalone/docs/he/custom-policies.mdx +72 -73
- package/.next/standalone/docs/hi/architecture.mdx +106 -106
- package/.next/standalone/docs/hi/configuration.mdx +39 -39
- package/.next/standalone/docs/hi/custom-policies.mdx +75 -76
- package/.next/standalone/docs/i18n/README.ar.md +66 -66
- package/.next/standalone/docs/i18n/README.de.md +38 -38
- package/.next/standalone/docs/i18n/README.es.md +38 -38
- package/.next/standalone/docs/i18n/README.fr.md +42 -42
- package/.next/standalone/docs/i18n/README.he.md +67 -67
- package/.next/standalone/docs/i18n/README.hi.md +70 -70
- package/.next/standalone/docs/i18n/README.it.md +62 -62
- package/.next/standalone/docs/i18n/README.ja.md +54 -54
- package/.next/standalone/docs/i18n/README.ko.md +58 -58
- package/.next/standalone/docs/i18n/README.pt-br.md +43 -43
- package/.next/standalone/docs/i18n/README.ru.md +69 -69
- package/.next/standalone/docs/i18n/README.tr.md +76 -76
- package/.next/standalone/docs/i18n/README.vi.md +70 -70
- package/.next/standalone/docs/i18n/README.zh.md +52 -52
- package/.next/standalone/docs/it/architecture.mdx +54 -53
- package/.next/standalone/docs/it/configuration.mdx +44 -45
- package/.next/standalone/docs/it/custom-policies.mdx +76 -78
- package/.next/standalone/docs/ja/architecture.mdx +93 -93
- package/.next/standalone/docs/ja/configuration.mdx +47 -47
- package/.next/standalone/docs/ja/custom-policies.mdx +62 -63
- package/.next/standalone/docs/ko/architecture.mdx +66 -66
- package/.next/standalone/docs/ko/configuration.mdx +35 -35
- package/.next/standalone/docs/ko/custom-policies.mdx +71 -72
- package/.next/standalone/docs/pt-br/architecture.mdx +55 -55
- package/.next/standalone/docs/pt-br/configuration.mdx +35 -35
- package/.next/standalone/docs/pt-br/custom-policies.mdx +60 -61
- package/.next/standalone/docs/ru/architecture.mdx +59 -60
- package/.next/standalone/docs/ru/configuration.mdx +52 -53
- package/.next/standalone/docs/ru/custom-policies.mdx +68 -69
- package/.next/standalone/docs/tr/architecture.mdx +124 -124
- package/.next/standalone/docs/tr/configuration.mdx +45 -46
- package/.next/standalone/docs/tr/custom-policies.mdx +75 -75
- package/.next/standalone/docs/vi/architecture.mdx +65 -64
- package/.next/standalone/docs/vi/configuration.mdx +41 -41
- package/.next/standalone/docs/vi/custom-policies.mdx +68 -69
- package/.next/standalone/docs/zh/architecture.mdx +67 -67
- package/.next/standalone/docs/zh/configuration.mdx +34 -34
- package/.next/standalone/docs/zh/custom-policies.mdx +53 -54
- package/.next/standalone/node_modules/@next/env/package.json +1 -1
- package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
- package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +7 -7
- package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
- package/.next/standalone/node_modules/next/dist/server/config-schema.js +10 -2
- package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/render.js +27 -20
- package/.next/standalone/node_modules/next/dist/shared/lib/errors/canary-only-config-error.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
- package/.next/standalone/node_modules/next/package.json +15 -15
- package/.next/standalone/package.json +2 -2
- package/.next/standalone/server.js +1 -1
- package/.next/standalone/src/hooks/builtin-policies.ts +131 -0
- package/README.md +2 -2
- package/dist/cli.mjs +107 -3
- package/package.json +2 -2
- package/src/hooks/builtin-policies.ts +131 -0
- package/.next/standalone/.next/static/chunks/0_yayar~bpphd.js +0 -4
- /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → CkmOT-ZvDN-sVULinGVKT}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → CkmOT-ZvDN-sVULinGVKT}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → CkmOT-ZvDN-sVULinGVKT}/_ssgManifest.js +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: 아키텍처
|
|
3
|
-
description: "훅 핸들러, 설정 로딩, 정책
|
|
3
|
+
description: "훅 핸들러, 설정 로딩, 정책 평가의 내부 동작 방식"
|
|
4
4
|
icon: sitemap
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
이 문서는 failproofai
|
|
7
|
+
이 문서는 failproofai의 내부 동작 방식을 설명합니다. 훅 시스템이 에이전트 도구 호출을 가로채는 방법, 설정이 로드되고 병합되는 방법, 정책이 평가되는 방법, 그리고 대시보드가 에이전트 활동을 모니터링하는 방법을 다룹니다.
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -12,10 +12,10 @@ icon: sitemap
|
|
|
12
12
|
|
|
13
13
|
failproofai는 두 개의 독립적인 서브시스템으로 구성됩니다:
|
|
14
14
|
|
|
15
|
-
1. **훅 핸들러** - Claude Code가 에이전트
|
|
15
|
+
1. **훅 핸들러** - Claude Code가 모든 에이전트 도구 호출 시 실행하는 빠른 CLI 서브프로세스입니다. 정책을 평가하고 결정을 반환합니다.
|
|
16
16
|
2. **에이전트 모니터 (대시보드)** - 에이전트 세션을 모니터링하고 정책을 관리하기 위한 Next.js 웹 애플리케이션입니다.
|
|
17
17
|
|
|
18
|
-
두 서브시스템 모두 `~/.failproofai/`와 프로젝트의 `.failproofai/`
|
|
18
|
+
두 서브시스템 모두 `~/.failproofai/`와 프로젝트의 `.failproofai/` 디렉토리에 있는 설정 파일을 공유하지만, 별도의 프로세스로 실행되며 파일 시스템을 통해서만 통신합니다.
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
@@ -23,7 +23,7 @@ failproofai는 두 개의 독립적인 서브시스템으로 구성됩니다:
|
|
|
23
23
|
|
|
24
24
|
### Claude Code와의 통합
|
|
25
25
|
|
|
26
|
-
`failproofai policies --install`을
|
|
26
|
+
`failproofai policies --install`을 실행하면, `~/.claude/settings.json`에 다음과 같은 항목이 작성됩니다:
|
|
27
27
|
|
|
28
28
|
```json
|
|
29
29
|
{
|
|
@@ -44,7 +44,7 @@ failproofai는 두 개의 독립적인 서브시스템으로 구성됩니다:
|
|
|
44
44
|
}
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
Claude Code는 각
|
|
47
|
+
Claude Code는 각 도구 호출 전에 `failproofai --hook PreToolUse`를 서브프로세스로 실행하며, stdin으로 JSON 페이로드를 전달합니다.
|
|
48
48
|
|
|
49
49
|
### 페이로드 형식
|
|
50
50
|
|
|
@@ -60,13 +60,13 @@ Claude Code는 각 툴 호출 전에 `failproofai --hook PreToolUse`를 서브
|
|
|
60
60
|
}
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
`PostToolUse` 이벤트의
|
|
63
|
+
`PostToolUse` 이벤트의 페이로드에는 도구의 출력 결과가 담긴 `tool_result`도 포함됩니다.
|
|
64
64
|
|
|
65
|
-
핸들러는 stdin
|
|
65
|
+
핸들러는 stdin을 1 MB로 제한합니다. 이를 초과하는 페이로드는 폐기되며 모든 정책은 암묵적으로 허용됩니다.
|
|
66
66
|
|
|
67
67
|
### 응답 형식
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
**거부 (PreToolUse):**
|
|
70
70
|
```json
|
|
71
71
|
{
|
|
72
72
|
"hookSpecificOutput": {
|
|
@@ -76,7 +76,7 @@ Claude Code는 각 툴 호출 전에 `failproofai --hook PreToolUse`를 서브
|
|
|
76
76
|
}
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
**거부 (PostToolUse):**
|
|
80
80
|
```json
|
|
81
81
|
{
|
|
82
82
|
"hookSpecificOutput": {
|
|
@@ -85,7 +85,7 @@ Claude Code는 각 툴 호출 전에 `failproofai --hook PreToolUse`를 서브
|
|
|
85
85
|
}
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
**지시 (Stop 이벤트 제외한 모든 이벤트):**
|
|
89
89
|
```json
|
|
90
90
|
{
|
|
91
91
|
"hookSpecificOutput": {
|
|
@@ -94,20 +94,20 @@ Claude Code는 각 툴 호출 전에 `failproofai --hook PreToolUse`를 서브
|
|
|
94
94
|
}
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
**Stop
|
|
97
|
+
**Stop 이벤트 지시:**
|
|
98
98
|
- 종료 코드: `2`
|
|
99
|
-
- 이유는 stdout이 아닌 stderr에
|
|
99
|
+
- 이유는 stdout이 아닌 stderr에 기록됨
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
**허용:**
|
|
102
102
|
- 종료 코드: `0`
|
|
103
|
-
- stdout
|
|
103
|
+
- stdout 비어 있음
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
**메시지와 함께 허용:**
|
|
106
106
|
|
|
107
|
-
`allow(message)`를
|
|
107
|
+
`allow(message)`를 사용하면 작업이 허용되더라도 정책이 Claude에게 정보성 컨텍스트를 전송할 수 있습니다. 훅 핸들러는 다음 JSON을 **stdout**에 기록합니다 (설정 파일이 아닌, 위의 거부 및 지시 응답과 동일하게 Claude Code에 대한 핸들러의 응답입니다):
|
|
108
108
|
|
|
109
109
|
```json
|
|
110
|
-
// 훅 핸들러 프로세스가 stdout에
|
|
110
|
+
// 훅 핸들러 프로세스가 stdout에 기록
|
|
111
111
|
{
|
|
112
112
|
"hookSpecificOutput": {
|
|
113
113
|
"additionalContext": "All CI checks passed on branch 'feat/my-feature'."
|
|
@@ -115,12 +115,12 @@ Claude Code는 각 툴 호출 전에 `failproofai --hook PreToolUse`를 서브
|
|
|
115
115
|
}
|
|
116
116
|
```
|
|
117
117
|
- 종료 코드: `0` (작업이 허용됨)
|
|
118
|
-
- 여러 정책이 메시지와 함께 `allow`를 반환하면, 해당 메시지들이 줄바꿈으로 연결되어
|
|
119
|
-
- 어떤 정책도 메시지를 제공하지 않으면 stdout은 비어
|
|
118
|
+
- 여러 정책이 메시지와 함께 `allow`를 반환하면, 해당 메시지들이 줄바꿈으로 연결되어 단일 `additionalContext` 문자열이 됨
|
|
119
|
+
- 어떤 정책도 메시지를 제공하지 않으면 stdout은 비어 있음 (기존과 동일)
|
|
120
120
|
|
|
121
121
|
### 처리 파이프라인
|
|
122
122
|
|
|
123
|
-
`src/hooks/handler.ts
|
|
123
|
+
`src/hooks/handler.ts`는 전체 파이프라인을 구현합니다:
|
|
124
124
|
|
|
125
125
|
```text
|
|
126
126
|
stdin JSON
|
|
@@ -131,62 +131,62 @@ stdin JSON
|
|
|
131
131
|
→ customPoliciesPath에서 커스텀 정책 로드 (설정된 경우)
|
|
132
132
|
→ 커스텀 정책을 정책 레지스트리에 등록
|
|
133
133
|
→ 모든 정책 평가 (내장 정책 먼저, 그 다음 커스텀)
|
|
134
|
-
→ 첫 번째
|
|
135
|
-
→
|
|
136
|
-
→
|
|
137
|
-
→ stdout에
|
|
138
|
-
→ ~/.failproofai/hook-activity.jsonl에
|
|
134
|
+
→ 첫 번째 거부가 단락(short-circuit)
|
|
135
|
+
→ 지시 결정이 누적됨
|
|
136
|
+
→ 허용 메시지가 누적됨
|
|
137
|
+
→ JSON 결정을 stdout에 기록
|
|
138
|
+
→ 이벤트를 ~/.failproofai/hook-activity.jsonl에 저장
|
|
139
139
|
→ 종료
|
|
140
140
|
```
|
|
141
141
|
|
|
142
|
-
LLM 호출 없이 일반적인 페이로드
|
|
142
|
+
전체 프로세스는 LLM 호출 없이 일반적인 페이로드 기준 100ms 이내에 완료됩니다.
|
|
143
143
|
|
|
144
144
|
---
|
|
145
145
|
|
|
146
146
|
## 설정 로딩
|
|
147
147
|
|
|
148
|
-
`src/hooks/hooks-config.ts
|
|
148
|
+
`src/hooks/hooks-config.ts`는 세 가지 범위의 설정 로딩을 구현합니다.
|
|
149
149
|
|
|
150
150
|
```text
|
|
151
|
-
[1] {cwd}/.failproofai/policies-config.json ← 프로젝트 (
|
|
151
|
+
[1] {cwd}/.failproofai/policies-config.json ← 프로젝트 (가장 높은 우선순위)
|
|
152
152
|
[2] {cwd}/.failproofai/policies-config.local.json ← 로컬
|
|
153
|
-
[3] ~/.failproofai/policies-config.json ← 전역 (
|
|
153
|
+
[3] ~/.failproofai/policies-config.json ← 전역 (가장 낮은 우선순위)
|
|
154
154
|
```
|
|
155
155
|
|
|
156
156
|
병합 로직:
|
|
157
|
-
- `enabledPolicies` - 세 파일
|
|
158
|
-
- `policyParams` - 정책별 키,
|
|
159
|
-
- `customPoliciesPath` -
|
|
160
|
-
- `llm` -
|
|
157
|
+
- `enabledPolicies` - 세 파일 모두에서 중복 제거된 합집합
|
|
158
|
+
- `policyParams` - 정책별 키, 이를 정의하는 첫 번째 파일이 전체 우선
|
|
159
|
+
- `customPoliciesPath` - 이를 정의하는 첫 번째 파일이 우선
|
|
160
|
+
- `llm` - 이를 정의하는 첫 번째 파일이 우선
|
|
161
161
|
|
|
162
|
-
웹 대시보드는 프로젝트 cwd 없이
|
|
162
|
+
웹 대시보드는 프로젝트 cwd 없이 실행되므로 읽기 및 쓰기에 `readHooksConfig()`(전역만)를 사용합니다.
|
|
163
163
|
|
|
164
164
|
---
|
|
165
165
|
|
|
166
166
|
## 정책 평가
|
|
167
167
|
|
|
168
|
-
`src/hooks/policy-evaluator.ts
|
|
168
|
+
`src/hooks/policy-evaluator.ts`는 정책을 순서대로 실행합니다.
|
|
169
169
|
|
|
170
170
|
각 정책에 대해:
|
|
171
171
|
|
|
172
|
-
1. 정책의 `params`
|
|
172
|
+
1. 정책의 `params` 스키마(존재하는 경우)를 조회합니다.
|
|
173
173
|
2. 병합된 설정에서 `policyParams[policy.name]`을 읽습니다.
|
|
174
174
|
3. 스키마 기본값 위에 사용자 제공 값을 병합하여 `ctx.params`를 생성합니다.
|
|
175
175
|
4. 해결된 컨텍스트와 함께 `policy.fn(ctx)`를 호출합니다.
|
|
176
176
|
5. 결과가 `deny`이면 즉시 중단하고 해당 결정을 반환합니다.
|
|
177
177
|
6. 결과가 `instruct`이면 메시지를 누적하고 계속 진행합니다.
|
|
178
|
-
7. 결과가 `allow`이면 다음 정책으로
|
|
178
|
+
7. 결과가 `allow`이면 다음 정책으로 계속 진행합니다.
|
|
179
179
|
|
|
180
|
-
모든
|
|
181
|
-
- `deny`가 반환된
|
|
182
|
-
- `instruct`
|
|
183
|
-
-
|
|
180
|
+
모든 정책이 실행된 후:
|
|
181
|
+
- `deny`가 반환된 경우 거부 응답을 내보냅니다.
|
|
182
|
+
- `instruct` 반환이 수집된 경우 모든 메시지를 결합한 단일 지시 응답을 내보냅니다.
|
|
183
|
+
- 그렇지 않으면 허용 응답을 내보냅니다 (stdout 비어 있음, 종료 코드 0).
|
|
184
184
|
|
|
185
185
|
---
|
|
186
186
|
|
|
187
187
|
## 내장 정책
|
|
188
188
|
|
|
189
|
-
`src/hooks/builtin-policies.ts
|
|
189
|
+
`src/hooks/builtin-policies.ts`는 26개의 내장 정책을 `BuiltinPolicyDefinition` 객체로 정의합니다:
|
|
190
190
|
|
|
191
191
|
```typescript
|
|
192
192
|
interface BuiltinPolicyDefinition {
|
|
@@ -204,15 +204,15 @@ interface BuiltinPolicyDefinition {
|
|
|
204
204
|
}
|
|
205
205
|
```
|
|
206
206
|
|
|
207
|
-
`params`를 받는 정책은 각 파라미터에 대한 타입과 기본값을
|
|
207
|
+
`params`를 받는 정책은 각 파라미터에 대한 타입과 기본값을 포함한 `PolicyParamsSchema`를 선언합니다. 정책 평가기는 `fn`을 호출하기 전에 해결된 값을 `ctx.params`에 주입합니다. 기본값이 항상 먼저 적용되므로 정책 함수는 null 검사 없이 `ctx.params`를 읽습니다.
|
|
208
208
|
|
|
209
|
-
정책 내부의 패턴 매칭은 원시 문자열 매칭이 아닌 파싱된 명령 토큰(argv)을 사용합니다. 이를 통해 셸 연산자 인젝션을 통한 우회를 방지합니다 (예: `sudo systemctl status *` 패턴은
|
|
209
|
+
정책 내부의 패턴 매칭은 원시 문자열 매칭이 아닌 파싱된 명령 토큰(argv)을 사용합니다. 이를 통해 셸 연산자 인젝션을 통한 우회를 방지합니다 (예: `sudo systemctl status *` 패턴은 명령어에 `; rm -rf /`를 추가해도 우회할 수 없음).
|
|
210
210
|
|
|
211
211
|
---
|
|
212
212
|
|
|
213
213
|
## 커스텀 정책
|
|
214
214
|
|
|
215
|
-
`src/hooks/custom-hooks-registry.ts
|
|
215
|
+
`src/hooks/custom-hooks-registry.ts`는 `globalThis` 기반 레지스트리를 구현합니다:
|
|
216
216
|
|
|
217
217
|
```typescript
|
|
218
218
|
const REGISTRY_KEY = "__failproofai_custom_hooks__";
|
|
@@ -225,25 +225,25 @@ export function getCustomHooks(): CustomHook[] { ... }
|
|
|
225
225
|
export function clearCustomHooks(): void { ... } // 테스트에서 사용
|
|
226
226
|
```
|
|
227
227
|
|
|
228
|
-
`src/hooks/custom-hooks-loader.ts
|
|
228
|
+
`src/hooks/custom-hooks-loader.ts`는 사용자의 정책 파일을 로드합니다:
|
|
229
229
|
|
|
230
230
|
1. 설정에서 `customPoliciesPath`를 읽고, 없으면 건너뜁니다.
|
|
231
|
-
2. 절대 경로로
|
|
232
|
-
3.
|
|
231
|
+
2. 절대 경로로 확인하고 파일 존재 여부를 확인합니다.
|
|
232
|
+
3. 모든 `from "failproofai"` 임포트를 실제 dist 경로로 재작성하여 `customPolicies`가 동일한 `globalThis` 레지스트리로 해결되도록 합니다.
|
|
233
233
|
4. ESM 호환성을 보장하기 위해 전이적 로컬 임포트를 재귀적으로 재작성합니다.
|
|
234
234
|
5. 임시 `.mjs` 파일을 작성하고 엔트리 파일을 `import()`합니다.
|
|
235
235
|
6. `getCustomHooks()`를 호출하여 등록된 훅을 가져옵니다.
|
|
236
236
|
7. `finally` 블록에서 모든 임시 파일을 정리합니다.
|
|
237
237
|
|
|
238
|
-
오류 발생 시(파일 없음, 구문 오류, 임포트 실패), 오류는 `~/.failproofai/hook.log`에 기록되고 로더는 빈 배열을 반환합니다. 내장
|
|
238
|
+
오류 발생 시(파일 없음, 구문 오류, 임포트 실패), 오류는 `~/.failproofai/hook.log`에 기록되고 로더는 빈 배열을 반환합니다. 내장 정책은 영향을 받지 않습니다.
|
|
239
239
|
|
|
240
|
-
커스텀 정책은 모든 내장 정책 이후에 평가됩니다. 커스텀 정책의 `deny`는 이후 커스텀 정책의 실행을
|
|
240
|
+
커스텀 정책은 모든 내장 정책 이후에 평가됩니다. 커스텀 정책의 `deny`는 이후 커스텀 정책의 실행을 단락(short-circuit)시키지만, 이 시점에서 모든 내장 정책은 이미 실행된 상태입니다.
|
|
241
241
|
|
|
242
242
|
---
|
|
243
243
|
|
|
244
244
|
## 활동 로깅
|
|
245
245
|
|
|
246
|
-
각 훅 이벤트
|
|
246
|
+
각 훅 이벤트 후, 핸들러는 `~/.failproofai/hook-activity.jsonl`에 JSONL 줄을 추가합니다:
|
|
247
247
|
|
|
248
248
|
```json
|
|
249
249
|
{
|
|
@@ -258,19 +258,19 @@ export function clearCustomHooks(): void { ... } // 테스트에서 사용
|
|
|
258
258
|
}
|
|
259
259
|
```
|
|
260
260
|
|
|
261
|
-
|
|
261
|
+
허용이 아닌 결정을 내린 정책당 한 줄씩 기록됩니다. 허용 결정은 기록하지 않습니다(파일 크기를 작게 유지하기 위함).
|
|
262
262
|
|
|
263
263
|
---
|
|
264
264
|
|
|
265
265
|
## 대시보드 아키텍처
|
|
266
266
|
|
|
267
|
-
대시보드는 App Router
|
|
267
|
+
대시보드는 App Router를 사용하는 **Next.js 16** 애플리케이션으로, React 서버 컴포넌트와 서버 액션을 활용합니다.
|
|
268
268
|
|
|
269
269
|
```text
|
|
270
270
|
app/
|
|
271
271
|
layout.tsx ← 루트 레이아웃 (테마, 텔레메트리, 내비게이션)
|
|
272
272
|
projects/page.tsx ← 서버 컴포넌트: 모든 Claude 프로젝트 목록
|
|
273
|
-
project/[name]/page.tsx ← 서버 컴포넌트:
|
|
273
|
+
project/[name]/page.tsx ← 서버 컴포넌트: 프로젝트의 세션 목록
|
|
274
274
|
project/[name]/session/
|
|
275
275
|
[sessionId]/page.tsx ← 서버 컴포넌트: 세션 뷰어 렌더링
|
|
276
276
|
policies/page.tsx ← 클라이언트 컴포넌트: 정책 관리 + 활동 로그
|
|
@@ -286,16 +286,16 @@ app/
|
|
|
286
286
|
|
|
287
287
|
**데이터 흐름:**
|
|
288
288
|
|
|
289
|
-
- 페이지 컴포넌트는 `lib/projects.ts`와 `lib/log-entries.ts`를 호출하여
|
|
289
|
+
- 페이지 컴포넌트는 `lib/projects.ts`와 `lib/log-entries.ts`를 호출하여 API 레이어 없이 파일 시스템에서 직접 프로젝트/세션 데이터를 읽습니다.
|
|
290
290
|
- 정책 페이지는 모든 변경 작업(토글, 파라미터 업데이트, 설치/제거)에 서버 액션을 사용합니다.
|
|
291
|
-
- 세션 뷰어는 Claude의 JSONL 트랜스크립트 형식을
|
|
291
|
+
- 세션 뷰어는 Claude의 JSONL 트랜스크립트 형식을 파싱하여 메시지와 도구 호출의 타임라인을 렌더링합니다.
|
|
292
292
|
|
|
293
293
|
**주요 설계 결정:**
|
|
294
294
|
|
|
295
|
-
- 데이터베이스 없음 - 모든 영구 상태는 일반
|
|
296
|
-
- 변경 작업에 서버 액션 사용 - CRUD
|
|
297
|
-
- 읽기 페이지에 React 서버 컴포넌트 사용 - 초기
|
|
298
|
-
- 상호작용이 필요한
|
|
295
|
+
- 데이터베이스 없음 - 모든 영구 상태는 일반 파일(`~/.failproofai/`, `~/.claude/projects/`)에 저장됩니다.
|
|
296
|
+
- 변경 작업에 서버 액션 사용 - CRUD 작업을 위한 REST API가 필요 없습니다.
|
|
297
|
+
- 읽기 페이지에 React 서버 컴포넌트 사용 - 초기 로드가 빠르고 데이터 페칭을 위한 클라이언트 번들이 없습니다.
|
|
298
|
+
- 상호작용이 필요한 경우에만 클라이언트 컴포넌트 사용 (정책 토글, 활동 검색, 로그 뷰어).
|
|
299
299
|
|
|
300
300
|
---
|
|
301
301
|
|
|
@@ -304,29 +304,29 @@ app/
|
|
|
304
304
|
```text
|
|
305
305
|
failproofai/
|
|
306
306
|
├── bin/
|
|
307
|
-
│ └── failproofai.mjs # CLI 라우터 (
|
|
307
|
+
│ └── failproofai.mjs # CLI 라우터 (훅 / 대시보드 / 설치 등)
|
|
308
308
|
├── src/hooks/
|
|
309
309
|
│ ├── handler.ts # 훅 이벤트 파이프라인
|
|
310
|
-
│ ├── builtin-policies.ts # 26
|
|
310
|
+
│ ├── builtin-policies.ts # 26개 정책 정의
|
|
311
311
|
│ ├── policy-evaluator.ts # 정책 실행 엔진
|
|
312
312
|
│ ├── policy-registry.ts # 정책 등록 및 조회
|
|
313
313
|
│ ├── policy-types.ts # TypeScript 인터페이스
|
|
314
314
|
│ ├── hooks-config.ts # 다중 범위 설정 로딩
|
|
315
315
|
│ ├── custom-hooks-registry.ts # globalThis 기반 훅 레지스트리
|
|
316
316
|
│ ├── custom-hooks-loader.ts # 사용자 JS 훅을 위한 ESM 로더
|
|
317
|
-
│ ├── manager.ts # 설치 / 제거 / 목록
|
|
317
|
+
│ ├── manager.ts # 설치 / 제거 / 목록 작업
|
|
318
318
|
│ ├── install-prompt.ts # 대화형 정책 선택 프롬프트
|
|
319
319
|
│ ├── hook-logger.ts # hook.log에 로깅
|
|
320
320
|
│ ├── hook-activity-store.ts # hook-activity.jsonl에 활동 저장
|
|
321
321
|
│ └── llm-client.ts # LLM API 클라이언트 (AI 기반 정책용)
|
|
322
322
|
├── app/ # Next.js 대시보드 (페이지 + 서버 액션)
|
|
323
323
|
├── lib/ # 공유 유틸리티
|
|
324
|
-
│ ├── projects.ts #
|
|
324
|
+
│ ├── projects.ts # 파일 시스템에서 Claude 프로젝트 열거
|
|
325
325
|
│ ├── log-entries.ts # Claude 트랜스크립트 JSONL 형식 파싱
|
|
326
326
|
│ ├── paths.ts # 시스템 경로 해결
|
|
327
327
|
│ └── ...
|
|
328
328
|
├── components/ # 공유 React UI 컴포넌트
|
|
329
329
|
├── contexts/ # React 컨텍스트 프로바이더 (테마, 자동 새로고침, 텔레메트리)
|
|
330
|
-
├── examples/ # 커스텀 훅 파일
|
|
330
|
+
├── examples/ # 커스텀 훅 파일 예시
|
|
331
331
|
└── __tests__/ # 단위 및 E2E 테스트
|
|
332
332
|
```
|
|
@@ -4,25 +4,25 @@ description: "설정 파일 형식, 세 가지 범위 시스템, 그리고 병
|
|
|
4
4
|
icon: gear
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
failproofai는 JSON 설정 파일을 사용하여 어떤
|
|
7
|
+
failproofai는 JSON 설정 파일을 사용하여 어떤 정책을 활성화할지, 정책이 어떻게 동작할지, 그리고 커스텀 정책을 어디서 불러올지를 제어합니다. 설정은 팀과 공유하기 쉽도록 설계되어 있습니다. 저장소에 커밋하면 모든 개발자가 동일한 에이전트 안전망을 갖게 됩니다.
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
## 설정 범위
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
우선순위 순서로 평가되는 세 가지 설정 범위가 있습니다:
|
|
14
14
|
|
|
15
15
|
| 범위 | 파일 경로 | 용도 |
|
|
16
|
-
|
|
16
|
+
|------|-----------|------|
|
|
17
17
|
| **project** | `.failproofai/policies-config.json` | 저장소별 설정, 버전 관리에 커밋 |
|
|
18
|
-
| **local** | `.failproofai/policies-config.local.json` | 개인 저장소별
|
|
18
|
+
| **local** | `.failproofai/policies-config.local.json` | 개인 저장소별 재정의, gitignore 처리 |
|
|
19
19
|
| **global** | `~/.failproofai/policies-config.json` | 모든 프로젝트에 적용되는 사용자 수준 기본값 |
|
|
20
20
|
|
|
21
|
-
failproofai가 훅 이벤트를 수신하면, 현재 작업 디렉터리에 존재하는 세 파일을 모두
|
|
21
|
+
failproofai가 훅 이벤트를 수신하면, 현재 작업 디렉터리에 존재하는 세 파일을 모두 불러와 병합합니다.
|
|
22
22
|
|
|
23
23
|
### 병합 규칙
|
|
24
24
|
|
|
25
|
-
**`enabledPolicies`** - 세
|
|
25
|
+
**`enabledPolicies`** - 세 범위 모두의 합집합입니다. 어느 레벨에서든 활성화된 정책은 유효합니다.
|
|
26
26
|
|
|
27
27
|
```text
|
|
28
28
|
project: ["block-sudo"]
|
|
@@ -32,7 +32,7 @@ global: ["block-sudo", "sanitize-api-keys"]
|
|
|
32
32
|
resolved: ["block-sudo", "block-rm-rf", "sanitize-api-keys"] ← 중복 제거된 합집합
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
**`policyParams`** -
|
|
35
|
+
**`policyParams`** - 해당 정책의 파라미터를 가장 먼저 정의한 범위가 완전히 우선합니다. 정책 파라미터 내부의 값은 깊은 병합(deep merge)이 수행되지 않습니다.
|
|
36
36
|
|
|
37
37
|
```text
|
|
38
38
|
project: block-sudo → { allowPatterns: ["sudo apt-get update"] }
|
|
@@ -46,12 +46,12 @@ project: (block-sudo 항목 없음)
|
|
|
46
46
|
local: (block-sudo 항목 없음)
|
|
47
47
|
global: block-sudo → { allowPatterns: ["sudo systemctl status"] }
|
|
48
48
|
|
|
49
|
-
resolved: { allowPatterns: ["sudo systemctl status"] } ← global까지
|
|
49
|
+
resolved: { allowPatterns: ["sudo systemctl status"] } ← global까지 전달됨
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
**`customPoliciesPath`** -
|
|
52
|
+
**`customPoliciesPath`** - 가장 먼저 정의한 범위가 우선합니다.
|
|
53
53
|
|
|
54
|
-
**`llm`** -
|
|
54
|
+
**`llm`** - 가장 먼저 정의한 범위가 우선합니다.
|
|
55
55
|
|
|
56
56
|
---
|
|
57
57
|
|
|
@@ -102,7 +102,7 @@ resolved: { allowPatterns: ["sudo systemctl status"] } ← global까지 폴스
|
|
|
102
102
|
|
|
103
103
|
타입: `string[]`
|
|
104
104
|
|
|
105
|
-
활성화할 정책 이름 목록입니다. 이름은 `failproofai policies
|
|
105
|
+
활성화할 정책 이름 목록입니다. 이름은 `failproofai policies`에서 표시하는 정책 식별자와 정확히 일치해야 합니다. 전체 목록은 [기본 제공 정책](/ko/built-in-policies)을 참조하세요.
|
|
106
106
|
|
|
107
107
|
`enabledPolicies`에 포함되지 않은 정책은 `policyParams`에 항목이 있더라도 비활성 상태입니다.
|
|
108
108
|
|
|
@@ -110,19 +110,19 @@ resolved: { allowPatterns: ["sudo systemctl status"] } ← global까지 폴스
|
|
|
110
110
|
|
|
111
111
|
타입: `Record<string, Record<string, unknown>>`
|
|
112
112
|
|
|
113
|
-
정책별 파라미터
|
|
113
|
+
정책별 파라미터 재정의입니다. 외부 키는 정책 이름이고, 내부 키는 정책별로 다릅니다. 각 정책의 사용 가능한 파라미터는 [기본 제공 정책](/ko/built-in-policies)에 문서화되어 있습니다.
|
|
114
114
|
|
|
115
|
-
정책에
|
|
115
|
+
파라미터가 있는 정책에 대해 별도로 지정하지 않으면 정책의 기본값이 사용됩니다. `policyParams`를 전혀 설정하지 않은 사용자는 이전 버전과 동일한 동작을 경험합니다.
|
|
116
116
|
|
|
117
|
-
정책 파라미터 블록 내의 알 수 없는 키는 훅 실행
|
|
117
|
+
정책 파라미터 블록 내의 알 수 없는 키는 훅 실행 시 자동으로 무시되지만, `failproofai policies` 실행 시 경고로 표시됩니다.
|
|
118
118
|
|
|
119
|
-
#### `hint` (공통
|
|
119
|
+
#### `hint` (공통 옵션)
|
|
120
120
|
|
|
121
121
|
타입: `string` (선택 사항)
|
|
122
122
|
|
|
123
|
-
정책이 `deny` 또는 `instruct`를 반환할 때
|
|
123
|
+
정책이 `deny` 또는 `instruct`를 반환할 때 이유(reason)에 추가되는 메시지입니다. 정책 자체를 수정하지 않고도 Claude에게 실질적인 지침을 제공할 수 있습니다.
|
|
124
124
|
|
|
125
|
-
기본
|
|
125
|
+
기본 제공, 커스텀(`custom/`), 프로젝트 컨벤션(`.failproofai-project/`), 사용자 컨벤션(`.failproofai-user/`) 등 모든 정책 유형에서 사용할 수 있습니다.
|
|
126
126
|
|
|
127
127
|
```json
|
|
128
128
|
{
|
|
@@ -141,40 +141,40 @@ resolved: { allowPatterns: ["sudo systemctl status"] } ← global까지 폴스
|
|
|
141
141
|
}
|
|
142
142
|
```
|
|
143
143
|
|
|
144
|
-
`block-force-push`가
|
|
144
|
+
`block-force-push`가 차단할 때 Claude는 다음을 확인합니다: *"Force-pushing is blocked. Try creating a fresh branch instead."*
|
|
145
145
|
|
|
146
|
-
문자열이 아닌 값과 빈 문자열은
|
|
146
|
+
문자열이 아닌 값과 빈 문자열은 자동으로 무시됩니다. `hint`가 설정되지 않으면 동작이 변경되지 않습니다(이전 버전과 호환).
|
|
147
147
|
|
|
148
148
|
### `customPoliciesPath`
|
|
149
149
|
|
|
150
150
|
타입: `string` (절대 경로)
|
|
151
151
|
|
|
152
|
-
커스텀 훅 정책이
|
|
152
|
+
커스텀 훅 정책이 포함된 JavaScript 파일의 경로입니다. `failproofai policies --install --custom <path>`를 실행하면 자동으로 설정됩니다(저장 전에 절대 경로로 변환됨).
|
|
153
153
|
|
|
154
|
-
파일은 매 훅 이벤트마다 새로
|
|
154
|
+
파일은 매 훅 이벤트마다 새로 불러오며, 캐싱이 없습니다. 작성 방법은 [커스텀 정책](/ko/custom-policies)을 참조하세요.
|
|
155
155
|
|
|
156
156
|
### 컨벤션 기반 정책
|
|
157
157
|
|
|
158
|
-
명시적인 `customPoliciesPath` 외에도, failproofai는 `.failproofai/policies/` 디렉터리에서 정책 파일을 자동으로 검색하여
|
|
158
|
+
명시적인 `customPoliciesPath` 외에도, failproofai는 `.failproofai/policies/` 디렉터리에서 정책 파일을 자동으로 검색하여 불러옵니다:
|
|
159
159
|
|
|
160
|
-
|
|
|
161
|
-
|
|
160
|
+
| 레벨 | 디렉터리 | 범위 |
|
|
161
|
+
|------|----------|------|
|
|
162
162
|
| 프로젝트 | `.failproofai/policies/` | 버전 관리를 통해 팀과 공유 |
|
|
163
163
|
| 사용자 | `~/.failproofai/policies/` | 개인용, 모든 프로젝트에 적용 |
|
|
164
164
|
|
|
165
|
-
**파일 매칭:** `*policies.{js,mjs,ts}` 패턴과 일치하는 파일만
|
|
165
|
+
**파일 매칭:** `*policies.{js,mjs,ts}` 패턴과 일치하는 파일만 불러옵니다(예: `security-policies.mjs`, `workflow-policies.js`). 디렉터리 내 다른 파일은 무시됩니다.
|
|
166
166
|
|
|
167
|
-
**설정 불필요:** 컨벤션 정책은 `policies-config.json`에
|
|
167
|
+
**설정 불필요:** 컨벤션 정책은 `policies-config.json`에 별도의 항목이 필요하지 않습니다. 디렉터리에 파일을 추가하기만 하면 다음 훅 이벤트 시 자동으로 반영됩니다.
|
|
168
168
|
|
|
169
|
-
**합집합 로딩:** 프로젝트와 사용자 컨벤션
|
|
169
|
+
**합집합 로딩:** 프로젝트와 사용자 컨벤션 디렉터리 모두 검색합니다. 두 레벨에서 일치하는 파일이 모두 로드됩니다(`customPoliciesPath`는 첫 번째 범위 우선 방식을 사용하는 것과 다름).
|
|
170
170
|
|
|
171
|
-
자세한 내용과
|
|
171
|
+
자세한 내용과 예제는 [커스텀 정책](/ko/custom-policies)을 참조하세요.
|
|
172
172
|
|
|
173
173
|
### `llm`
|
|
174
174
|
|
|
175
175
|
타입: `object` (선택 사항)
|
|
176
176
|
|
|
177
|
-
AI 호출을 수행하는 정책을 위한 LLM 클라이언트 설정입니다. 대부분의
|
|
177
|
+
AI 호출을 수행하는 정책을 위한 LLM 클라이언트 설정입니다. 대부분의 설정에서는 필요하지 않습니다.
|
|
178
178
|
|
|
179
179
|
```json
|
|
180
180
|
{
|
|
@@ -187,20 +187,20 @@ AI 호출을 수행하는 정책을 위한 LLM 클라이언트 설정입니다.
|
|
|
187
187
|
|
|
188
188
|
---
|
|
189
189
|
|
|
190
|
-
## CLI
|
|
190
|
+
## CLI에서 설정 관리하기
|
|
191
191
|
|
|
192
|
-
`policies --install` 및 `policies --uninstall` 명령은 Claude Code의 `settings.json`(훅 진입점)에
|
|
192
|
+
`policies --install` 및 `policies --uninstall` 명령은 Claude Code의 `settings.json`(훅 진입점)에 기록하며, `policies-config.json`은 직접 관리하는 파일입니다. 두 파일은 별개입니다:
|
|
193
193
|
|
|
194
|
-
- **`settings.json`** - 각 도구 사용 시
|
|
194
|
+
- **`settings.json`** - Claude Code가 각 도구 사용 시 `failproofai --hook <event>`를 호출하도록 지시
|
|
195
195
|
- **`policies-config.json`** - failproofai가 어떤 정책을 어떤 파라미터로 평가할지 지시
|
|
196
196
|
|
|
197
|
-
`policies-config.json`은 언제든지 직접 편집할 수 있으며, 변경 사항은 재시작 없이 다음 훅
|
|
197
|
+
`policies-config.json`은 언제든지 직접 편집할 수 있으며, 변경 사항은 재시작 없이 다음 훅 이벤트 시 즉시 적용됩니다.
|
|
198
198
|
|
|
199
199
|
---
|
|
200
200
|
|
|
201
201
|
## 예시: 팀 기본값이 포함된 프로젝트 수준 설정
|
|
202
202
|
|
|
203
|
-
`.failproofai/policies-config.json`을 저장소에
|
|
203
|
+
`.failproofai/policies-config.json`을 저장소에 커밋합니다:
|
|
204
204
|
|
|
205
205
|
```json
|
|
206
206
|
{
|
|
@@ -219,4 +219,4 @@ AI 호출을 수행하는 정책을 위한 LLM 클라이언트 설정입니다.
|
|
|
219
219
|
}
|
|
220
220
|
```
|
|
221
221
|
|
|
222
|
-
각 개발자는 `.failproofai/policies-config.local.json`(gitignore
|
|
222
|
+
각 개발자는 `.failproofai/policies-config.local.json`(gitignore 처리됨)을 생성하여 팀원에게 영향을 주지 않고 개인 설정을 재정의할 수 있습니다.
|