polydeukes 0.6.1 → 0.7.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.
Files changed (106) hide show
  1. package/README.ko.md +14 -28
  2. package/README.md +14 -28
  3. package/dist/baseline.d.ts +37 -1
  4. package/dist/baseline.js +68 -1
  5. package/dist/bin.d.ts +3 -4
  6. package/dist/bin.js +73 -90
  7. package/dist/covenant/bash-line.d.ts +130 -0
  8. package/dist/covenant/bash-line.js +566 -0
  9. package/dist/covenant/declaration-engine.d.ts +108 -0
  10. package/dist/covenant/declaration-engine.js +415 -0
  11. package/dist/covenant/discipline.d.ts +103 -0
  12. package/dist/covenant/discipline.js +667 -0
  13. package/dist/covenant/dispatch.d.ts +153 -0
  14. package/dist/covenant/dispatch.js +237 -0
  15. package/dist/covenant/extract-steps.d.ts +122 -0
  16. package/dist/covenant/extract-steps.js +0 -0
  17. package/dist/covenant/mention.d.ts +117 -0
  18. package/dist/covenant/mention.js +209 -0
  19. package/dist/covenant/module.d.ts +25 -0
  20. package/dist/covenant/module.js +23 -0
  21. package/dist/covenant/mutation-rules.d.ts +40 -0
  22. package/dist/covenant/mutation-rules.js +146 -0
  23. package/dist/covenant/relations.d.ts +46 -0
  24. package/dist/covenant/relations.js +68 -0
  25. package/dist/covenant/run-covenant.d.ts +95 -0
  26. package/dist/covenant/run-covenant.js +164 -0
  27. package/dist/covenant/self-mod.d.ts +55 -0
  28. package/dist/covenant/self-mod.js +84 -0
  29. package/dist/covenant/shell-evidence.d.ts +38 -0
  30. package/dist/covenant/shell-evidence.js +247 -0
  31. package/dist/covenant/shell-mod.d.ts +84 -0
  32. package/dist/covenant/shell-mod.js +213 -0
  33. package/dist/covenant/supply.d.ts +54 -0
  34. package/dist/covenant/supply.js +50 -0
  35. package/dist/covenant/transcript-mod.d.ts +60 -0
  36. package/dist/covenant/transcript-mod.js +254 -0
  37. package/dist/covenant/ttl-witness.d.ts +47 -0
  38. package/dist/covenant/ttl-witness.js +80 -0
  39. package/dist/covenant-check.d.ts +72 -39
  40. package/dist/covenant-check.js +260 -121
  41. package/dist/diff-ir.d.ts +28 -0
  42. package/dist/diff-ir.js +310 -0
  43. package/dist/docs/README.ko.md +8 -8
  44. package/dist/docs/README.md +8 -8
  45. package/dist/docs/catalog.json +44 -28
  46. package/dist/docs/concepts/judgment.ko.md +2 -2
  47. package/dist/docs/concepts/judgment.md +2 -2
  48. package/dist/docs/how-to/configure-project.ko.md +16 -16
  49. package/dist/docs/how-to/configure-project.md +15 -12
  50. package/dist/docs/how-to/connect-surfaces.ko.md +39 -34
  51. package/dist/docs/how-to/connect-surfaces.md +36 -33
  52. package/dist/docs/how-to/write-disciplines.ko.md +61 -6
  53. package/dist/docs/how-to/write-disciplines.md +62 -6
  54. package/dist/docs/index.json +607 -373
  55. package/dist/docs/reference/cli/covenant-check.ko.md +112 -65
  56. package/dist/docs/reference/cli/covenant-check.md +114 -59
  57. package/dist/docs/reference/cli/docs.ko.md +2 -2
  58. package/dist/docs/reference/cli/docs.md +2 -2
  59. package/dist/docs/reference/cli/explain.ko.md +14 -9
  60. package/dist/docs/reference/cli/explain.md +15 -10
  61. package/dist/docs/reference/cli/init.ko.md +52 -52
  62. package/dist/docs/reference/cli/init.md +43 -55
  63. package/dist/docs/reference/configuration/index.ko.md +171 -66
  64. package/dist/docs/reference/configuration/index.md +178 -71
  65. package/dist/docs/reference/packages/adapter-claude-code.ko.md +38 -11
  66. package/dist/docs/reference/packages/adapter-claude-code.md +38 -14
  67. package/dist/docs/reference/packages/adapter-grok.ko.md +77 -0
  68. package/dist/docs/reference/packages/adapter-grok.md +79 -0
  69. package/dist/docs/reference/packages/core.ko.md +49 -3
  70. package/dist/docs/reference/packages/core.md +54 -5
  71. package/dist/docs/reference/packages/polydeukes.ko.md +138 -77
  72. package/dist/docs/reference/packages/polydeukes.md +146 -81
  73. package/dist/docs/reference/packages/sdk-ts.ko.md +161 -0
  74. package/dist/docs/reference/packages/sdk-ts.md +164 -0
  75. package/dist/docs/troubleshooting.ko.md +17 -15
  76. package/dist/docs/troubleshooting.md +18 -14
  77. package/dist/docs/tutorials/first-judgment.ko.md +2 -2
  78. package/dist/docs/tutorials/first-judgment.md +2 -2
  79. package/dist/explain.d.ts +1 -1
  80. package/dist/explain.js +37 -22
  81. package/dist/load-config.d.ts +1 -1
  82. package/dist/load-config.js +1 -1
  83. package/dist/pre-state-reader.d.ts +1 -1
  84. package/dist/pre-state-reader.js +1 -1
  85. package/dist/scaffold-project.d.ts +2 -2
  86. package/dist/scaffold-project.js +9 -3
  87. package/dist/schema/polydeukes.schema.json +12 -0
  88. package/dist/worktree-reader.d.ts +19 -0
  89. package/dist/worktree-reader.js +30 -0
  90. package/package.json +3 -17
  91. package/dist/claude-code-hook.d.ts +0 -79
  92. package/dist/claude-code-hook.js +0 -372
  93. package/dist/claude-code.d.ts +0 -6
  94. package/dist/claude-code.js +0 -6
  95. package/dist/covenant-module.d.ts +0 -25
  96. package/dist/covenant-module.js +0 -42
  97. package/dist/docs/reference/packages/adapter-git.ko.md +0 -101
  98. package/dist/docs/reference/packages/adapter-git.md +0 -108
  99. package/dist/docs/reference/packages/covenant.ko.md +0 -115
  100. package/dist/docs/reference/packages/covenant.md +0 -123
  101. package/dist/index.d.ts +0 -22
  102. package/dist/index.js +0 -21
  103. package/dist/init-claude-code.d.ts +0 -52
  104. package/dist/init-claude-code.js +0 -586
  105. package/dist/init-grok.d.ts +0 -51
  106. package/dist/init-grok.js +0 -242
