polydeukes 0.6.1 → 0.8.0
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 +16 -28
- package/README.md +16 -28
- package/dist/baseline.d.ts +37 -1
- package/dist/baseline.js +68 -1
- package/dist/bin.d.ts +3 -4
- package/dist/bin.js +73 -90
- package/dist/covenant/bash-line.d.ts +130 -0
- package/dist/covenant/bash-line.js +566 -0
- package/dist/covenant/declaration-engine.d.ts +108 -0
- package/dist/covenant/declaration-engine.js +415 -0
- package/dist/covenant/discipline.d.ts +109 -0
- package/dist/covenant/discipline.js +667 -0
- package/dist/covenant/dispatch.d.ts +156 -0
- package/dist/covenant/dispatch.js +250 -0
- package/dist/covenant/extract-steps.d.ts +122 -0
- package/dist/covenant/extract-steps.js +0 -0
- package/dist/covenant/mention.d.ts +117 -0
- package/dist/covenant/mention.js +209 -0
- package/dist/covenant/module.d.ts +25 -0
- package/dist/covenant/module.js +23 -0
- package/dist/covenant/mutation-rules.d.ts +40 -0
- package/dist/covenant/mutation-rules.js +146 -0
- package/dist/covenant/relations.d.ts +46 -0
- package/dist/covenant/relations.js +68 -0
- package/dist/covenant/run-covenant.d.ts +95 -0
- package/dist/covenant/run-covenant.js +164 -0
- package/dist/covenant/self-mod.d.ts +55 -0
- package/dist/covenant/self-mod.js +84 -0
- package/dist/covenant/shell-evidence.d.ts +38 -0
- package/dist/covenant/shell-evidence.js +247 -0
- package/dist/covenant/shell-mod.d.ts +84 -0
- package/dist/covenant/shell-mod.js +213 -0
- package/dist/covenant/supply.d.ts +54 -0
- package/dist/covenant/supply.js +50 -0
- package/dist/covenant/transcript-mod.d.ts +60 -0
- package/dist/covenant/transcript-mod.js +254 -0
- package/dist/covenant/ttl-witness.d.ts +47 -0
- package/dist/covenant/ttl-witness.js +80 -0
- package/dist/covenant-check.d.ts +74 -41
- package/dist/covenant-check.js +372 -129
- package/dist/diff-ir.d.ts +28 -0
- package/dist/diff-ir.js +310 -0
- package/dist/docs/README.ko.md +10 -9
- package/dist/docs/README.md +10 -9
- package/dist/docs/catalog.json +76 -28
- package/dist/docs/concepts/judgment.ko.md +2 -2
- package/dist/docs/concepts/judgment.md +2 -2
- package/dist/docs/how-to/configure-project.ko.md +16 -16
- package/dist/docs/how-to/configure-project.md +15 -12
- package/dist/docs/how-to/connect-surfaces.ko.md +67 -34
- package/dist/docs/how-to/connect-surfaces.md +67 -34
- package/dist/docs/how-to/write-disciplines.ko.md +64 -7
- package/dist/docs/how-to/write-disciplines.md +65 -7
- package/dist/docs/index.json +744 -362
- package/dist/docs/reference/cli/covenant-check.ko.md +112 -65
- package/dist/docs/reference/cli/covenant-check.md +114 -59
- package/dist/docs/reference/cli/docs.ko.md +2 -2
- package/dist/docs/reference/cli/docs.md +2 -2
- package/dist/docs/reference/cli/explain.ko.md +20 -15
- package/dist/docs/reference/cli/explain.md +22 -15
- package/dist/docs/reference/cli/init.ko.md +91 -52
- package/dist/docs/reference/cli/init.md +81 -55
- package/dist/docs/reference/configuration/index.ko.md +182 -71
- package/dist/docs/reference/configuration/index.md +188 -76
- package/dist/docs/reference/packages/adapter-claude-code.ko.md +39 -11
- package/dist/docs/reference/packages/adapter-claude-code.md +40 -14
- package/dist/docs/reference/packages/adapter-codex.ko.md +99 -0
- package/dist/docs/reference/packages/adapter-codex.md +100 -0
- package/dist/docs/reference/packages/adapter-grok.ko.md +81 -0
- package/dist/docs/reference/packages/adapter-grok.md +83 -0
- package/dist/docs/reference/packages/core.ko.md +50 -4
- package/dist/docs/reference/packages/core.md +55 -6
- package/dist/docs/reference/packages/polydeukes.ko.md +139 -77
- package/dist/docs/reference/packages/polydeukes.md +147 -81
- package/dist/docs/reference/packages/sdk-ts.ko.md +164 -0
- package/dist/docs/reference/packages/sdk-ts.md +167 -0
- package/dist/docs/troubleshooting.ko.md +51 -19
- package/dist/docs/troubleshooting.md +53 -17
- package/dist/docs/tutorials/first-judgment.ko.md +6 -4
- package/dist/docs/tutorials/first-judgment.md +6 -4
- package/dist/explain.d.ts +1 -1
- package/dist/explain.js +37 -22
- package/dist/load-config.d.ts +25 -1
- package/dist/load-config.js +21 -3
- package/dist/pre-state-reader.d.ts +1 -1
- package/dist/pre-state-reader.js +1 -1
- package/dist/scaffold-project.d.ts +2 -2
- package/dist/scaffold-project.js +12 -4
- package/dist/schema/polydeukes.schema.json +12 -0
- package/dist/worktree-reader.d.ts +19 -0
- package/dist/worktree-reader.js +30 -0
- package/package.json +5 -18
- package/dist/claude-code-hook.d.ts +0 -79
- package/dist/claude-code-hook.js +0 -372
- package/dist/claude-code.d.ts +0 -6
- package/dist/claude-code.js +0 -6
- package/dist/covenant-module.d.ts +0 -25
- package/dist/covenant-module.js +0 -42
- package/dist/docs/reference/packages/adapter-git.ko.md +0 -101
- package/dist/docs/reference/packages/adapter-git.md +0 -108
- package/dist/docs/reference/packages/covenant.ko.md +0 -115
- package/dist/docs/reference/packages/covenant.md +0 -123
- package/dist/index.d.ts +0 -22
- package/dist/index.js +0 -21
- package/dist/init-claude-code.d.ts +0 -52
- package/dist/init-claude-code.js +0 -586
- package/dist/init-grok.d.ts +0 -51
- package/dist/init-grok.js +0 -242
|
@@ -2,100 +2,147 @@
|
|
|
2
2
|
|
|
3
3
|
[English](./covenant-check.md) · **한국어**
|
|
4
4
|
|
|
5
|
-
`pdks covenant check`는 설치된 패키지로
|
|
6
|
-
설정을 읽고
|
|
7
|
-
|
|
5
|
+
`pdks covenant check`는 설치된 패키지로 변경 집합 표면의 판정을 실행합니다. 작업 디렉터리에서
|
|
6
|
+
설정을 읽고 **stdin**에서 관측 하나를 받아, 세션 훅에서도 사용하는 판정 본체에 전달합니다.
|
|
7
|
+
저장소를 열지 않고 `git`을 부르지도 않습니다. 관측은 호출자가 만들고, 이 명령은 그것을
|
|
8
|
+
판정해 종료 코드로 답합니다.
|
|
8
9
|
|
|
9
10
|
<a id="covenant-check-syntax"></a>
|
|
10
11
|
## 구문
|
|
11
12
|
|
|
12
13
|
```sh
|
|
13
|
-
pdks covenant check
|
|
14
|
-
pdks covenant check --worktree
|
|
15
|
-
pdks covenant check --range <base>..<head>
|
|
16
|
-
pdks covenant check --range <base>...<head>
|
|
14
|
+
pdks covenant check [--diff] [--enforce advise|block]
|
|
17
15
|
```
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
`--diff`가 없으면 stdin은 약속(covenant) 입력 IR입니다. `@polydeukes/core`가 정의하는 JSON
|
|
18
|
+
문서(`toolCalls` · `subagentSpawns` · `userMessages`, 그리고 호스트가 더하는 선택 키 둘,
|
|
19
|
+
도구 명부 `tools`와 살아 있는 에이전트 세션의 증거 `session`)입니다. `--diff`를 주면 stdin은
|
|
20
|
+
unified diff이고, 명령이 먼저 그것을 IR로 번역합니다. `--enforce`는 이 실행의 관측자 자세이며
|
|
21
|
+
기본값은 `advise`입니다. 기본값에서는 모든 위반이 행으로 기록되고 종료 코드 0입니다. `--enforce block`을
|
|
22
|
+
주면 보호 경로 위반과 `enforce: block` 항목의 위반이 종료 코드 2가 됩니다. 플래그는 각각 한
|
|
23
|
+
번씩, 순서는 무관합니다. 그 밖의 인자는 사용법 오류입니다. stdin은 EOF까지 읽습니다.
|
|
22
24
|
|
|
23
25
|
<a id="covenant-check-boundaries"></a>
|
|
24
26
|
## 관측 경계
|
|
25
27
|
|
|
26
|
-
이 명령은
|
|
28
|
+
이 명령은 stdin이 담은 것만 판정합니다. 어떤 diff를 파이프로 넘기느냐가 관측을 정합니다.
|
|
27
29
|
|
|
28
|
-
|
|
|
29
|
-
|
|
30
|
-
| `pdks covenant check` |
|
|
31
|
-
| `pdks covenant check --
|
|
32
|
-
| `pdks covenant check --
|
|
33
|
-
| `pdks covenant check
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
30
|
+
| 파이프 | 관측 집합 |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `git diff --cached \| pdks covenant check --diff` | 스테이징한 변경. pre-commit 형태 |
|
|
33
|
+
| `git diff HEAD \| pdks covenant check --diff` | HEAD 대비 작업 트리 |
|
|
34
|
+
| `git diff <base>..<head> \| pdks covenant check --diff` | 두 ref 사이의 변경 집합(`...`는 merge-base 기준) |
|
|
35
|
+
| `pdks covenant check < input.json` | 호출자가 만든 IR 그대로 |
|
|
36
|
+
|
|
37
|
+
diff 형식은 VCS 중립입니다. git · jj · hg · 손으로 쓴 `diff -u`가 모두 같은 형식을 냅니다.
|
|
38
|
+
|
|
39
|
+
호스트가 만든 IR은 저장소 디스크에 없는 것을 담습니다. `tools`는 어느 도구 이름이 파일을
|
|
40
|
+
바꾸고 어느 것이 명령줄을 담는지(`mutating` · `shell` · `commandArgs`)를 값으로 적습니다.
|
|
41
|
+
어휘가 아니라 값이며, 이것이 없으면 명령은 diff가 만드는 staged 이름만 라우팅합니다.
|
|
42
|
+
`session`은 타임스탬프가 있는 사람의 메시지(TTL 증인이 읽는 것), 이미 실행된 호출과 그
|
|
43
|
+
결과(선행 조건 선언이 읽는 것), 증거를 읽어 온 파일의 절대 경로(이 실행 동안 동일성으로
|
|
44
|
+
보호), 스폰 사이드카 텍스트를 담습니다. 선언이 지정한 파일은 명령이 작업 트리에서 직접
|
|
45
|
+
읽고, 자체 `world` 키를 담은 IR은 거부합니다. 세션 입력은 이 명령이 관측하지 못하는 변경
|
|
46
|
+
집합의 한 호출이므로 변경 집합 선언은 거기서 `skipped`로 기록됩니다. 판정 전후에는 세션
|
|
47
|
+
표면과 같은 방식으로 보호 항목을 저장된 기준선과 비교합니다.
|
|
48
|
+
|
|
49
|
+
<a id="diff-translation"></a>
|
|
50
|
+
## diff가 IR이 되는 방식
|
|
51
|
+
|
|
52
|
+
파일 블록 하나가 `toolCall` 하나가 되며 입력 순서를 지킵니다. 도구 이름은 생성·수정이
|
|
53
|
+
`staged-write`, 삭제가 `staged-delete`입니다. `args.file_path`는 저장소 기준 상대 경로이며
|
|
54
|
+
`a/` 또는 `b/` 접두 한 단계를 벗기고 따옴표 경로는 이스케이프를 풉니다.
|
|
55
|
+
|
|
56
|
+
| diff 블록 | 증거 |
|
|
57
|
+
|---|---|
|
|
58
|
+
| `--- /dev/null` → `+++ b/P` | `create`, `post` = 모든 `+` 줄 |
|
|
59
|
+
| `--- a/P` → `+++ /dev/null` | `delete`, `pre` = 모든 `-` 줄 |
|
|
60
|
+
| `--- a/P` → `+++ b/P`, hunk 있음 | `modify`, `pre` = `-` 줄, `post` = `+` 줄 |
|
|
61
|
+
| 같은 경로, hunk 없음(모드 변경) | `pre`와 `post`가 빈 `modify` |
|
|
62
|
+
| `rename from O` / `rename to N` | `staged-delete` O, 그다음 hunk 줄을 `modify` 증거로 담은 `staged-write` N |
|
|
63
|
+
| `Binary files … differ` / `GIT binary patch` | 경로만. 증거가 없으므로 경로 판정만 적용 |
|
|
64
|
+
|
|
65
|
+
**수정의 `pre`와 `post`는 hunk 줄이지 파일 전체가 아닙니다.** 문맥 줄과
|
|
66
|
+
`` 표시는 버립니다. 이 저장소가 배포하는 규율 가운데 `pre`·`post`를
|
|
67
|
+
읽는 것은 모두 줄 단위로 키를 뽑아 비교하므로 파일 전체로 판정한 것과 같은 판정이 나옵니다.
|
|
68
|
+
파일의 전체 텍스트가 필요한 선언은 그 파일을 `source`로 지정하고, 그것은 아래의 세계 축에서
|
|
69
|
+
읽습니다. 생성과 삭제는 전체 텍스트를 담습니다.
|
|
70
|
+
|
|
71
|
+
**세계 축은 작업 트리입니다.** 선언이 `source`로 지정한 파일은 작업 디렉터리의 디스크에서
|
|
72
|
+
읽습니다. index도 ref도 아닙니다. index와 디스크가 다르면(부분 스테이징) 판정되는 텍스트는
|
|
73
|
+
디스크의 것입니다. 변경 집합(`world.changes`)은 증거를 지닌 toolCall들의 경로 목록입니다.
|
|
74
|
+
|
|
75
|
+
**주체는 없습니다.** diff는 작성자를 증명하지 못하므로 번역된 IR에는 `actor` 키가 없습니다.
|
|
76
|
+
주체 범위의 규율은 이 표면에서 건너뜁니다.
|
|
54
77
|
|
|
55
78
|
<a id="covenant-check-results"></a>
|
|
56
79
|
## 결과와 종료 코드
|
|
57
80
|
|
|
58
81
|
| 상황 | 결과 |
|
|
59
82
|
|---|---|
|
|
60
|
-
| covenant
|
|
61
|
-
| `
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
83
|
+
| 약속(covenant) 위반 없음 | exit `0`. 어느 등록에도 라우팅되지 않은 toolCall은 `covenant-check` 라벨의 `passed` 행 하나를 남깁니다 |
|
|
84
|
+
| 규율 항목 위반(기본 `advise`) | exit `0`, `advised` 행 하나, stderr에 `why`와 권고 요약 한 줄 |
|
|
85
|
+
| 보호 경로 위반 또는 `enforce: block` 항목 위반, 기본 자세 | exit `0`, `advised` 행 하나. 이 표면에는 사람이 답할 밸브가 없고, 스테이징된 관문 파일 변경은 이미 세션 표면에서 판정을 받은 것입니다 |
|
|
86
|
+
| 같은 위반, `--enforce block` | exit `2`, `blocked` 행 하나 |
|
|
87
|
+
| `--diff`에 0바이트 stdin | exit `0`, 행 없음. 스테이징이 없으면 판정할 것도 없습니다 |
|
|
88
|
+
| `--diff` 없이 0바이트 stdin | exit `2`. 빈 페이로드는 IR이 아닙니다 |
|
|
89
|
+
| JSON 파싱 실패 · 객체가 아님 · `toolCalls` 배열 부재 | exit `2`, `covenant-check`의 `blocked` 행 하나 |
|
|
90
|
+
| IR이 자체 `world` 키를 담은 경우 | exit `2`. 세계 축은 이 명령이 채웁니다 |
|
|
91
|
+
| `tools`의 목록이 빠졌거나 문자열 아닌 이름을 담은 경우, `session`에 `userMessages`·`toolCalls` 배열이 없는 경우 | exit `2`, `blocked` `covenant-check` 행 1건. 판정할 수 없는 형상은 기본값이 아니라 차단입니다 |
|
|
92
|
+
| `session`의 토큰 메시지가 설정의 `witness` 안에서 신선한 경우 | 차단 판정이 `witnessed`로 기록되고 exit `0`. 세션 표면이 여는 것과 같은 밸브입니다 |
|
|
93
|
+
| 병합 diff(`diff --cc`) · 짝이 맞지 않는 `---`/`+++` · 미지의 hunk 줄 | exit `2`, `covenant-check`의 `blocked` 행 하나 |
|
|
94
|
+
| 다른 인자 | exit `2`, stderr에 사용법 줄. stdin은 읽지 않습니다 |
|
|
95
|
+
| 설정 부재 · 중복 · 무효 | exit `2` |
|
|
96
|
+
| 판정 본체 로드 실패 | exit `2` |
|
|
97
|
+
|
|
98
|
+
자세는 설정이 아니라 명령줄에 있고, 프롬프트는 없습니다. 이 명령은 성공 또는 실패를 답하고,
|
|
99
|
+
커밋을 진행할지는 이 명령을 스폰한 훅이 정합니다. 행은 판정만 기록하고, 커밋이 진행됐는지는
|
|
100
|
+
기록하지 않습니다. 배선이 종료 코드를 무시해 커밋이 진행됐더라도 `blocked` 행은 그대로 남습니다.
|
|
77
101
|
|
|
78
102
|
<a id="covenant-check-examples"></a>
|
|
79
103
|
## 예제
|
|
80
104
|
|
|
81
105
|
```sh
|
|
82
|
-
pdks covenant check
|
|
83
|
-
pdks covenant check --
|
|
84
|
-
pdks covenant check --
|
|
85
|
-
pdks covenant check --
|
|
106
|
+
git diff --cached | pdks covenant check --diff # pre-commit, 기록만
|
|
107
|
+
git diff --cached | pdks covenant check --diff --enforce block # pre-commit, 위반을 거부
|
|
108
|
+
git diff HEAD | pdks covenant check --diff # 작업 뒤
|
|
109
|
+
git diff main...HEAD | pdks covenant check --diff # PR 전
|
|
110
|
+
pdks covenant check < input.json # 다른 프로그램이 만든 IR
|
|
86
111
|
```
|
|
87
112
|
|
|
88
|
-
|
|
89
|
-
|
|
113
|
+
<a id="pin-the-producer"></a>
|
|
114
|
+
## 생산자를 고정하기
|
|
115
|
+
|
|
116
|
+
관측은 이 패키지 밖의 프로세스가 만들고, git 자체의 설정이 그 텍스트를 바꿀 수 있습니다.
|
|
117
|
+
판정되는 텍스트가 스테이징한 텍스트이도록 훅에는 다음 플래그를 씁니다.
|
|
90
118
|
|
|
91
|
-
|
|
92
|
-
|
|
119
|
+
| 플래그 | 막는 것 |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `--no-color` | `color.ui=always`는 모든 줄을 이스케이프 코드로 감쌉니다. 번역기가 블록을 인식하지 못해 exit 2로 fail-closed됩니다 |
|
|
122
|
+
| `--no-ext-diff` / `--no-textconv` | `diff.external`이나 `.gitattributes`의 textconv 드라이버는 디스크 어디에도 없는 텍스트를 내고, 규율은 그 텍스트를 판정하게 됩니다 |
|
|
123
|
+
| `--src-prefix=a/ --dst-prefix=b/` | `diff.mnemonicPrefix`는 `c/`·`i/`·`w/`를 찍습니다. 번역기는 정확히 `a/`와 `b/`만 벗기므로 다른 접두는 판정 경로에 남습니다 |
|
|
124
|
+
|
|
125
|
+
생산자가 도중에 죽으면 stdin은 0바이트가 되고, 그것은 빈 관측이라 exit 0입니다. 셸이
|
|
126
|
+
지원하면 파이프 앞에 `set -o pipefail;`을 두어 git의 실패를 훅의 실패로 만듭니다.
|
|
127
|
+
|
|
128
|
+
모든 판정을 기록하고 판정 불가일 때만 커밋을 멈추는 lefthook 명령입니다.
|
|
129
|
+
|
|
130
|
+
```yaml
|
|
131
|
+
pre-commit:
|
|
132
|
+
commands:
|
|
133
|
+
covenant:
|
|
134
|
+
run: git diff --cached --no-color --no-ext-diff --no-textconv --src-prefix=a/ --dst-prefix=b/ | ./node_modules/.bin/pdks covenant check --diff
|
|
93
135
|
```
|
|
94
136
|
|
|
137
|
+
보호 경로 위반에도 커밋을 멈추려면 그 줄에 `--enforce block`을 덧붙입니다.
|
|
138
|
+
|
|
139
|
+
다른 프로그램에서 판정을 쓰려면 `pdks covenant check`를 실행하고 그 프로세스의 표준 입력에
|
|
140
|
+
입력 IR이나 diff를 씁니다. 종료 코드가 판정 결과입니다.
|
|
141
|
+
|
|
95
142
|
<a id="covenant-check-see-also"></a>
|
|
96
143
|
## 같이 보기
|
|
97
144
|
|
|
98
145
|
- [`pdks explain`](./explain.ko.md)
|
|
99
|
-
- [`@polydeukes/
|
|
100
|
-
- [
|
|
101
|
-
- [
|
|
146
|
+
- [`@polydeukes/core`](../packages/core.ko.md)
|
|
147
|
+
- [판정기(`covenant` 모듈)](../packages/polydeukes.ko.md#covenant-module)
|
|
148
|
+
- [설정 레퍼런스](../configuration/index.ko.md)
|
|
@@ -2,97 +2,152 @@
|
|
|
2
2
|
|
|
3
3
|
**English** · [한국어](./covenant-check.ko.md)
|
|
4
4
|
|
|
5
|
-
`pdks covenant check` runs the
|
|
6
|
-
config from the working directory,
|
|
7
|
-
|
|
5
|
+
`pdks covenant check` runs the change-set-surface judgment against the installed package. It reads the
|
|
6
|
+
config from the working directory, takes one observation from **stdin**, and dispatches the same
|
|
7
|
+
judge bodies that the session hook uses. It never opens a repository and never calls `git`: the
|
|
8
|
+
caller produces the observation, the command judges it and answers with an exit code.
|
|
8
9
|
|
|
9
10
|
<a id="covenant-check-syntax"></a>
|
|
10
11
|
## Syntax
|
|
11
12
|
|
|
12
13
|
```sh
|
|
13
|
-
pdks covenant check
|
|
14
|
-
pdks covenant check --worktree
|
|
15
|
-
pdks covenant check --range <base>..<head>
|
|
16
|
-
pdks covenant check --range <base>...<head>
|
|
14
|
+
pdks covenant check [--diff] [--enforce advise|block]
|
|
17
15
|
```
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
Without `--diff`, stdin is the covenant input IR — the JSON document `@polydeukes/core` defines
|
|
18
|
+
(`toolCalls`, `subagentSpawns`, `userMessages`, and the two optional keys a host adds:
|
|
19
|
+
`tools`, its tool roster, and `session`, the evidence a live agent session carries). With
|
|
20
|
+
`--diff`, stdin is a unified diff and the command translates it into that IR first.
|
|
21
|
+
`--enforce` is the observer's posture for the run and
|
|
22
|
+
defaults to `advise`: every break lands as a row and exit 0. `--enforce block` makes a protected
|
|
23
|
+
path or an entry set to `enforce: block` exit 2. Each flag at most once, in either order; any
|
|
24
|
+
other argument is a usage error. stdin is read to EOF.
|
|
21
25
|
|
|
22
26
|
<a id="covenant-check-boundaries"></a>
|
|
23
27
|
## Observation boundaries
|
|
24
28
|
|
|
25
|
-
The command
|
|
29
|
+
The command judges exactly what stdin carries. Which diff you pipe decides the observation:
|
|
26
30
|
|
|
27
|
-
|
|
|
28
|
-
|
|
29
|
-
| `pdks covenant check` | Staged changes
|
|
30
|
-
| `pdks covenant check --
|
|
31
|
-
| `pdks covenant check --
|
|
32
|
-
| `pdks covenant check
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
31
|
+
| Pipe | Observed set |
|
|
32
|
+
|---|---|
|
|
33
|
+
| `git diff --cached \| pdks covenant check --diff` | Staged changes — the pre-commit shape |
|
|
34
|
+
| `git diff HEAD \| pdks covenant check --diff` | The working tree against HEAD |
|
|
35
|
+
| `git diff <base>..<head> \| pdks covenant check --diff` | The change set between two refs (`...` for the merge-base reading) |
|
|
36
|
+
| `pdks covenant check < input.json` | Whatever IR the caller built |
|
|
37
|
+
|
|
38
|
+
The diff format is VCS-neutral: git, jj, hg, and a hand-written `diff -u` all produce it.
|
|
39
|
+
|
|
40
|
+
An IR built by a host carries what the repository's disk cannot show. `tools` names which tool
|
|
41
|
+
names change a file and which carry a command line (`mutating`, `shell`, `commandArgs`) — values,
|
|
42
|
+
never vocabulary — and without it only the staged names a diff produces are routed. `session`
|
|
43
|
+
carries the human messages with their timestamps (what the TTL witness reads), the calls already
|
|
44
|
+
made with their outcomes (what a precedent declaration reads), the absolute path the evidence was
|
|
45
|
+
read from (protected by equality for the run), and the spawn sidecar text. The command reads the
|
|
46
|
+
working tree itself for every file a declaration names; an IR that supplies its own `world` is
|
|
47
|
+
refused. A session input is one call of a change set the command cannot see, so a change-set
|
|
48
|
+
declaration records `skipped` there, and the protected entries are compared against the stored
|
|
49
|
+
baseline around the judgment exactly as the session surface does.
|
|
50
|
+
|
|
51
|
+
<a id="diff-translation"></a>
|
|
52
|
+
## How a diff becomes the IR
|
|
53
|
+
|
|
54
|
+
One `toolCall` per file block, in input order. The tool name is `staged-write` for a creation or
|
|
55
|
+
modification and `staged-delete` for a deletion; `args.file_path` is the repo-relative path with
|
|
56
|
+
one `a/` or `b/` prefix stripped and quoted paths unescaped.
|
|
57
|
+
|
|
58
|
+
| Diff block | Evidence |
|
|
59
|
+
|---|---|
|
|
60
|
+
| `--- /dev/null` → `+++ b/P` | `create`, `post` = every `+` line |
|
|
61
|
+
| `--- a/P` → `+++ /dev/null` | `delete`, `pre` = every `-` line |
|
|
62
|
+
| `--- a/P` → `+++ b/P` with hunks | `modify`, `pre` = the `-` lines, `post` = the `+` lines |
|
|
63
|
+
| Same path, no hunks (a mode change) | `modify` with empty `pre` and `post` |
|
|
64
|
+
| `rename from O` / `rename to N` | `staged-delete` O, then `staged-write` N as `modify` over the hunks |
|
|
65
|
+
| `Binary files … differ` / `GIT binary patch` | The path only — no evidence, so only path judgments apply |
|
|
66
|
+
|
|
67
|
+
**A modification's `pre` and `post` are the hunk lines, not the whole file.** Context lines and
|
|
68
|
+
the `` marker are dropped. Every shipped discipline that reads `pre`
|
|
69
|
+
and `post` compares keyed lines, so the verdict is the one the whole file would give; a
|
|
70
|
+
declaration that needs a file's full text names it as a `source`, and that is read from the
|
|
71
|
+
world axis below. Creations and deletions carry the full text.
|
|
72
|
+
|
|
73
|
+
**The world axis is the working tree.** A file a declaration names by `source` is read from disk
|
|
74
|
+
under the working directory — not from the index, not from a ref. When the index and the disk
|
|
75
|
+
differ (a partially staged file), the judged text is the disk's. The change set (`world.changes`)
|
|
76
|
+
is the list of paths whose toolCalls carry evidence.
|
|
77
|
+
|
|
78
|
+
**No actor.** A diff proves no author, so the translated IR carries no `actor` key; actor-scoped
|
|
79
|
+
disciplines skip on this surface.
|
|
51
80
|
|
|
52
81
|
<a id="covenant-check-results"></a>
|
|
53
82
|
## Results and exit codes
|
|
54
83
|
|
|
55
84
|
| Situation | Result |
|
|
56
85
|
|---|---|
|
|
57
|
-
| No covenant breaks | exit `0` |
|
|
58
|
-
| A break
|
|
59
|
-
| A
|
|
60
|
-
|
|
|
61
|
-
|
|
|
62
|
-
|
|
|
63
|
-
|
|
|
86
|
+
| No covenant breaks | exit `0`; a toolCall no registration routed leaves one `passed` row under the `covenant-check` label |
|
|
87
|
+
| A break on a discipline entry (default `advise`) | exit `0`, one `advised` row, the `why` and one advisory summary on stderr |
|
|
88
|
+
| A break on a protected path or an entry set to `enforce: block`, default posture | exit `0`, one `advised` row — this surface has no valve a human could answer, and a staged gate-file change already passed the session surface |
|
|
89
|
+
| The same break under `--enforce block` | exit `2`, one `blocked` row |
|
|
90
|
+
| 0 bytes on stdin with `--diff` | exit `0`, no rows — nothing staged is nothing to judge |
|
|
91
|
+
| 0 bytes on stdin without `--diff` | exit `2` — an empty payload is not an IR |
|
|
92
|
+
| Unparseable JSON, a non-object, or a missing `toolCalls` array | exit `2`, one `blocked` `covenant-check` row |
|
|
93
|
+
| An IR carrying its own `world` key | exit `2` — the world axis is the command's to fill |
|
|
94
|
+
| A `tools` whose lists are missing or hold a non-string name, or a `session` without `userMessages` and `toolCalls` arrays | exit `2`, one `blocked` `covenant-check` row — a shape the command cannot judge is a block, never a default |
|
|
95
|
+
| A `session` whose token message is fresh under the config's `witness` | the blocked verdict lands `witnessed`, exit `0` — the same valve the session surface opens |
|
|
96
|
+
| A combined diff (`diff --cc`), an unmatched `---`/`+++`, or an unknown hunk line | exit `2`, one `blocked` `covenant-check` row |
|
|
97
|
+
| Any other argument | exit `2` with the usage line on stderr, stdin unread |
|
|
64
98
|
| Missing, ambiguous, or invalid config | exit `2` |
|
|
65
|
-
| Unresolved range or missing merge-base | exit `2` |
|
|
66
99
|
| Judge body cannot load | exit `2` |
|
|
67
100
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
`exit 0` can mean passing, advising, skipping, or an empty observation set. `exit 2` means the run
|
|
73
|
-
was fail-closed or the witness token did not open the gate.
|
|
101
|
+
The posture lives on the command line, not in the config, and there is no prompt. The command
|
|
102
|
+
answers success or failure; whether a commit proceeds is decided by the hook that spawned it. A
|
|
103
|
+
row records the verdict, not the commit's fate — a `blocked` row can sit beside a commit that
|
|
104
|
+
landed because the wiring ignored the exit code.
|
|
74
105
|
|
|
75
106
|
<a id="covenant-check-examples"></a>
|
|
76
107
|
## Examples
|
|
77
108
|
|
|
78
109
|
```sh
|
|
79
|
-
pdks covenant check
|
|
80
|
-
pdks covenant check --
|
|
81
|
-
pdks covenant check --
|
|
82
|
-
pdks covenant check --
|
|
110
|
+
git diff --cached | pdks covenant check --diff # pre-commit, record only
|
|
111
|
+
git diff --cached | pdks covenant check --diff --enforce block # pre-commit, refuse a break
|
|
112
|
+
git diff HEAD | pdks covenant check --diff # after a task
|
|
113
|
+
git diff main...HEAD | pdks covenant check --diff # before a PR
|
|
114
|
+
pdks covenant check < input.json # an IR another program built
|
|
83
115
|
```
|
|
84
116
|
|
|
85
|
-
|
|
86
|
-
|
|
117
|
+
<a id="pin-the-producer"></a>
|
|
118
|
+
## Pin the producer
|
|
87
119
|
|
|
88
|
-
|
|
89
|
-
|
|
120
|
+
The observation is produced by a process outside this package, and git's own configuration
|
|
121
|
+
can change its text. Wire a hook with these flags so the judged text is the staged text:
|
|
122
|
+
|
|
123
|
+
| Flag | What it prevents |
|
|
124
|
+
|---|---|
|
|
125
|
+
| `--no-color` | `color.ui=always` wraps every line in escape codes; the translator recognizes no block and the run fails closed (exit 2) |
|
|
126
|
+
| `--no-ext-diff` / `--no-textconv` | `diff.external` or a `.gitattributes` textconv driver substitutes text that exists nowhere on disk, and the disciplines judge that text |
|
|
127
|
+
| `--src-prefix=a/ --dst-prefix=b/` | `diff.mnemonicPrefix` prints `c/`, `i/`, `w/`; the translator strips exactly `a/` and `b/`, so any other prefix survives into the judged path |
|
|
128
|
+
|
|
129
|
+
A producer that dies mid-stream leaves 0 bytes on stdin, which is the empty observation and
|
|
130
|
+
exit 0. Where the shell supports it, `set -o pipefail;` in front of the pipeline makes git's
|
|
131
|
+
failure the hook's failure.
|
|
132
|
+
|
|
133
|
+
A lefthook command that records every verdict and stops the commit only on a fail-closed run:
|
|
134
|
+
|
|
135
|
+
```yaml
|
|
136
|
+
pre-commit:
|
|
137
|
+
commands:
|
|
138
|
+
covenant:
|
|
139
|
+
run: git diff --cached --no-color --no-ext-diff --no-textconv --src-prefix=a/ --dst-prefix=b/ | ./node_modules/.bin/pdks covenant check --diff
|
|
90
140
|
```
|
|
91
141
|
|
|
142
|
+
Append `--enforce block` to that line to stop the commit on a protected-path break too.
|
|
143
|
+
|
|
144
|
+
Another program embeds the judgment by spawning `pdks covenant check` and writing its input IR
|
|
145
|
+
or diff to that process's stdin; the exit code is the verdict.
|
|
146
|
+
|
|
92
147
|
<a id="covenant-check-see-also"></a>
|
|
93
148
|
## See also
|
|
94
149
|
|
|
95
150
|
- [`pdks explain`](./explain.md)
|
|
96
|
-
- [`@polydeukes/
|
|
97
|
-
- [
|
|
98
|
-
- [
|
|
151
|
+
- [`@polydeukes/core`](../packages/core.md)
|
|
152
|
+
- [The judge (`covenant` module)](../packages/polydeukes.md#covenant-module)
|
|
153
|
+
- [Configuration reference](../configuration/index.md)
|
|
@@ -25,10 +25,10 @@ pdks docs show <document-id> [--lang en|ko] [--section <section-id>] [--json]
|
|
|
25
25
|
```sh
|
|
26
26
|
pdks docs search 'locale key pairing'
|
|
27
27
|
pdks docs search '번역 키 짝 맞춤' --lang ko --limit 3
|
|
28
|
-
pdks docs search --
|
|
28
|
+
pdks docs search --diff --json
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
검색어는 인수 하나입니다. 여러 단어로 검색할 때는 따옴표로 묶습니다. `--
|
|
31
|
+
검색어는 인수 하나입니다. 여러 단어로 검색할 때는 따옴표로 묶습니다. `--diff` 같은
|
|
32
32
|
식별자도 첫 번째 검색 인수로 사용할 수 있습니다. 그 뒤에 오는 알 수 없는 플래그는
|
|
33
33
|
오류입니다. 결과 개수는 1부터 50까지의 정수이며 기본값은 5입니다. 선택한 언어의 절을
|
|
34
34
|
대상으로 제목, 문서 메타데이터, Markdown 본문을 검색합니다. 공백으로 나눈 검색어가
|
|
@@ -25,10 +25,10 @@ The default language is English. The five legacy topics remain `install`, `confi
|
|
|
25
25
|
```sh
|
|
26
26
|
pdks docs search 'locale key pairing'
|
|
27
27
|
pdks docs search '번역 키 짝 맞춤' --lang ko --limit 3
|
|
28
|
-
pdks docs search --
|
|
28
|
+
pdks docs search --diff --json
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
The query is one argument. Quote multiword queries. A literal identifier such as `--
|
|
31
|
+
The query is one argument. Quote multiword queries. A literal identifier such as `--diff`
|
|
32
32
|
is accepted as the first search argument; subsequent unknown flags are errors. Limits are
|
|
33
33
|
integers from 1 to 50, defaulting to 5. Search selects sections in the requested language and
|
|
34
34
|
uses their titles, document metadata, and Markdown text. Every whitespace-separated query term
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
pdks explain
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
추가 인자는 허용하지 않습니다. 작업 디렉터리의
|
|
15
|
+
추가 인자는 허용하지 않습니다. 작업 디렉터리의 설정을 읽고, 두 표면을 조립한 뒤 결과를 출력합니다.
|
|
16
16
|
|
|
17
17
|
<a id="explain-what-it-shows"></a>
|
|
18
18
|
## 무엇을 보여 주는가
|
|
@@ -34,10 +34,9 @@ pdks explain
|
|
|
34
34
|
|
|
35
35
|
| 상황 | 결과 |
|
|
36
36
|
|---|---|
|
|
37
|
-
| 설정이 유효하고
|
|
37
|
+
| 설정이 유효하고 두 표면이 조립됨 | 종료 `0` |
|
|
38
38
|
| 추가 인자 | 종료 `2`, stderr에 사용법 출력 |
|
|
39
39
|
| 설정이 없거나 여러 개이거나 유효하지 않음 | 종료 `2` |
|
|
40
|
-
| 판정 패키지를 불러올 수 없음 | 종료 `2` |
|
|
41
40
|
| 그 밖의 조립 실패 | 종료 `2` |
|
|
42
41
|
|
|
43
42
|
실패 시 stdout은 0바이트로 남습니다. 중간 테이블을 출력하지 않습니다.
|
|
@@ -49,24 +48,30 @@ pdks explain
|
|
|
49
48
|
pdks explain
|
|
50
49
|
```
|
|
51
50
|
|
|
52
|
-
출력은 설정 파일 경로로 시작하고, 그다음 세션 표면 블록 하나와
|
|
53
|
-
추가 규율이 없는 시작 설정은 이런
|
|
51
|
+
출력은 설정 파일 경로로 시작하고, 그다음 세션 표면 블록 하나와 변경 집합 표면 블록 하나가 나옵니다.
|
|
52
|
+
추가 규율이 없는 시작 설정은 이런 모양입니다(`N`은 조립이 센 보호 경로 개수이고, `skip` 행 하나는 정상입니다. 쓰기 대상을 판정할 수 없는 셸 명령이 착지하는 자리입니다).
|
|
54
53
|
|
|
55
54
|
```text
|
|
56
55
|
pdks explain — polydeukes.config.yaml
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
registrations 3 · declare 0 · skip
|
|
60
|
-
meta self-mod
|
|
61
|
-
meta
|
|
62
|
-
|
|
57
|
+
input: call IR (one call, stdin) · disciplines 0 · sessionDisciplines 0 · disciplines: advise unless enforce: block · meta: block
|
|
58
|
+
registrations 3 · declare 0 · skip 1 · meta 2 · draft 0
|
|
59
|
+
meta self-mod paths N (common; includes the config file itself)
|
|
60
|
+
meta transcript-mod content predicate · conditional: session.evidencePath
|
|
61
|
+
skip shell-unjudgeable a shell command whose write target this layer cannot determine
|
|
63
62
|
|
|
64
|
-
|
|
65
|
-
registrations 2 · declare 0 · skip
|
|
66
|
-
meta self-mod
|
|
67
|
-
|
|
63
|
+
input: --diff (change set, stdin) · disciplines 0 · changeSetDisciplines 0 · disciplines: advise unless enforce: block
|
|
64
|
+
registrations 2 · declare 0 · skip 1 · meta 1 · draft 0
|
|
65
|
+
meta self-mod paths N (common; includes the config file itself)
|
|
66
|
+
skip shell-unjudgeable a shell command whose write target this layer cannot determine
|
|
68
67
|
```
|
|
69
68
|
|
|
69
|
+
**표면 머리줄은 그 표면이 컴파일하는 목록의 이름과 각 목록의 항목 수를 적습니다.** 세션
|
|
70
|
+
머리줄은 `disciplines <n> · sessionDisciplines <n>`을, 변경 집합 머리줄은
|
|
71
|
+
`disciplines <n> · changeSetDisciplines <n>`을 출력하며, 두 수 모두 조립 전에 설정에 적힌
|
|
72
|
+
그대로 셉니다. 판정을 돌리지 않고 모든 항목의 배치를 확인하는 방법이 이 머리줄 둘을 읽는
|
|
73
|
+
것입니다. 목록을 옮긴 항목은 두 머리줄에서 각각 수 하나를 움직입니다.
|
|
74
|
+
|
|
70
75
|
`N`은 조립된 경로 개수입니다. `declare` 행의 라벨은 항목 `id`이고 설명은 카탈로그 좌표입니다.
|
|
71
76
|
`skip` 행은 건너뛴 이유를 적습니다. `draft` 행은 `unpromoted — no judgment`입니다.
|
|
72
77
|
|
|
@@ -75,5 +80,5 @@ surface: commit (git pre-commit) · enforce: block · disciplines: advise unless
|
|
|
75
80
|
|
|
76
81
|
- [`pdks covenant check`](./covenant-check.ko.md)
|
|
77
82
|
- [`pdks init`](./init.ko.md)
|
|
78
|
-
- [
|
|
83
|
+
- [판정기(`covenant` 모듈)](../packages/polydeukes.ko.md#covenant-module)
|
|
79
84
|
- [설정 참조](../configuration/index.ko.md)
|
|
@@ -13,8 +13,8 @@ a second opinion.
|
|
|
13
13
|
pdks explain
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
Any extra argument is invalid. The command reads the config at the working directory,
|
|
17
|
-
|
|
16
|
+
Any extra argument is invalid. The command reads the config at the working directory, assembles
|
|
17
|
+
both surfaces, and prints the result.
|
|
18
18
|
|
|
19
19
|
<a id="explain-what-it-shows"></a>
|
|
20
20
|
## What it shows
|
|
@@ -38,10 +38,9 @@ it would under a normal hook payload.
|
|
|
38
38
|
|
|
39
39
|
| Situation | Result |
|
|
40
40
|
|---|---|
|
|
41
|
-
| Config loads and
|
|
41
|
+
| Config loads and both surfaces assemble | exit `0` |
|
|
42
42
|
| Any extra argument | exit `2`, usage line on stderr |
|
|
43
43
|
| Missing, ambiguous, or invalid config | exit `2` |
|
|
44
|
-
| The covenant distribution cannot load | exit `2` |
|
|
45
44
|
| Any assembly failure | exit `2` |
|
|
46
45
|
|
|
47
46
|
The command leaves stdout at zero bytes on failure. It never prints a partial table.
|
|
@@ -54,23 +53,31 @@ pdks explain
|
|
|
54
53
|
```
|
|
55
54
|
|
|
56
55
|
The output starts with the config file path, then one block for the session surface and one for the
|
|
57
|
-
|
|
56
|
+
change-set surface. A starter config with no extra disciplines looks like this (`N` stands for
|
|
57
|
+
the number of protected paths the assembly counted; the one `skip` row is normal — it is where a
|
|
58
|
+
shell command whose write target cannot be determined lands):
|
|
58
59
|
|
|
59
60
|
```text
|
|
60
61
|
pdks explain — polydeukes.config.yaml
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
registrations 3 · declare 0 · skip
|
|
64
|
-
meta self-mod
|
|
65
|
-
meta
|
|
66
|
-
|
|
63
|
+
input: call IR (one call, stdin) · disciplines 0 · sessionDisciplines 0 · disciplines: advise unless enforce: block · meta: block
|
|
64
|
+
registrations 3 · declare 0 · skip 1 · meta 2 · draft 0
|
|
65
|
+
meta self-mod paths N (common; includes the config file itself)
|
|
66
|
+
meta transcript-mod content predicate · conditional: session.evidencePath
|
|
67
|
+
skip shell-unjudgeable a shell command whose write target this layer cannot determine
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
registrations 2 · declare 0 · skip
|
|
70
|
-
meta self-mod
|
|
71
|
-
|
|
69
|
+
input: --diff (change set, stdin) · disciplines 0 · changeSetDisciplines 0 · disciplines: advise unless enforce: block
|
|
70
|
+
registrations 2 · declare 0 · skip 1 · meta 1 · draft 0
|
|
71
|
+
meta self-mod paths N (common; includes the config file itself)
|
|
72
|
+
skip shell-unjudgeable a shell command whose write target this layer cannot determine
|
|
72
73
|
```
|
|
73
74
|
|
|
75
|
+
**The surface header names the lists that surface compiles and how many entries each holds.**
|
|
76
|
+
The session header prints `disciplines <n> · sessionDisciplines <n>` and the change-set header
|
|
77
|
+
prints `disciplines <n> · changeSetDisciplines <n>`, both counted from the config as written,
|
|
78
|
+
before assembly. Reading the two headers is how the placement of every entry is checked without
|
|
79
|
+
running a judgment: an entry that moved between lists moves one count in each header.
|
|
80
|
+
|
|
74
81
|
`N` is the assembled path count. A `declare` row uses the entry `id` as its label and a
|
|
75
82
|
catalogue coordinate as its description. A `skip` row names a skip reason. A `draft` row is
|
|
76
83
|
`unpromoted — no judgment`.
|
|
@@ -80,5 +87,5 @@ catalogue coordinate as its description. A `skip` row names a skip reason. A `dr
|
|
|
80
87
|
|
|
81
88
|
- [`pdks covenant check`](./covenant-check.md)
|
|
82
89
|
- [`pdks init`](./init.md)
|
|
83
|
-
- [
|
|
90
|
+
- [The judge (`covenant` module)](../packages/polydeukes.md#covenant-module)
|
|
84
91
|
- [`Configuration reference`](../configuration/index.md)
|