polydeukes 0.6.0 → 0.6.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/README.ko.md +54 -80
- package/README.md +55 -94
- package/dist/bin.js +8 -5
- package/dist/docs/README.ko.md +60 -0
- package/dist/docs/README.md +64 -0
- package/dist/docs/catalog.json +464 -0
- package/dist/docs/concepts/judgment.ko.md +113 -0
- package/dist/docs/concepts/judgment.md +113 -0
- package/dist/docs/how-to/configure-project.ko.md +99 -0
- package/dist/docs/how-to/configure-project.md +95 -0
- package/dist/docs/how-to/connect-surfaces.ko.md +115 -0
- package/dist/docs/how-to/connect-surfaces.md +118 -0
- package/dist/docs/how-to/write-disciplines.ko.md +124 -0
- package/dist/docs/how-to/write-disciplines.md +125 -0
- package/dist/docs/index.json +2046 -0
- package/dist/docs/reference/cli/covenant-check.ko.md +101 -0
- package/dist/docs/reference/cli/covenant-check.md +98 -0
- package/dist/docs/reference/cli/docs.ko.md +97 -0
- package/dist/docs/reference/cli/docs.md +95 -0
- package/dist/docs/reference/cli/explain.ko.md +79 -0
- package/dist/docs/reference/cli/explain.md +84 -0
- package/dist/docs/reference/cli/init.ko.md +119 -0
- package/dist/docs/reference/cli/init.md +131 -0
- package/dist/docs/reference/configuration/index.ko.md +448 -0
- package/dist/docs/reference/{configuration.md → configuration/index.md} +48 -30
- package/dist/docs/reference/packages/adapter-claude-code.ko.md +83 -0
- package/dist/docs/reference/{adapter-claude-code.md → packages/adapter-claude-code.md} +10 -6
- package/dist/docs/reference/packages/adapter-git.ko.md +101 -0
- package/dist/docs/reference/{adapter-git.md → packages/adapter-git.md} +20 -12
- package/dist/docs/reference/packages/core.ko.md +128 -0
- package/dist/docs/reference/{core.md → packages/core.md} +21 -8
- package/dist/docs/reference/packages/covenant.ko.md +115 -0
- package/dist/docs/reference/{covenant.md → packages/covenant.md} +18 -11
- package/dist/docs/reference/packages/polydeukes.ko.md +134 -0
- package/dist/docs/reference/packages/polydeukes.md +139 -0
- package/dist/docs/troubleshooting.ko.md +142 -0
- package/dist/docs/troubleshooting.md +98 -150
- package/dist/docs/tutorials/first-judgment.ko.md +82 -0
- package/dist/docs/tutorials/first-judgment.md +81 -0
- package/dist/docs-catalog.d.ts +25 -0
- package/dist/docs-catalog.js +450 -0
- package/dist/docs-library.d.ts +23 -0
- package/dist/docs-library.js +347 -0
- package/dist/docs-markdown.d.ts +32 -0
- package/dist/docs-markdown.js +150 -0
- package/dist/docs-query.d.ts +11 -40
- package/dist/docs-query.js +28 -122
- package/dist/docs-types.d.ts +105 -0
- package/dist/docs-types.js +2 -0
- package/dist/init-claude-code.d.ts +1 -1
- package/dist/init-claude-code.js +159 -42
- package/package.json +5 -5
- package/dist/docs/configuration.md +0 -103
- package/dist/docs/installation.md +0 -241
- package/dist/docs/reference/polydeukes.md +0 -315
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# Configuration reference
|
|
2
2
|
|
|
3
|
-
**English** · [한국어](
|
|
3
|
+
**English** · [한국어](index.ko.md)
|
|
4
4
|
|
|
5
5
|
Every key of `polydeukes.config.yaml`, one section per key. The guide — what the file is,
|
|
6
6
|
how discovery fails, and the IDE wiring — is
|
|
7
|
-
[Configuring Polydeukes](
|
|
7
|
+
[Configuring Polydeukes](../../how-to/configure-project.md), and what a verdict looks like when a
|
|
8
8
|
discipline fires is its
|
|
9
|
-
[What enforcement looks like](
|
|
9
|
+
[What enforcement looks like](../../how-to/configure-project.md#choose-advise-or-block)
|
|
10
|
+
section.
|
|
10
11
|
|
|
12
|
+
<a id="languages"></a>
|
|
11
13
|
## `languages`
|
|
12
14
|
|
|
13
15
|
Required. The language axis, first-class. Keys are your values (`typescript`, `python`, …) —
|
|
@@ -24,6 +26,7 @@ languages:
|
|
|
24
26
|
all other braces (`${VAR}`, `{a,b}`, `awk '{print}'`) pass through untouched. A command
|
|
25
27
|
that ignores scope (`pnpm test`) is equally valid.
|
|
26
28
|
|
|
29
|
+
<a id="protectedpaths"></a>
|
|
27
30
|
## `protectedPaths`
|
|
28
31
|
|
|
29
32
|
Optional. Raw path patterns whose files the covenants protect from modification — by
|
|
@@ -42,6 +45,7 @@ to `protectedPaths` — an edit that would lower your own gates goes through the
|
|
|
42
45
|
as everything else. If the file that declares the disciplines were not itself under the
|
|
43
46
|
disciplines, the whole chain would be decoration.
|
|
44
47
|
|
|
48
|
+
<a id="adapters"></a>
|
|
45
49
|
## `adapters`
|
|
46
50
|
|
|
47
51
|
Optional. Adapter namespaces. One config file, one namespace per adapter: each key names an
|
|
@@ -58,6 +62,7 @@ adapters:
|
|
|
58
62
|
- 'packages/core/src'
|
|
59
63
|
```
|
|
60
64
|
|
|
65
|
+
<a id="adapters-git"></a>
|
|
61
66
|
### `adapters.git` — the git commit adapter
|
|
62
67
|
|
|
63
68
|
| Key | Values | Default | Meaning |
|
|
@@ -65,7 +70,9 @@ adapters:
|
|
|
65
70
|
| `enforce` | `block` \| `advise` | `block` | Enforcement level of the commit surface |
|
|
66
71
|
| `protectedPaths` | string array | `[]` | Additive protection scope judged by the commit surface only |
|
|
67
72
|
|
|
68
|
-
- **`block`** — a staged change that breaks a covenant
|
|
73
|
+
- **`block`** — a staged change that breaks a covenant judged at block level blocks the
|
|
74
|
+
commit (exit 2): a protected path, or an entry promoted with `enforce: block`. An ordinary
|
|
75
|
+
entry keeps its own default `advise` under this setting (see `enforce` below). The
|
|
69
76
|
only way through is the witness valve: a human answering the TTY prompt with the full
|
|
70
77
|
token. The prompt names what it asks the human to witness — the broken registration,
|
|
71
78
|
the matched entry, and the fact that the one answer covers the whole commit. An absent
|
|
@@ -73,9 +80,9 @@ adapters:
|
|
|
73
80
|
writing the key selects the strictest level.
|
|
74
81
|
- **`advise`** — the commit surface becomes a backstop without a block: a verdict on a
|
|
75
82
|
staged change is recorded as an `advised` telemetry event and the commit proceeds
|
|
76
|
-
(exit 0) with one advisory line on stderr. No TTY prompt fires.
|
|
77
|
-
|
|
78
|
-
body) still fails closed at exit 2, at either level.
|
|
83
|
+
(exit 0) with one advisory line on stderr. No TTY prompt fires. The judgment criteria stay
|
|
84
|
+
the same; violations no longer block. A run that cannot judge (missing or invalid config,
|
|
85
|
+
an unresolvable judge body) still fails closed at exit 2, at either level.
|
|
79
86
|
|
|
80
87
|
**`protectedPaths` here is an additive scope.** The commit surface judges the union of the
|
|
81
88
|
top-level `protectedPaths` and this list — concatenated (common first) and normalized as one,
|
|
@@ -92,8 +99,8 @@ shell axes, the session transcript, an assembly that cannot judge (missing or in
|
|
|
92
99
|
config, unbuilt judge, unparseable payload, a routing that could not answer) — plus any
|
|
93
100
|
entry promoted with `enforce: block`. Every other discipline entry lands `advised` there.
|
|
94
101
|
|
|
95
|
-
**Declarations that read the session skip on the commit surface
|
|
96
|
-
to look at, so a declaration whose `sources` bind the transcript — a `precedent`,
|
|
102
|
+
**Declarations that read the session skip on the commit surface when their supply policy is `pass`.**
|
|
103
|
+
A commit has no session to look at, so a declaration whose `sources` bind the transcript — a `precedent`,
|
|
97
104
|
`phase-order`, `turn-locality` or `stated-ground` entry — cannot be judged there; demanding
|
|
98
105
|
evidence a commit cannot carry would block every matching commit with no legitimate way
|
|
99
106
|
through. The declaration's own `supply: { session: 'pass' }` disposes of the absence: when
|
|
@@ -105,9 +112,10 @@ source records nothing at all there: a staged diff carries no command line, so n
|
|
|
105
112
|
observes is ever admitted.
|
|
106
113
|
|
|
107
114
|
This is the same disposition the session surface uses whenever it has no transcript to
|
|
108
|
-
read
|
|
109
|
-
|
|
115
|
+
read **and** the declaration's `supply` is `pass`. Without that policy a missing source is
|
|
116
|
+
unjudgeable (exit 2), not an automatic skip.
|
|
110
117
|
|
|
118
|
+
<a id="telemetry"></a>
|
|
111
119
|
## `telemetry`
|
|
112
120
|
|
|
113
121
|
Optional.
|
|
@@ -122,6 +130,7 @@ Telemetry is fail-open by design: a logging failure never changes a verdict. The
|
|
|
122
130
|
itself is still validated at load time — an empty or whitespace-only `logPath` is
|
|
123
131
|
rejected.
|
|
124
132
|
|
|
133
|
+
<a id="witness"></a>
|
|
125
134
|
## `witness`
|
|
126
135
|
|
|
127
136
|
Optional.
|
|
@@ -174,6 +183,7 @@ when the token arrives in a message positively identified as human-typed in the
|
|
|
174
183
|
transcript, so an AI that knows the token still cannot forge one. Witnessed judgments are
|
|
175
184
|
recorded as `witnessed`, never silent.
|
|
176
185
|
|
|
186
|
+
<a id="disciplines"></a>
|
|
177
187
|
## `disciplines`
|
|
178
188
|
|
|
179
189
|
Optional. Each entry is one discipline: a practice the team imposes on itself, declared as
|
|
@@ -192,11 +202,15 @@ error, and `draft: false` is rejected as dead data.
|
|
|
192
202
|
|
|
193
203
|
```yaml
|
|
194
204
|
disciplines:
|
|
195
|
-
- id: '
|
|
196
|
-
why: '
|
|
205
|
+
- id: 'benchmark-supports-performance-claim'
|
|
206
|
+
why: 'a performance claim must be supported by a fresh benchmark run during judgment.'
|
|
197
207
|
draft: true
|
|
198
208
|
```
|
|
199
209
|
|
|
210
|
+
A bilingual mirror pair is not a draft. The engine already judges that shape as `companion`
|
|
211
|
+
(this repository's `docs-stay-bilingual` entry). Use `draft: true` only for a promise the
|
|
212
|
+
current grammar cannot express.
|
|
213
|
+
|
|
200
214
|
A `why` is never judged — it changes no verdict. It is appended to the break message once a
|
|
201
215
|
verdict has blocked, so whoever reads the block gets the rationale in the same line instead
|
|
202
216
|
of having to open this file. A `why` spanning several lines is folded to spaces: the message
|
|
@@ -242,21 +256,21 @@ regular expressions over the path.
|
|
|
242
256
|
|
|
243
257
|
```yaml
|
|
244
258
|
disciplines:
|
|
245
|
-
- id: '
|
|
246
|
-
why: '
|
|
259
|
+
- id: 'no-focused-tests-in-src'
|
|
260
|
+
why: 'a focused test must not land in shared source.'
|
|
247
261
|
declare:
|
|
248
262
|
mechanism: 'added-only'
|
|
249
|
-
scope: { source: 'target.path', include: ['^
|
|
263
|
+
scope: { source: 'target.path', include: ['^src/', '^test/'] }
|
|
250
264
|
supply: { pre: 'empty', post: 'empty' }
|
|
251
265
|
extract:
|
|
252
266
|
before:
|
|
253
267
|
- { op: 'source', of: 'pre' }
|
|
254
268
|
- { op: 'lines' }
|
|
255
|
-
- { op: 'keyByPattern', re: '\
|
|
269
|
+
- { op: 'keyByPattern', re: '(\.only\()' }
|
|
256
270
|
after:
|
|
257
271
|
- { op: 'source', of: 'post' }
|
|
258
272
|
- { op: 'lines' }
|
|
259
|
-
- { op: 'keyByPattern', re: '\
|
|
273
|
+
- { op: 'keyByPattern', re: '(\.only\()' }
|
|
260
274
|
added:
|
|
261
275
|
- { op: 'onlyIn', of: 'after', notIn: 'before' }
|
|
262
276
|
relate:
|
|
@@ -266,12 +280,13 @@ disciplines:
|
|
|
266
280
|
```
|
|
267
281
|
|
|
268
282
|
The key is the match text, so a line carrying a word the file already has anywhere is
|
|
269
|
-
forgiven
|
|
270
|
-
|
|
283
|
+
forgiven. A line carrying two new words surfaces only the first match; the second appears
|
|
284
|
+
on a later judgment **after that first match is removed**. Re-judging the same input yields
|
|
285
|
+
the same first match.
|
|
271
286
|
|
|
272
287
|
**A frozen path is a declaration too.** A file that may be created once and never modified
|
|
273
288
|
or deleted: `pre` present means a modification, `post` absent means a deletion, and either
|
|
274
|
-
breaks.
|
|
289
|
+
breaks. Creating the file, including with empty contents (`post: ''`), passes.
|
|
275
290
|
|
|
276
291
|
```yaml
|
|
277
292
|
- id: 'archived-records-stay-frozen'
|
|
@@ -360,10 +375,12 @@ adds nothing to an added-only difference and the discipline silently passes: mak
|
|
|
360
375
|
pattern span the whole value that can change. Both failure shapes compile, run, and answer
|
|
361
376
|
`passed`, so measure a new entry against a real file and a realistic edit.
|
|
362
377
|
|
|
363
|
-
**
|
|
364
|
-
the
|
|
365
|
-
|
|
366
|
-
behaviour the discipline exists to
|
|
378
|
+
**Witnesses and precedent evidence are different.** A pattern seeking precedent evidence must
|
|
379
|
+
distinguish the required action from a mere mention. Session evidence lives on the AI's own
|
|
380
|
+
surface, so it is not forgery-proof; the design relies on the least effortful way to satisfy
|
|
381
|
+
the check being to actually run the command, which is the behaviour the discipline exists to
|
|
382
|
+
induce. A pattern alone does not eliminate the possibility of forged evidence. Test both valid
|
|
383
|
+
and violating cases.
|
|
367
384
|
|
|
368
385
|
**`declare` — declaration family.** One judgment written as data, in the algebra grammar
|
|
369
386
|
the core publishes as `algebra-declaration.schema.json`: `judge = relate ∘ extract`. The
|
|
@@ -372,22 +389,23 @@ block carries the declaration's `scope`, `sources`, `supply`, `extract`, `relate
|
|
|
372
389
|
`discipline` key, and `in`/`except`/`when` are refused — the `scope` block is the scope.
|
|
373
390
|
|
|
374
391
|
```yaml
|
|
375
|
-
- id: 'db-only-under-
|
|
376
|
-
why: 'a *.db file may exist only under
|
|
392
|
+
- id: 'db-files-only-under-data'
|
|
393
|
+
why: 'a *.db file may exist only under data/'
|
|
377
394
|
declare:
|
|
378
395
|
mechanism: 'naming'
|
|
379
396
|
scope: { source: 'target.path', include: ['\.db$'] }
|
|
380
397
|
extract:
|
|
381
398
|
outside:
|
|
382
399
|
- { op: 'source', of: 'target.path' }
|
|
383
|
-
- { op: 'matches', re: '^(?!
|
|
400
|
+
- { op: 'matches', re: '^(?!data/)' }
|
|
384
401
|
relate:
|
|
385
402
|
- id: 'placed'
|
|
386
403
|
relation: { op: 'empty', of: 'outside' }
|
|
387
|
-
message: '{value} is outside
|
|
404
|
+
message: '{value} is outside data/'
|
|
388
405
|
```
|
|
389
406
|
|
|
390
|
-
This repository's live config
|
|
407
|
+
This repository's live config uses the same mechanism with `_docs/knowledge/` as
|
|
408
|
+
`sqlite-only-under-knowledge`.
|
|
391
409
|
|
|
392
410
|
Each observation is judged as one **world** with seven source names: `target.path` (the
|
|
393
411
|
repo-relative path), `pre` and `post` (the file's text on the side the change carries —
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# `@polydeukes/adapter-claude-code`
|
|
2
|
+
|
|
3
|
+
[English](adapter-claude-code.md) · **한국어**
|
|
4
|
+
|
|
5
|
+
> **세션 표면의 번역기**입니다. PreToolUse 페이로드가 약속(covenant) 입력 IR이 되고,
|
|
6
|
+
> 판정기가 읽는 파일 변경 증거와 대화 기록(transcript) 통로가 함께 실립니다.
|
|
7
|
+
>
|
|
8
|
+
> 알파입니다. 통합 패키지의 의존성으로 설치되므로 일반 사용자가 따로 설치하거나 불러올 필요는 없습니다. 세션 표면은
|
|
9
|
+
> [`polydeukes/claude-code`](polydeukes.ko.md#session-export)를 통해 닿습니다.
|
|
10
|
+
|
|
11
|
+
<a id="ownership"></a>
|
|
12
|
+
## 담당하는 기능
|
|
13
|
+
|
|
14
|
+
Claude Code의 입력을 공통 형식으로 번역합니다. 에이전트와 도구의 구체적인 이름은 이 패키지에서 처리하고 코어에는 넣지 않습니다. 코어가 특정 에이전트에 의존하지 않는다는
|
|
15
|
+
제약은 테스트로 확인합니다.
|
|
16
|
+
|
|
17
|
+
| 단위 | 하는 일 |
|
|
18
|
+
|---|---|
|
|
19
|
+
| 페이로드 상향 번역 | 원본 PreToolUse 페이로드가 `CovenantInput`이 됩니다 |
|
|
20
|
+
| 예상 변경 후 상태 | 편집이 적용되면 파일이 무엇을 담을지 디스크를 건드리지 않고 계산합니다 |
|
|
21
|
+
| 파일 변경 증거 | 디스크의 변경 전 상태와 예상 변경 후 상태를 짝지어 변경 증거를 만듭니다 |
|
|
22
|
+
| 대화 기록(transcript) 제공자 | 세션 JSONL 파일을 `CanonicalTranscript`로 바꿉니다 |
|
|
23
|
+
| 텔레메트리 배선 | 전체 처리 경로에서 호출이 기록되도록 연결합니다 |
|
|
24
|
+
|
|
25
|
+
이 패키지는 약속(covenant) 패키지를 결코 불러오지 않습니다. 판정 전달 함수는 통합 패키지가
|
|
26
|
+
**주입**하고, 그래서 의존은 코어를 통해 한 방향으로만 흐릅니다. `@polydeukes/core`는
|
|
27
|
+
`peerDependency`로 부릅니다. 판정기와 같은 어휘를 공유하며 별도 사본을 설치하지 않습니다.
|
|
28
|
+
|
|
29
|
+
<a id="translation"></a>
|
|
30
|
+
## 페이로드 번역과 세 축
|
|
31
|
+
|
|
32
|
+
**판정기에 증거를 전달하는 축은 셋**이며, 축마다 제공할 수 있는 증거가 다릅니다.
|
|
33
|
+
|
|
34
|
+
| 축 | 싣는 것 | 결과 |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| 도구 | 증명된 `fileChange`입니다. 도구가 실행되기 전에 계산된 변형 대상입니다 | 증명된 대상만 판정합니다. 편집 **내용** 안의 보호 경로는 언급이고 통과합니다 |
|
|
37
|
+
| 셸 | 실행 전에는 대상을 계산할 수 없는 경우가 많은 명령줄입니다 | 계산되는 쓰기는 편집처럼 판정하고, 나머지는 추측하지 않고 기록합니다 |
|
|
38
|
+
| 대화 기록 | 세션 자신의 기록입니다 | 전체 경로 등가로 판정하고 보호 조상으로는 보지 않습니다 |
|
|
39
|
+
|
|
40
|
+
번역 과정에서 실패하면 어느 단계에서든 호출을 차단합니다(fail-closed).
|
|
41
|
+
서브에이전트 종류가 지정된 `Task` 호출은 스폰에 대응시킵니다. 분류할 수 없는 페이로드는 번역 **실패**이고, `blocked` 한 행을 기록하고
|
|
42
|
+
종료 `2`를 냅니다. 추측으로 물러서지 않습니다. 봉투 최상위의 `agent_type`은 IR의 `actor`가
|
|
43
|
+
됩니다. 서브에이전트 안에서는 `{ agentType }`, 그 밖에는 `{}`입니다. `tool_input`은 에이전트
|
|
44
|
+
자신의 텍스트이므로 여기서 읽지 않습니다.
|
|
45
|
+
|
|
46
|
+
**변경 후의 증거는 파일을 다시 읽는 대신 계산합니다.** `Edit`, `Write`, `MultiEdit`을
|
|
47
|
+
메모리에서 적용해 예상 변경 후 상태를 구합니다. 다중 편집도 순서대로 적용합니다. 내용을
|
|
48
|
+
확인하는 규율(discipline)은 현재 파일이 아니라 **제안된** 결과를 판정합니다.
|
|
49
|
+
변경 후 상태를 계산할 수 없으면 증거를 만들지 않습니다. 실제 도구도 같은 편집을 거부하기
|
|
50
|
+
때문입니다. 파일을 바꾸지 않는 호출에 변경 증거를 만들어 넣지도 않습니다.
|
|
51
|
+
|
|
52
|
+
**대화 기록은 사람이 친 것으로 확정된 메시지만 받아들입니다.** 증인 밸브가 사람 전용인
|
|
53
|
+
근거가 이것입니다. AI는 자기 증인을 합성할 수 없습니다. 읽기 실패는 빈 대화 기록이 아니라
|
|
54
|
+
`undefined`로 답합니다. 빈 세션은 아직 아무 말도 하지 않은 것이라 판정 대상이고, 읽을 수
|
|
55
|
+
없는 세션은 증거 통로 자체가 없는 것이라 건너뜁니다. 어느 경우에도 이 부재만으로 증인 밸브가 작업을 허용하지는 않습니다.
|
|
56
|
+
|
|
57
|
+
**선행(`precedent`)은 선언이지 어댑터 평가기가 아닙니다.** 이 어댑터는 대화 기록
|
|
58
|
+
스냅샷을 공급합니다. 성공한 `toolUses`를 추출해 대조하는 것은 선언 엔진입니다. 이
|
|
59
|
+
패키지에 별도 선례 평가기는 없습니다. 문법은
|
|
60
|
+
[설정 — 규율](../configuration/index.ko.md#disciplines)에 있습니다.
|
|
61
|
+
|
|
62
|
+
<a id="consumer-contract"></a>
|
|
63
|
+
## 사용자와의 접점
|
|
64
|
+
|
|
65
|
+
- **생성된 훅.** 통합 패키지의 `claude-code` 서브패스를 통해 이 어댑터를 불러옵니다. 패키지를 갱신하면 실행할 구현도 바뀌지만 훅 파일은 그대로입니다.
|
|
66
|
+
|
|
67
|
+
일반 사용자가 직접 불러올 필요는 없으며 별도 설정 네임스페이스도 없습니다.
|
|
68
|
+
|
|
69
|
+
<a id="limits"></a>
|
|
70
|
+
## 선언된 한계
|
|
71
|
+
|
|
72
|
+
- **자식 프로세스의 쓰기는 관측 밖입니다.** 이 표면이 판정하는 것은 **선언된 도구
|
|
73
|
+
호출**입니다. 프로세스를 띄우고 그 프로세스가 파일을 쓰는 명령은, 테스트 러너든 빌드든,
|
|
74
|
+
명령에 대해 판정되지 자식이 한 일에 대해 판정되지 않습니다. 추적되는 파일에 대해서는
|
|
75
|
+
커밋 표면에서 결과를 별도로 관측할 수 있습니다.
|
|
76
|
+
- **증거는 후상태를 계산할 수 있는 곳에만 있습니다.** 변형 도구 넷이 전부 증거를 내고
|
|
77
|
+
노트북도 그렇습니다. `NotebookEdit`는 셀 단위 `modify` 증거를 냅니다. 증거가 없는 것은
|
|
78
|
+
이 어댑터가 해소하지 못하는 페이로드입니다. 읽을 수 없거나 파싱되지 않는 노트북, 이름을
|
|
79
|
+
붙일 수 없는 셀, 알지 못하는 편집 모드가 그렇습니다.
|
|
80
|
+
- **증거 없는 호출은 보수적으로 판정합니다.** 증명된 대상이 없으므로 호출 인자에 보호
|
|
81
|
+
경로가 언급됐는지 대조합니다.
|
|
82
|
+
- **저장소 밖 조상은 범위 밖입니다.** 프로젝트 루트 위의 경로는 여기서 관측하지 않습니다.
|
|
83
|
+
그 범위는 에이전트 실행 환경의 권한 정책으로 제한해야 합니다.
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# `@polydeukes/adapter-claude-code`
|
|
2
2
|
|
|
3
|
-
**English** · [한국어](
|
|
3
|
+
**English** · [한국어](adapter-claude-code.ko.md)
|
|
4
4
|
|
|
5
5
|
> **The session surface's translator** — PreToolUse payloads become the covenant input IR,
|
|
6
6
|
> with the file-change evidence and the transcript channel the judge reads.
|
|
7
7
|
>
|
|
8
8
|
> Alpha. A transitive dependency of the umbrella: you do not install it and you do not
|
|
9
9
|
> import it. The session surface reaches it through
|
|
10
|
-
> [`polydeukes/claude-code`](
|
|
10
|
+
> [`polydeukes/claude-code`](polydeukes.md#session-export).
|
|
11
11
|
|
|
12
|
+
<a id="ownership"></a>
|
|
12
13
|
## What this package owns
|
|
13
14
|
|
|
14
15
|
The boundary where Claude Code's vocabulary is translated away. Agent and tool literals
|
|
@@ -28,6 +29,7 @@ umbrella, which keeps dependencies one-way, through the core alone. It names
|
|
|
28
29
|
`@polydeukes/core` as a `peerDependency`: the vocabulary is shared with the judge, not
|
|
29
30
|
installed a second time here.
|
|
30
31
|
|
|
32
|
+
<a id="translation"></a>
|
|
31
33
|
## Payload translation and the three axes
|
|
32
34
|
|
|
33
35
|
**Three axes reach the judge**, and they differ in what evidence they can carry.
|
|
@@ -56,11 +58,12 @@ witness valve human-only: an AI cannot synthesize its own witness. A read failur
|
|
|
56
58
|
judged, an unreadable one is no evidence channel at all and is skipped. Either way the
|
|
57
59
|
valve turns off, never open.
|
|
58
60
|
|
|
59
|
-
**
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
**Precedent is a declaration, not an adapter evaluator.** This adapter supplies the
|
|
62
|
+
transcript snapshot. The declaration engine extracts succeeded `toolUses` and matches them;
|
|
63
|
+
there is no separate precedent evaluator in this package. The grammar is in
|
|
64
|
+
[Configuration — disciplines](../configuration/index.md#disciplines).
|
|
63
65
|
|
|
66
|
+
<a id="consumer-contract"></a>
|
|
64
67
|
## Where the consumer touches it
|
|
65
68
|
|
|
66
69
|
- **The generated hook**, which loads this adapter through the umbrella's `claude-code`
|
|
@@ -68,6 +71,7 @@ the compiler the evidence is unjudgeable, so the entry skips instead of judging
|
|
|
68
71
|
|
|
69
72
|
No import, and no configuration namespace of its own.
|
|
70
73
|
|
|
74
|
+
<a id="limits"></a>
|
|
71
75
|
## Declared limits
|
|
72
76
|
|
|
73
77
|
- **A child process's writes are outside observation.** This surface judges *declared tool
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# `@polydeukes/adapter-git`
|
|
2
|
+
|
|
3
|
+
[English](adapter-git.md) · **한국어**
|
|
4
|
+
|
|
5
|
+
> **커밋 표면의 번역기**입니다. 스테이징된 diff가 약속(covenant) 입력 IR이 되고,
|
|
6
|
+
> `adapters.git` 설정 네임스페이스가 여기서 정의됩니다.
|
|
7
|
+
>
|
|
8
|
+
> 알파입니다. 통합 패키지의 의존성으로 설치되므로 일반 사용자가 따로 설치하거나 불러올 필요는 없습니다. 커밋 표면은
|
|
9
|
+
> [`pdks covenant check`](polydeukes.ko.md#polydeukes-bin)를 통해 닿습니다.
|
|
10
|
+
|
|
11
|
+
<a id="ownership"></a>
|
|
12
|
+
## 담당하는 기능
|
|
13
|
+
|
|
14
|
+
Git의 변경 정보를 세션 표면과 같은 공통 입력 형식으로 번역합니다. 작성자가 AI인지 사람인지에 따라 판정 방식을 달리하지 않습니다.
|
|
15
|
+
|
|
16
|
+
| 단위 | 하는 일 |
|
|
17
|
+
|---|---|
|
|
18
|
+
| 스테이징 변경 수집 | 스테이징 영역을 내용 기준선을 갖춘 변경 목록으로 읽습니다 |
|
|
19
|
+
| 순수 번역 | 변경 목록을 하나의 `CovenantInput`으로 바꿉니다 |
|
|
20
|
+
| 설정 어휘 | 이 어댑터 자신의 설정 네임스페이스를 검증합니다 |
|
|
21
|
+
|
|
22
|
+
순수 라이브러리입니다. 스테이징된 diff의 형태를 알 뿐 설치나 훅 러너, 밸브는 알지
|
|
23
|
+
못합니다. pre-commit 훅에 배선하는 것은 우산이 맡는 배포 행위입니다.
|
|
24
|
+
`@polydeukes/core`는 `peerDependency`로 부릅니다. 판정기와 같은 어휘를 공유하며 별도 사본을 설치하지 않습니다.
|
|
25
|
+
|
|
26
|
+
<a id="collection"></a>
|
|
27
|
+
## 수집과 `adapters.git` 네임스페이스
|
|
28
|
+
|
|
29
|
+
**세 수집기가 같은 형식으로 결과를 반환합니다.** `collectStagedChanges` · `collectWorktreeChanges` ·
|
|
30
|
+
`collectRangeChanges({ repoRoot, range: '<base>..<head>' | '<base>...<head>' })`는 모두 같은
|
|
31
|
+
`StagedChange[]`를 반환하므로 이후에는 같은 번역기와 판정 경로를 사용합니다.
|
|
32
|
+
|
|
33
|
+
| 수집기 | `pre` | `post` | 그 밖에 |
|
|
34
|
+
|---|---|---|---|
|
|
35
|
+
| staged | HEAD blob | **스테이징된** blob. 워크트리는 쓰지 않습니다. `git add` 뒤에 갈라졌을 수 있습니다 | |
|
|
36
|
+
| worktree | HEAD blob | 디스크의 바이트 | 추적하지 않는 파일도 무시 대상이 아니면 `added`로 포함하며, 디스크에서 사라진 파일은 HEAD에 있었든 인덱스에만 있었든 `deleted`입니다. 읽을 수 없는 경로(깨진 심볼릭 링크)는 내용 null로 경로만 판정합니다 |
|
|
37
|
+
| range | base blob | head blob | `...`는 base를 `git merge-base`로 해소합니다. git이 해소하지 못하는 ref나 merge-base 없는 두 ref는 예외를 던집니다 |
|
|
38
|
+
|
|
39
|
+
**수집기는 증거로 사용할 수 있는 내용을 제한합니다.**
|
|
40
|
+
|
|
41
|
+
| 결정 | 이유 |
|
|
42
|
+
|---|---|
|
|
43
|
+
| 모든 수집기에서 `--no-renames` 강제 | 이름 변경을 삭제 더하기 추가로 판정합니다. 보호 파일의 `git mv`가 불투명한 이름 변경 항목 하나로 빠져나가면 안 됩니다 |
|
|
44
|
+
| 바이너리 blob이나 파일은 내용을 null로 | 손실 있게 디코딩된 바이트를 싣지 않습니다 |
|
|
45
|
+
| 첫 커밋 이전 상태는 전부 추가로 좁힘 | 예외를 던지지 않습니다. staged와 worktree가 같습니다 |
|
|
46
|
+
| 타입 변경(`T`)은 `pre`를 유지 | 심볼릭 링크가 파일로 바뀐 것은 수정이라, delta 판정이 사라진 내용을 봅니다 |
|
|
47
|
+
| 모든 목록 명령은 `--`로 끝남 | 파일과 이름이 같은 브랜치도 ref이지 모호한 인자가 아닙니다 |
|
|
48
|
+
|
|
49
|
+
번역은 변경 하나마다 도구 호출 하나를 만듭니다. 이름은 어댑터가 소유한 `staged-write`와
|
|
50
|
+
`staged-delete`입니다. 삭제는 언제나 증거를 답니다. 쓰기는 스테이징된 blob이 바이너리인
|
|
51
|
+
경우를 빼고 증거를 답니다. 그때는 견줄 텍스트가 없으므로 `fileChange` 없이 도착하고,
|
|
52
|
+
증명되지 않은 다른 호출과 똑같이 경로만으로 판정됩니다. **세션 컬렉션은 정직하게
|
|
53
|
+
비어 있습니다.** 커밋 표면에는 세션이 없고, 있는 것처럼 보이게 키를 지어내지 않습니다.
|
|
54
|
+
`actor`도 없습니다. 훅은 사람의 `git commit`과 에이전트의 것을 구별할 수 없으므로 아무것도
|
|
55
|
+
증명하지 않습니다.
|
|
56
|
+
|
|
57
|
+
**네임스페이스는 이 어댑터 자신의 어휘입니다.** 코어는 컨테이너 형태만 검증합니다.
|
|
58
|
+
어댑터마다 설정 객체 하나라는 것까지이고 내용은 그대로 통과시킵니다. 그래서 어휘와 그
|
|
59
|
+
검증기와 기본값이 전부 여기 있습니다.
|
|
60
|
+
|
|
61
|
+
| 키 | 값 | 기본값 | 뜻 |
|
|
62
|
+
|---|---|---|---|
|
|
63
|
+
| `adapters.git.enforce` | `block` \| `advise` | `block` | 커밋 표면의 판정이 무엇을 **하는지** |
|
|
64
|
+
| `adapters.git.protectedPaths` | string[] | `[]` | 커밋 표면의 **가산** 보호 범위입니다. 공통 목록 위에 얹혀 판정됩니다 |
|
|
65
|
+
|
|
66
|
+
알 수 없는 키, 허용된 두 값 이외의 `enforce`, 문자열 배열이 아닌 `protectedPaths`는
|
|
67
|
+
즉시 거부하며 오류에 전체 필드 경로를 표시합니다. 작성 레퍼런스는
|
|
68
|
+
[설정 레퍼런스의 `adapters` 절](../configuration/index.ko.md#adapters)입니다.
|
|
69
|
+
|
|
70
|
+
**추가 보호 범위는 관측자가 정합니다.** 강제 수준과 마찬가지로 해당 표면의 설정입니다. 여기 적힌 항목은 작업이 역사가 되는 시점에 판정되고 세션 표면은 그것을 읽지
|
|
71
|
+
않습니다. 저장소가 판정기 **소스**를 세션에서 편집할 수 있게 두면서도 그것을 올리는
|
|
72
|
+
커밋은 멈출 수 있는 이유가 이것입니다.
|
|
73
|
+
|
|
74
|
+
`enforce: advise`에서는 밸브를 구성하지 않습니다. 위반은 `advised`로 기록하고 권고를
|
|
75
|
+
stderr에 출력한 뒤 커밋을 계속합니다. 달라지는 것은 위반 뒤의 처리이지 판정 기준이 아닙니다.
|
|
76
|
+
판정할 수 없는 실행은 어느 강제 수준에서도 종료 코드 `2`로 차단합니다(fail-closed).
|
|
77
|
+
|
|
78
|
+
<a id="consumer-contract"></a>
|
|
79
|
+
## 사용자와의 접점
|
|
80
|
+
|
|
81
|
+
- **설정의 `adapters.git` 블록.**
|
|
82
|
+
- **`pdks covenant check`를 실행하는 pre-commit 훅.** 손으로 배선하며, 훅 관리자 셋의
|
|
83
|
+
수동 절차는
|
|
84
|
+
[설치](../../how-to/connect-surfaces.ko.md#commit-surface)에 있습니다.
|
|
85
|
+
|
|
86
|
+
일반 사용자가 직접 불러올 필요는 없습니다.
|
|
87
|
+
|
|
88
|
+
<a id="limits"></a>
|
|
89
|
+
## 선언된 한계
|
|
90
|
+
|
|
91
|
+
- **세션을 읽는 선언은 여기서 판정할 수 없습니다.** `precedent`는 세션 이력이 필요한데 커밋에는
|
|
92
|
+
없습니다. 항목이 `skipped`와 `supply-pass`를 남기는 것은 그 선언의 `supply`가 `pass`일
|
|
93
|
+
때뿐입니다. 정책이 없으면 없는 세션은 판정 불가(exit 2)입니다. 항목의 결함이 아니라 이
|
|
94
|
+
표면이 제공하는 증거의 한계입니다.
|
|
95
|
+
- **추적하지 않는 파일이 무시 대상이면 이 표면에서 관측하지 않습니다. 이미 추적 중인 파일은
|
|
96
|
+
`.gitignore`와 무관하게 관측합니다.** 무시 대상이며 한 번도 추가하지 않은 `dist`는 보이지
|
|
97
|
+
않지만, 추적 중인 파일은 나중에 무시 패턴에 해당하더라도 `git diff`에 남습니다. 세션 표면이 생성 경로를 공통 목록에
|
|
98
|
+
싣는 이유입니다.
|
|
99
|
+
- **밸브에는 터미널 앞의 사람이 필요합니다.** TTY가 없으면 프롬프트를 표시하지 못하므로
|
|
100
|
+
증언으로 차단을 해제할 수 없습니다. CI 실행과 에이전트가 시작한 `git commit`에도 같은 조건을 적용합니다. 무엇도
|
|
101
|
+
저장되지 않으므로 한 번의 답이 나중 커밋을 덮지 않습니다.
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# `@polydeukes/adapter-git`
|
|
2
2
|
|
|
3
|
-
**English** · [한국어](
|
|
3
|
+
**English** · [한국어](adapter-git.ko.md)
|
|
4
4
|
|
|
5
5
|
> **The commit surface's translator** — a staged diff becomes the covenant input IR, and
|
|
6
6
|
> the `adapters.git` config namespace is defined here.
|
|
7
7
|
>
|
|
8
8
|
> Alpha. A transitive dependency of the umbrella: you do not install it and you do not
|
|
9
9
|
> import it. The commit surface reaches it through
|
|
10
|
-
> [`pdks covenant check`](
|
|
10
|
+
> [`pdks covenant check`](polydeukes.md#polydeukes-bin).
|
|
11
11
|
|
|
12
|
+
<a id="ownership"></a>
|
|
12
13
|
## What this package owns
|
|
13
14
|
|
|
14
15
|
The boundary where git's vocabulary is translated away. A staged diff becomes the same
|
|
@@ -26,10 +27,12 @@ runners, or valves — wiring it into a pre-commit hook is a deployment act that
|
|
|
26
27
|
umbrella. It names `@polydeukes/core` as a `peerDependency`: the vocabulary is shared with
|
|
27
28
|
the judge, not installed a second time here.
|
|
28
29
|
|
|
30
|
+
<a id="collection"></a>
|
|
29
31
|
## Collection and the `adapters.git` namespace
|
|
30
32
|
|
|
31
33
|
**Three collectors, one shape.** `collectStagedChanges`, `collectWorktreeChanges`, and
|
|
32
|
-
`collectRangeChanges({ repoRoot, range: '<base>..<head>' | '<base>...<head>' })` each return the
|
|
34
|
+
`collectRangeChanges({ repoRoot, range: '<base>..<head>' | '<base>...<head>' })` each return the
|
|
35
|
+
same
|
|
33
36
|
`StagedChange[]`, so the translator and everything after it is one path.
|
|
34
37
|
|
|
35
38
|
| Collector | `pre` | `post` | Also |
|
|
@@ -67,7 +70,7 @@ vocabulary, its validator, and its defaults all live here.
|
|
|
67
70
|
|
|
68
71
|
An unknown key, an `enforce` outside the two values, or a `protectedPaths` that is not an
|
|
69
72
|
array of strings each fail fast with the full field path. The writing reference is
|
|
70
|
-
[the configuration reference's `adapters` section](
|
|
73
|
+
[the configuration reference's `adapters` section](../configuration/index.md#adapters).
|
|
71
74
|
|
|
72
75
|
**The additive scope is additive for a reason.** The level belongs to the observer, and so
|
|
73
76
|
does the scope: entries listed here are judged when work becomes history, and the session
|
|
@@ -75,26 +78,31 @@ surface never reads them. That is what lets a repository leave judge *sources* e
|
|
|
75
78
|
a session while still stopping the commit that promotes them.
|
|
76
79
|
|
|
77
80
|
Under `enforce: advise` the valve is structurally absent: a verdict is recorded as
|
|
78
|
-
`advised`, one advisory line lands on stderr, and the commit proceeds.
|
|
79
|
-
|
|
81
|
+
`advised`, one advisory line lands on stderr, and the commit proceeds. The response to a violation
|
|
82
|
+
changes, not the judgment criteria: a run that cannot judge still fails closed at exit `2` at either
|
|
83
|
+
level.
|
|
80
84
|
|
|
85
|
+
<a id="consumer-contract"></a>
|
|
81
86
|
## Where the consumer touches it
|
|
82
87
|
|
|
83
88
|
- **The `adapters.git` block** in your config.
|
|
84
89
|
- **The pre-commit hook** that runs `pdks covenant check`, wired by hand — the manual
|
|
85
90
|
procedure for three hook managers is in
|
|
86
|
-
[installation](
|
|
91
|
+
[installation](../../how-to/connect-surfaces.md#commit-surface).
|
|
87
92
|
|
|
88
93
|
No import.
|
|
89
94
|
|
|
95
|
+
<a id="limits"></a>
|
|
90
96
|
## Declared limits
|
|
91
97
|
|
|
92
98
|
- **A declaration that reads the session cannot be judged here.** A `precedent` needs
|
|
93
|
-
session history and a commit has none
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
99
|
+
session history and a commit has none. The entry records `skipped` with `supply-pass`
|
|
100
|
+
only when its own `supply` is `pass`; with no policy the missing session is unjudgeable
|
|
101
|
+
(exit 2). A permanent condition of this surface, not a fault in the entry.
|
|
102
|
+
- **Untracked ignored files are invisible here; already-tracked files are not.** `.gitignore`
|
|
103
|
+
does not hide a path git already tracks. A built `dist` that was never added stays
|
|
104
|
+
invisible; a tracked file that later matches an ignore line still appears in `git diff`.
|
|
105
|
+
That is why the session surface carries generated paths on the common list instead.
|
|
98
106
|
- **The valve needs a human at a terminal.** No TTY means no prompt and no way through: a
|
|
99
107
|
CI run and an agent-spawned `git commit` reach the same closed door. Nothing is ever
|
|
100
108
|
persisted, so one answer never covers a later commit.
|