@@ -0,0 +1,310 @@
1
+ /**
2
+ * unified diff → `CovenantInput`. One pure translation, no judgment and no disk.
3
+ *
4
+ * The accepted grammar is finite: `diff --git` blocks and header-less `---`/`+++` blocks,
5
+ * covering creation, deletion, modification, mode-only changes, renames, and binary blobs.
6
+ * Anything else throws, so an unrecognised shape fails the run closed instead of translating
7
+ * to a partial observation.
8
+ *
9
+ * A modification's `pre`/`post` are the hunk's `-` and `+` lines, never the whole file: a
10
+ * unified diff carries the changed lines and the context around them, and reconstructing the
11
+ * file from them is not a translation. A creation and a deletion carry the whole text because
12
+ * every line of the file is in the hunk.
13
+ */
14
+ /** The tool name a staged write is dispatched under — telemetry and configs read it. */
15
+ export const STAGED_WRITE = 'staged-write';
16
+ /** The tool name a staged deletion is dispatched under. */
17
+ export const STAGED_DELETE = 'staged-delete';
18
+ function emptyBlock() {
19
+ return { binary: false, deletedFile: false, newFile: false, removed: [], added: [] };
20
+ }
21
+ /** A path as git prints it after `rename from` / `rename to`: quoted only when it has to be. */
22
+ function readBarePath(raw) {
23
+ return raw.startsWith('"') ? unquotePath(raw) : raw;
24
+ }
25
+ /**
26
+ * Decode git's C-quoted path form: the octal escapes are BYTES of the path, so they are
27
+ * collected and decoded as UTF-8 together — decoding each one on its own would turn every
28
+ * non-ASCII character into replacement characters.
29
+ */
30
+ function unquotePath(quoted) {
31
+ const body = quoted.slice(1, -1);
32
+ const bytes = [];
33
+ for (let at = 0; at < body.length; at += 1) {
34
+ const char = body[at];
35
+ if (char !== '\\') {
36
+ bytes.push(...Buffer.from(char, 'utf-8'));
37
+ continue;
38
+ }
39
+ const next = body[at + 1];
40
+ const octal = body.slice(at + 1, at + 4);
41
+ if (/^[0-7]{3}$/.test(octal)) {
42
+ bytes.push(Number.parseInt(octal, 8));
43
+ at += 3;
44
+ continue;
45
+ }
46
+ const simple = {
47
+ t: 0x09,
48
+ n: 0x0a,
49
+ r: 0x0d,
50
+ '"': 0x22,
51
+ '\\': 0x5c,
52
+ };
53
+ bytes.push(simple[next] ?? Buffer.from(next, 'utf-8')[0] ?? 0);
54
+ at += 1;
55
+ }
56
+ return Buffer.from(bytes).toString('utf-8');
57
+ }
58
+ /**
59
+ * The path a `---`/`+++` line names, or null for `/dev/null`. A quoted path is unquoted
60
+ * before anything is cut, because a quoted path may itself contain a tab; an unquoted one is
61
+ * cut at the tab `diff -u` puts its timestamp behind. Exactly one `a/` or `b/` level is
62
+ * stripped, so a repository directory literally named `a/` survives.
63
+ */
64
+ function readPath(rest, prefix) {
65
+ let path;
66
+ if (rest.startsWith('"')) {
67
+ const end = rest.lastIndexOf('"');
68
+ path = unquotePath(rest.slice(0, end + 1));
69
+ }
70
+ else {
71
+ const tab = rest.indexOf('\t');
72
+ path = tab === -1 ? rest : rest.slice(0, tab);
73
+ }
74
+ if (path === '/dev/null')
75
+ return null;
76
+ return path.startsWith(prefix) ? path.slice(prefix.length) : path;
77
+ }
78
+ /** The two paths of a `diff --git a/X b/Y` header, or undefined when they cannot be read. */
79
+ function readHeaderPaths(rest) {
80
+ if (rest.startsWith('"')) {
81
+ const end = rest.indexOf('" "');
82
+ if (end === -1)
83
+ return undefined;
84
+ const old = unquotePath(rest.slice(0, end + 1));
85
+ const next = unquotePath(rest.slice(end + 2));
86
+ return { old: stripOnce(old, 'a/'), new: stripOnce(next, 'b/') };
87
+ }
88
+ // Unquoted paths may contain spaces, and git writes no separator between the two. The
89
+ // halves are equal in length whenever the prefixes are, which is git's own output; the
90
+ // midpoint split is what recovers them.
91
+ const middle = rest.length % 2 === 1 ? (rest.length - 1) / 2 : -1;
92
+ if (middle > 0 && rest[middle] === ' ') {
93
+ return {
94
+ old: stripOnce(rest.slice(0, middle), 'a/'),
95
+ new: stripOnce(rest.slice(middle + 1), 'b/'),
96
+ };
97
+ }
98
+ const at = rest.indexOf(' ');
99
+ if (at === -1)
100
+ return undefined;
101
+ return { old: stripOnce(rest.slice(0, at), 'a/'), new: stripOnce(rest.slice(at + 1), 'b/') };
102
+ }
103
+ function stripOnce(path, prefix) {
104
+ return path.startsWith(prefix) ? path.slice(prefix.length) : path;
105
+ }
106
+ /** The old and new line counts a hunk header declares, or undefined when it is not one. */
107
+ function readHunkCounts(line) {
108
+ const match = /^@@ -\d+(?:,(\d+))? \+\d+(?:,(\d+))? @@/.exec(line);
109
+ if (match === null)
110
+ return undefined;
111
+ return {
112
+ old: match[1] === undefined ? 1 : Number.parseInt(match[1], 10),
113
+ new: match[2] === undefined ? 1 : Number.parseInt(match[2], 10),
114
+ };
115
+ }
116
+ /**
117
+ * Split the text into file blocks, reading hunk bodies by the line counts their headers
118
+ * declare. The counts are what keeps a removed `-- note` line (which reads as `--- note`)
119
+ * from being taken for a new file header: header lines are only recognised outside a hunk.
120
+ */
121
+ function parseBlocks(text) {
122
+ const lines = text.split('\n');
123
+ const blocks = [];
124
+ let block;
125
+ const open = () => {
126
+ if (block === undefined) {
127
+ block = emptyBlock();
128
+ blocks.push(block);
129
+ }
130
+ return block;
131
+ };
132
+ for (let at = 0; at < lines.length; at += 1) {
133
+ const line = lines[at];
134
+ if (line === '' && at === lines.length - 1)
135
+ continue;
136
+ if (line.startsWith('diff --cc ') || line.startsWith('diff --combined ')) {
137
+ throw new Error(`unified diff: combined diffs are not translatable: ${line}`);
138
+ }
139
+ if (line.startsWith('diff --git ')) {
140
+ block = emptyBlock();
141
+ blocks.push(block);
142
+ block.headerPaths = readHeaderPaths(line.slice('diff --git '.length));
143
+ continue;
144
+ }
145
+ if (line.startsWith('--- ')) {
146
+ // A second `---` outside a hunk starts a new header-less block.
147
+ if (block !== undefined && block.oldPath !== undefined)
148
+ block = undefined;
149
+ open().oldPath = readPath(line.slice(4), 'a/');
150
+ continue;
151
+ }
152
+ if (line.startsWith('+++ ')) {
153
+ const current = open();
154
+ if (current.oldPath === undefined) {
155
+ throw new Error(`unified diff: '+++' line with no '---' partner: ${line}`);
156
+ }
157
+ current.newPath = readPath(line.slice(4), 'b/');
158
+ continue;
159
+ }
160
+ const counts = readHunkCounts(line);
161
+ if (counts !== undefined) {
162
+ const current = open();
163
+ if (current.oldPath === undefined || current.newPath === undefined) {
164
+ if (current.headerPaths === undefined) {
165
+ throw new Error(`unified diff: hunk with no file header: ${line}`);
166
+ }
167
+ }
168
+ let oldLeft = counts.old;
169
+ let newLeft = counts.new;
170
+ while ((oldLeft > 0 || newLeft > 0) && at + 1 < lines.length) {
171
+ const body = lines[at + 1];
172
+ at += 1;
173
+ if (body.startsWith('\\'))
174
+ continue;
175
+ // A line the declared counts have no room for is a malformed hunk: judging the
176
+ // lines that fit and dropping the rest would be an observation smaller than the
177
+ // input, so the whole run fails closed instead.
178
+ if (body.startsWith('+') && newLeft > 0) {
179
+ current.added.push(body.slice(1));
180
+ newLeft -= 1;
181
+ continue;
182
+ }
183
+ if (body.startsWith('-') && oldLeft > 0) {
184
+ current.removed.push(body.slice(1));
185
+ oldLeft -= 1;
186
+ continue;
187
+ }
188
+ if ((body.startsWith(' ') || body === '') && oldLeft > 0 && newLeft > 0) {
189
+ oldLeft -= 1;
190
+ newLeft -= 1;
191
+ continue;
192
+ }
193
+ throw new Error(`unified diff: unknown hunk line: ${body}`);
194
+ }
195
+ continue;
196
+ }
197
+ if (line.startsWith('rename from ')) {
198
+ open().renameFrom = readBarePath(line.slice('rename from '.length));
199
+ continue;
200
+ }
201
+ if (line.startsWith('rename to ')) {
202
+ open().renameTo = readBarePath(line.slice('rename to '.length));
203
+ continue;
204
+ }
205
+ if (line.startsWith('deleted file mode ')) {
206
+ open().deletedFile = true;
207
+ continue;
208
+ }
209
+ if (line.startsWith('new file mode ')) {
210
+ open().newFile = true;
211
+ continue;
212
+ }
213
+ if (line.startsWith('Binary files ') || line === 'GIT binary patch') {
214
+ const current = open();
215
+ current.binary = true;
216
+ if (line.endsWith('and /dev/null differ'))
217
+ current.deletedFile = true;
218
+ }
219
+ // Everything else outside a hunk is an extended header line (`index`, `old mode`,
220
+ // `similarity index`, a binary patch's base85 payload) that names nothing this
221
+ // translation reads.
222
+ }
223
+ return blocks;
224
+ }
225
+ /** The toolCalls one block translates to, in the order the judgment sees them. */
226
+ function blockToolCalls(block) {
227
+ const { renameFrom, renameTo } = block;
228
+ if (renameFrom !== undefined && renameTo !== undefined) {
229
+ return [
230
+ {
231
+ name: STAGED_DELETE,
232
+ args: { file_path: renameFrom },
233
+ fileChange: { kind: 'delete', path: renameFrom },
234
+ },
235
+ {
236
+ name: STAGED_WRITE,
237
+ args: { file_path: renameTo },
238
+ fileChange: {
239
+ kind: 'modify',
240
+ path: renameTo,
241
+ pre: block.removed.join('\n'),
242
+ post: block.added.join('\n'),
243
+ },
244
+ },
245
+ ];
246
+ }
247
+ // An empty file's deletion or creation carries no `---`/`+++` pair and no hunk, so the
248
+ // mode line is the only evidence of which one it is.
249
+ const deletion = block.newPath === null || block.deletedFile;
250
+ const path = deletion
251
+ ? (block.oldPath ?? block.headerPaths?.old)
252
+ : (block.newPath ?? block.headerPaths?.new);
253
+ if (path === undefined || path === null) {
254
+ throw new Error('unified diff: a file block names no path');
255
+ }
256
+ if (block.binary) {
257
+ return [{ name: deletion ? STAGED_DELETE : STAGED_WRITE, args: { file_path: path } }];
258
+ }
259
+ if (deletion) {
260
+ return [
261
+ {
262
+ name: STAGED_DELETE,
263
+ args: { file_path: path },
264
+ fileChange: { kind: 'delete', path, pre: block.removed.join('\n') },
265
+ },
266
+ ];
267
+ }
268
+ if (block.oldPath === null || block.newFile) {
269
+ return [
270
+ {
271
+ name: STAGED_WRITE,
272
+ args: { file_path: path },
273
+ fileChange: { kind: 'create', path, post: block.added.join('\n') },
274
+ },
275
+ ];
276
+ }
277
+ return [
278
+ {
279
+ name: STAGED_WRITE,
280
+ args: { file_path: path },
281
+ fileChange: {
282
+ kind: 'modify',
283
+ path,
284
+ pre: block.removed.join('\n'),
285
+ post: block.added.join('\n'),
286
+ },
287
+ },
288
+ ];
289
+ }
290
+ /**
291
+ * Translate a unified diff into the covenant input IR: one toolCall per file block in input
292
+ * order (a rename is two, the deletion first), and no `actor` key — a diff proves no author.
293
+ */
294
+ export function covenantInputFromUnifiedDiff(spec) {
295
+ const blocks = parseBlocks(spec.text);
296
+ // Text that is not blank yet contains no block the grammar recognizes — a colored diff,
297
+ // a pager banner, anything else — must not translate to "nothing staged": an empty
298
+ // observation is a pass, and this input may describe a whole commit.
299
+ if (blocks.length === 0 && spec.text.trim() !== '') {
300
+ throw new Error('unified diff: no file block recognized in the input');
301
+ }
302
+ const toolCalls = [];
303
+ for (const block of blocks) {
304
+ if (block.oldPath !== undefined && block.newPath === undefined) {
305
+ throw new Error(`unified diff: '---' line with no '+++' partner: ${block.oldPath}`);
306
+ }
307
+ toolCalls.push(...blockToolCalls(block));
308
+ }
309
+ return { toolCalls, subagentSpawns: [], userMessages: [] };
310
+ }
@@ -25,11 +25,10 @@
25
25
  | 문서 | 답하는 것 |
26
26
  |---|---|
27
27
  | [설정 레퍼런스](./reference/configuration/index.ko.md) | `polydeukes.config.yaml`에 무엇을 넣을 수 있고 각 키가 무엇을 하는지 |
28
- | [`polydeukes` (`pdks` CLI)](./reference/packages/polydeukes.ko.md) | 패키지 계약. 서브커맨드는 [`reference/cli/`](./reference/cli/covenant-check.ko.md) |
28
+ | [`polydeukes` (`pdks` CLI)](./reference/packages/polydeukes.ko.md) | 패키지 계약과 그 안에 있는 판정기. 서브커맨드는 [`reference/cli/`](./reference/cli/covenant-check.ko.md) |
29
29
  | [`@polydeukes/core`](./reference/packages/core.ko.md) | 프로토콜, 입력 IR, 설정 스키마, 텔레메트리 |
30
- | [`@polydeukes/covenant`](./reference/packages/covenant.ko.md) | 판정기입니다. 디스패처와 규율 라이브러리, 메타 약속, 밸브 |
31
- | [`@polydeukes/adapter-claude-code`](./reference/packages/adapter-claude-code.ko.md) | 세션 표면입니다. 훅 페이로드에서 입력 IR로 |
32
- | [`@polydeukes/adapter-git`](./reference/packages/adapter-git.ko.md) | 커밋 표면입니다. 스테이징·작업 트리·범위 diff에서 입력 IR로 |
30
+ | [`@polydeukes/adapter-claude-code`](./reference/packages/adapter-claude-code.ko.md) | Claude Code 세션 표면입니다. 페이로드에서 입력 IR로 |
31
+ | [`@polydeukes/adapter-grok`](./reference/packages/adapter-grok.ko.md) | Grok 세션 표면입니다. 훅 페이로드에서 입력 IR로 |
33
32
 
34
33
  <a id="shape-of-the-thing"></a>
35
34
  ## 한 페이지로 보는 구조
@@ -53,8 +52,9 @@
53
52
 
54
53
  | 표면 | 판정 대상 | 배선 방법 | 대상 |
55
54
  |---|---|---|---|
56
- | **세션** | 도구 호출, 실행되기 전에 | `pdks init claude-code` 또는 `pdks init grok` | AI 파트너와 함께 개발하는 프로젝트 |
57
- | **커밋** | diff — 스테이징 영역, 작업 트리, ref 범위 | pre-commit 훅, 또는 필요할 때 직접 실행 | 혼자 개발하는 사람, 그리고 CI |
55
+ | **세션** | 도구 호출, 실행되기 전에 | `pdks-claude-code init` 또는 `pdks-grok init` | AI 파트너와 함께 개발하는 프로젝트 |
56
+ | **커밋** | stdin의 unified diff — 스테이징 영역, 작업 트리, ref 범위 | `git diff --cached`를 파이프로 넘기는 pre-commit 훅, 또는 필요할 때 직접 실행 | 혼자 개발하는 사람, 그리고 CI |
58
57
 
59
- 커밋 판정기는 필요할 때 직접 실행할 수도 있습니다. 작업 후에는 `pdks covenant check --worktree`,
60
- PR 전에는 `--range`를 사용합니다. 같은 판정 기준으로 결과를 보고하며 증인 입력은 요청하지 않습니다.
58
+ 커밋 판정기는 필요할 때 직접 실행할 수도 있습니다. 작업 후에는 `git diff HEAD | pdks covenant check --diff`,
59
+ PR 전에는 `git diff main...HEAD | …`를 사용합니다. 같은 판정 기준을 종료 코드로 답하며 묻지
60
+ 않습니다. 관문은 그 코드를 소비하는 쪽입니다.
@@ -27,11 +27,10 @@ is aspirational.
27
27
  | Document | Answers |
28
28
  |---|---|
29
29
  | [Configuration reference](./reference/configuration/index.md) | What may go in `polydeukes.config.yaml`, and what each key does |
30
- | [`polydeukes` (the `pdks` CLI)](./reference/packages/polydeukes.md) | Package contract; subcommands live under [`reference/cli/`](./reference/cli/covenant-check.md) |
30
+ | [`polydeukes` (the `pdks` CLI)](./reference/packages/polydeukes.md) | Package contract, and the judge that lives inside it; subcommands live under [`reference/cli/`](./reference/cli/covenant-check.md) |
31
31
  | [`@polydeukes/core`](./reference/packages/core.md) | The protocol, the input IR, the config schema, telemetry |
32
- | [`@polydeukes/covenant`](./reference/packages/covenant.md) | The judgedispatcher, discipline library, meta-covenants, the valve |
33
- | [`@polydeukes/adapter-claude-code`](./reference/packages/adapter-claude-code.md) | Session surface — hook payloads become the input IR |
34
- | [`@polydeukes/adapter-git`](./reference/packages/adapter-git.md) | Commit surface — staged, worktree, and range diffs become the input IR |
32
+ | [`@polydeukes/adapter-claude-code`](./reference/packages/adapter-claude-code.md) | Claude Code session surface hook payloads become the input IR |
33
+ | [`@polydeukes/adapter-grok`](./reference/packages/adapter-grok.md) | Grok session surface — hook payloads become the input IR |
35
34
 
36
35
  <a id="shape-of-the-thing"></a>
37
36
  ## The shape of the thing, in one page
@@ -57,8 +56,9 @@ in the whitepaper, which were all found by counting rows rather than by reading
57
56
 
58
57
  | Surface | Judges | Wired by | For |
59
58
  |---|---|---|---|
60
- | **Session** | A tool call, before it runs | `pdks init claude-code` or `pdks init grok` | A project developed with an AI partner |
61
- | **Commit** | A diff — staged, the working tree, or a ref range | A pre-commit hook, or run on demand | A human developing alone, and CI |
59
+ | **Session** | A tool call, before it runs | `pdks-claude-code init` or `pdks-grok init` | A project developed with an AI partner |
60
+ | **Commit** | A unified diff on stdin — staged, the working tree, or a ref range | A pre-commit hook piping `git diff --cached`, or run on demand | A human developing alone, and CI |
62
61
 
63
- The commit judge also answers on demand: `pdks covenant check --worktree` after a task, `--range`
64
- before a PR. Same verdict a commit would receive, delivered as a report with no prompt and no gate.
62
+ The commit judge also answers on demand: `git diff HEAD | pdks covenant check --diff` after a task,
63
+ `git diff main...HEAD | …` before a PR. Same verdict a commit would receive, delivered as an exit
64
+ code with no prompt — the gate is whatever consumes that code.
@@ -130,12 +130,12 @@
130
130
  "en": {
131
131
  "path": "reference/cli/covenant-check.md",
132
132
  "title": "`pdks covenant check`",
133
- "summary": "Inspect staged changes, --worktree, or a revision range."
133
+ "summary": "Judge a unified diff or an input IR from stdin, and read the exit codes."
134
134
  },
135
135
  "ko": {
136
136
  "path": "reference/cli/covenant-check.ko.md",
137
137
  "title": "`pdks covenant check`",
138
- "summary": "스테이징한 변경, 작업 트리 검사, 리비전 범위 검사를 설명합니다."
138
+ "summary": "stdin의 unified diff나 입력 IR을 판정하고 종료 코드를 읽는 방법을 설명합니다."
139
139
  }
140
140
  },
141
141
  {
@@ -146,12 +146,12 @@
146
146
  "en": {
147
147
  "path": "reference/cli/init.md",
148
148
  "title": "`pdks init`",
149
- "summary": "Install the Claude Code or Grok integration."
149
+ "summary": "Create the project scaffold, and find the Claude Code and Grok installers."
150
150
  },
151
151
  "ko": {
152
152
  "path": "reference/cli/init.ko.md",
153
153
  "title": "`pdks init`",
154
- "summary": "Claude Code 또는 Grok 연동을 설치합니다."
154
+ "summary": "프로젝트 초기 파일을 만들고, Claude Code Grok 설치기를 찾습니다."
155
155
  }
156
156
  },
157
157
  {
@@ -235,51 +235,51 @@
235
235
  }
236
236
  },
237
237
  {
238
- "id": "package-covenant",
238
+ "id": "package-adapter-claude-code",
239
239
  "category": "reference",
240
- "order": 14,
240
+ "order": 15,
241
241
  "bundled": true,
242
242
  "en": {
243
- "path": "reference/packages/covenant.md",
244
- "title": "`@polydeukes/covenant`",
245
- "summary": "Consult the covenant package contract and its limits."
243
+ "path": "reference/packages/adapter-claude-code.md",
244
+ "title": "`@polydeukes/adapter-claude-code`",
245
+ "summary": "Install the Claude Code session surface, and consult the adapter package contract and its limits."
246
246
  },
247
247
  "ko": {
248
- "path": "reference/packages/covenant.ko.md",
249
- "title": "`@polydeukes/covenant`",
250
- "summary": "covenant 패키지의 계약과 한계를 확인합니다."
248
+ "path": "reference/packages/adapter-claude-code.ko.md",
249
+ "title": "`@polydeukes/adapter-claude-code`",
250
+ "summary": "Claude Code 세션 표면을 설치하고, 어댑터 패키지의 계약과 한계를 확인합니다."
251
251
  }
252
252
  },
253
253
  {
254
- "id": "package-adapter-claude-code",
254
+ "id": "package-adapter-grok",
255
255
  "category": "reference",
256
- "order": 15,
256
+ "order": 16,
257
257
  "bundled": true,
258
258
  "en": {
259
- "path": "reference/packages/adapter-claude-code.md",
260
- "title": "`@polydeukes/adapter-claude-code`",
261
- "summary": "Consult the adapter-claude-code package contract and its limits."
259
+ "path": "reference/packages/adapter-grok.md",
260
+ "title": "`@polydeukes/adapter-grok`",
261
+ "summary": "Install the Grok session surface, and consult the adapter package contract and its limits."
262
262
  },
263
263
  "ko": {
264
- "path": "reference/packages/adapter-claude-code.ko.md",
265
- "title": "`@polydeukes/adapter-claude-code`",
266
- "summary": "adapter-claude-code 패키지의 계약과 한계를 확인합니다."
264
+ "path": "reference/packages/adapter-grok.ko.md",
265
+ "title": "`@polydeukes/adapter-grok`",
266
+ "summary": "Grok 세션 표면을 설치하고, 어댑터 패키지의 계약과 한계를 확인합니다."
267
267
  }
268
268
  },
269
269
  {
270
- "id": "package-adapter-git",
270
+ "id": "package-sdk-ts",
271
271
  "category": "reference",
272
- "order": 16,
272
+ "order": 25,
273
273
  "bundled": true,
274
274
  "en": {
275
- "path": "reference/packages/adapter-git.md",
276
- "title": "`@polydeukes/adapter-git`",
277
- "summary": "Consult the adapter-git package contract and its limits."
275
+ "path": "reference/packages/sdk-ts.md",
276
+ "title": "`@polydeukes/sdk-ts`",
277
+ "summary": "Call the judge from TypeScript with one verb, and read the three verdicts it returns."
278
278
  },
279
279
  "ko": {
280
- "path": "reference/packages/adapter-git.ko.md",
281
- "title": "`@polydeukes/adapter-git`",
282
- "summary": "adapter-git 패키지의 계약과 한계를 확인합니다."
280
+ "path": "reference/packages/sdk-ts.ko.md",
281
+ "title": "`@polydeukes/sdk-ts`",
282
+ "summary": "TypeScript에서 동사 하나로 판정기를 부르고, 돌아오는 판정 결과 셋을 읽습니다."
283
283
  }
284
284
  },
285
285
  {
@@ -409,6 +409,22 @@
409
409
  "title": "<!--",
410
410
  "summary": "당시의 개발 기록이며 현재 사용법을 설명하는 참조 문서는 아닙니다."
411
411
  }
412
+ },
413
+ {
414
+ "id": "post-7",
415
+ "category": "history",
416
+ "order": 24,
417
+ "bundled": false,
418
+ "en": {
419
+ "path": "build-in-public/2026-09-v0.6.1-docs-and-search.md",
420
+ "title": "<!--",
421
+ "summary": "Historical development account; not a current usage reference."
422
+ },
423
+ "ko": {
424
+ "path": "build-in-public/2026-09-v0.6.1-docs-and-search.ko.md",
425
+ "title": "<!--",
426
+ "summary": "당시의 개발 기록이며 현재 사용법을 설명하는 참조 문서는 아닙니다."
427
+ }
412
428
  }
413
429
  ],
414
430
  "topics": {
@@ -16,7 +16,7 @@ Polydeukes는 연결된 표면이 공급하는 증거를 바탕으로 선언된
16
16
  **표면(surface)**은 언제 증거를 수집하는지 결정합니다.
17
17
 
18
18
  - 세션 표면은 지원하는 호스트의 도구 호출을 실행 전에 관측합니다.
19
- - 커밋 표면은 스테이징한 변경, 작업 트리의 변경 또는 두 리비전 사이의 변경을 관측합니다.
19
+ - 변경 집합 표면은 스테이징한 변경, 작업 트리의 변경 또는 두 리비전 사이의 변경을 관측합니다.
20
20
 
21
21
  패키지를 설치하는 것과 표면을 연결하는 것은 다릅니다. 에이전트가 지침을 읽었다고 해서
22
22
  도구 호출에 자동으로 판정이 적용되지는 않습니다. 지원하는 연동을 설정하고 실제 호출로
@@ -103,7 +103,7 @@ Polydeukes는 연결된 표면이 공급하는 증거를 바탕으로 선언된
103
103
  ## 강제 수준과 증인
104
104
 
105
105
  규율 항목의 기본 강제 수준은 `advise`입니다. 위반과 정상 사례를 모두 확인한 뒤
106
- `enforce: block`으로 승격하세요. 커밋 표면의 수준과 항목의 수준을 함께 적용할 때는
106
+ `enforce: block`으로 승격하세요. 변경 집합 표면의 수준과 항목의 수준을 함께 적용할 때는
107
107
  **더 관대한 쪽을 따릅니다**. 표면만 `block`으로 설정해도 모든 항목이 차단 수준으로
108
108
  바뀌지는 않습니다. 판정 체계 자체의 보호는 일반 규율 항목과 별개입니다.
109
109
 
@@ -15,7 +15,7 @@ in the project's configuration. The **judge** evaluates evidence; a **verdict**
15
15
  A **surface** determines when evidence is gathered:
16
16
 
17
17
  - The session surface observes a supported host's tool call before it runs.
18
- - The commit surface observes staged changes, working-tree changes, or a revision range.
18
+ - The change-set surface observes staged changes, working-tree changes, or a revision range.
19
19
 
20
20
  Installing the package is not the same as connecting a surface. Instructions an agent reads are
21
21
  not automatic interception of its tools. Use a supported integration and verify an actual call.
@@ -102,7 +102,7 @@ that the practice was followed. An empty observation set establishes nothing abo
102
102
  ## Enforcement and witness
103
103
 
104
104
  Discipline entries default to `advise`. Promote an entry with `enforce: block` only after checking
105
- both its violating and valid cases. The commit surface's level and an entry's level compose:
105
+ both its violating and valid cases. The change-set surface's level and an entry's level compose:
106
106
  **the lenient side wins**. Setting only the surface to `block` does not promote every entry.
107
107
  Protection of the judging chain is separate from ordinary discipline entries.
108
108
 
@@ -36,8 +36,8 @@ YAML 파일에는 다음 줄을 넣어 설치된 스키마를 편집기에서
36
36
  # yaml-language-server: $schema=../../node_modules/polydeukes/dist/schema/polydeukes.schema.json
37
37
  ```
38
38
 
39
- `pdks init claude-code`는 생성한 설정 파일을 기준으로 기본 경로의 스키마를 찾을 수 있을 때만
40
- 스키마 줄을 넣습니다. 이 줄이 없다면 스키마 위치에 맞춰 상대 경로를 직접 추가하세요.
39
+ `pdks init`은 생성한 설정 파일을 기준으로 기본 경로의 스키마를 찾을 수 있을 때만 스키마 줄을
40
+ 넣습니다. `pdks-claude-code init`이명령을 대신 실행합니다. 이 줄이 없다면 스키마 위치에 맞춰 상대 경로를 직접 추가하세요.
41
41
  `$schema` 경로를 찾지 못하면 편집기에 오류가 표시되지 않은 채 스키마 검증이 중단될 수 있습니다.
42
42
 
43
43
  우산이 아니라 `@polydeukes/core`를 직접 설치했다면 그 사본을 가리킵니다.
@@ -72,27 +72,27 @@ languages:
72
72
 
73
73
  | 설정 | 위반 시 동작 |
74
74
  |---|---|
75
- | `adapters.git.enforce: advise` | 권고를 기록하고 커밋을 계속합니다. 증인 입력은 요청하지 않습니다. |
76
- | `adapters.git.enforce: block` | 차단 판정을 받은 작업을 거부합니다. 스테이징 검사에서는 TTY로 증인 입력을 받을 수 있습니다. |
75
+ | 항목의 `enforce: advise`(또는 적지 않음) | 권고를 기록하고 호출을 진행합니다. 종료 코드 0입니다. |
76
+ | 항목의 `enforce: block` | 판정한 호출을 거부합니다. 종료 코드 2입니다. |
77
77
 
78
- 일반 규율(discipline) 항목에도 자체 강제 수준이 있으며 기본값은 `advise`입니다.
79
- **두 수준 관대한 쪽을 따릅니다.** 어댑터만 `block`으로 설정해도 일반 항목이 자동으로
80
- 차단 수준으로 바뀌지는 않습니다. 설정된 경로의 보호는 항목별 기본값과 별개입니다.
81
- 조립 단계에서 오류가 나면 어느 수준에서든 종료 코드 2를 반환합니다.
78
+ **적지 않으면 `advise`입니다.** 설정에는 표면 단위의 강제 수준 키가 없습니다. 강제 수준은
79
+ 항목이 가지며 적지 않은 항목을 승격하는 설정도 없습니다. 설정된 경로의 보호는 이 항목별
80
+ 기본값과 별개입니다. 세션 표면에서는 차단하고, 변경 집합 표면에서는 명령을 `--enforce block`으로
81
+ 실행하지 않는 한 `advised`로 기록합니다. 조립 단계에서 오류가 나면 종료 코드 2를
82
+ 반환합니다.
82
83
 
83
- 최상위 `protectedPaths`는 두 표면에 모두 적용합니다. `adapters.git.protectedPaths`에는
84
- 커밋할 때만 보호할 경로를 추가합니다. 세션 중에는 편집을 허용하되 커밋할 때 보호하려는
85
- 파일에 사용하세요. [표면 연결과 증인](./connect-surfaces.ko.md#witness-and-recovery)에서
86
- 자세히 설명합니다.
84
+ `protectedPaths`는 두 표면에 모두 적용하는 최상위 목록 하나입니다. 변경 집합 표면에서 판정기는
85
+ 종료 코드만 내므로, 커밋을 멈출지는 배선이 정합니다.
86
+ [표면 연결과 증인](./connect-surfaces.ko.md#witness-and-recovery)에서 자세히 설명합니다.
87
87
 
88
88
  <a id="confirm-the-project"></a>
89
89
  ## 설정 확인하기
90
90
 
91
91
  - `pdks explain`은 설정을 읽고 등록된 항목을 보여 줍니다. 변경을 판정하지는 않습니다.
92
- - `pdks covenant check --worktree`는 HEAD와 디스크를 비교합니다. 아직 Git에 등록하지 않은
93
- 파일도 무시 대상이 아니면 포함합니다.
94
- - `pdks covenant check`는 스테이징한 변경을 관측합니다. 차단 결과가 나고 TTY를 사용할
95
- 있을 증인 입력을 요청할 수 있습니다. 어댑터가 `block`이라는 이유만으로 묻지는 않습니다.
92
+ - `git diff HEAD | pdks covenant check --diff`는 아직 커밋하지 않은 변경 전부를 판정합니다.
93
+ - `git diff --cached | pdks covenant check --diff`는 스테이징한 변경을 관측합니다. pre-commit
94
+ 훅이 쓰는 형태입니다. 명령은 사람에게 묻지 않고 종료 코드 0 또는 2만 내며, 커밋을
95
+ 멈출지는 배선이 정합니다.
96
96
 
97
97
  종료 코드와 함께 stderr와 텔레메트리도 확인하세요. 권고나 일부 미판정도 종료 코드 0을
98
98
  반환합니다. 조립에 실패했다면 규율을 시험하기 전에 오류가 지목한 설정이나 빠진 패키지부터
@@ -36,8 +36,9 @@ monorepo sub-package whose dependencies installed at the workspace root, count t
36
36
  # yaml-language-server: $schema=../../node_modules/polydeukes/dist/schema/polydeukes.schema.json
37
37
  ```
38
38
 
39
- `pdks init claude-code` adds the schema line only when the default path resolves relative to the
40
- generated config. If the line is absent, add a relative path to the installed schema yourself.
39
+ `pdks init` — which `pdks-claude-code init` runs for you — adds the schema line only when the
40
+ default path resolves relative to the generated config. If the line is absent, add a relative path
41
+ to the installed schema yourself.
41
42
  An unresolvable `$schema` can disable editor validation without displaying an error.
42
43
 
43
44
  If you installed `@polydeukes/core` directly rather than the umbrella, name its copy:
@@ -72,24 +73,26 @@ Loading this setting does not itself run the command.
72
73
 
73
74
  | Setting | Effect on a violation |
74
75
  |---|---|
75
- | `adapters.git.enforce: advise` | Record advice and let the commit continue, without a witness prompt. |
76
- | `adapters.git.enforce: block` | Refuse a blocking judgment; the staged path can offer a TTY witness prompt. |
76
+ | `enforce: advise` on an entry (or absent) | Record advice and let the call proceed, exit 0. |
77
+ | `enforce: block` on an entry | Refuse the judged call, exit 2. |
77
78
 
78
- An ordinary discipline also has its own level, defaulting to `advise`. **The lenient level wins.**
79
- Setting only the adapter to `block` does not promote an ordinary entry. Protection of configured
80
- paths is separate from that per-entry default. Assembly errors still exit 2 at either level.
79
+ **Absent means `advise`.** There is no surface-level enforcement key in the config: each entry
80
+ carries its own level and nothing promotes an absent one. Protection of configured paths is
81
+ separate from that per-entry default it blocks on the session surface, and on the change-set
82
+ surface it lands `advised` unless the command is run with `--enforce block`. Assembly errors
83
+ still exit 2.
81
84
 
82
- Top-level `protectedPaths` applies to both surfaces. `adapters.git.protectedPaths` adds commit-only
83
- paths. Use the latter for files that may be edited in a session but need protection when committed.
85
+ `protectedPaths` is a single top-level list that applies to both surfaces. On the change-set
86
+ surface the judge only emits the exit code; whether the commit stops is your hook wiring.
84
87
  See [surface connection and witnesses](./connect-surfaces.md#witness-and-recovery).
85
88
 
86
89
  <a id="confirm-the-project"></a>
87
90
  ## Confirm the project
88
91
 
89
92
  - `pdks explain` loads the configuration and shows registrations without judging a change.
90
- - `pdks covenant check --worktree` compares HEAD with disk, including untracked, non-ignored files.
91
- - `pdks covenant check` observes staged changes. A blocking result can prompt only when a TTY is
92
- available; the command does not prompt merely because the adapter is set to `block`.
93
+ - `git diff HEAD | pdks covenant check --diff` judges everything not yet committed.
94
+ - `git diff --cached | pdks covenant check --diff` observes staged changes the pre-commit shape.
95
+ The command never prompts; it exits 0 or 2 and your hook wiring decides the commit's fate.
93
96
 
94
97
  Check stderr and telemetry as well as the exit code. Advice and some skipped observations exit 0.
95
98
  If assembly fails, diagnose the named configuration or missing package before testing a discipline.