polydeukes 0.8.0 → 0.10.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.
Files changed (32) hide show
  1. package/dist/covenant/shell-mod.d.ts +15 -4
  2. package/dist/covenant/shell-mod.js +63 -8
  3. package/dist/covenant/transcript-mod.js +8 -5
  4. package/dist/docs/README.ko.md +43 -18
  5. package/dist/docs/README.md +39 -17
  6. package/dist/docs/catalog.json +50 -162
  7. package/dist/docs/concepts/judgment.ko.md +2 -0
  8. package/dist/docs/concepts/judgment.md +2 -0
  9. package/dist/docs/how-to/connect-surfaces.ko.md +19 -7
  10. package/dist/docs/how-to/connect-surfaces.md +24 -12
  11. package/dist/docs/how-to/write-disciplines.ko.md +68 -31
  12. package/dist/docs/how-to/write-disciplines.md +69 -32
  13. package/dist/docs/index.json +577 -231
  14. package/dist/docs/reference/cli/init.ko.md +10 -7
  15. package/dist/docs/reference/cli/init.md +16 -11
  16. package/dist/docs/reference/configuration/index.ko.md +14 -20
  17. package/dist/docs/reference/configuration/index.md +16 -24
  18. package/dist/docs/reference/declaration-language/index.ko.md +280 -0
  19. package/dist/docs/reference/declaration-language/index.md +277 -0
  20. package/dist/docs/reference/packages/adapter-claude-code.ko.md +1 -1
  21. package/dist/docs/reference/packages/adapter-claude-code.md +1 -1
  22. package/dist/docs/reference/packages/adapter-codex.ko.md +34 -17
  23. package/dist/docs/reference/packages/adapter-codex.md +39 -21
  24. package/dist/docs/reference/packages/core.ko.md +2 -2
  25. package/dist/docs/reference/packages/core.md +2 -2
  26. package/dist/docs/reference/packages/polydeukes.ko.md +2 -2
  27. package/dist/docs/reference/packages/polydeukes.md +3 -3
  28. package/dist/docs/reference/packages/sdk-ts.ko.md +15 -18
  29. package/dist/docs/reference/packages/sdk-ts.md +14 -17
  30. package/dist/docs/troubleshooting.ko.md +18 -10
  31. package/dist/docs/troubleshooting.md +19 -11
  32. package/package.json +2 -2
@@ -50,12 +50,12 @@
50
50
  "en": {
51
51
  "path": "how-to/connect-surfaces.md",
52
52
  "title": "Connect the surfaces",
53
- "summary": "Connect Claude Code, Grok, and git; distinguish their witness paths."
53
+ "summary": "Connect Claude Code, Grok, Codex, and git; distinguish their witness paths."
54
54
  },
55
55
  "ko": {
56
56
  "path": "how-to/connect-surfaces.ko.md",
57
57
  "title": "표면 연결하기",
58
- "summary": "Claude Code, Grok, git을 연결하고 표면별 증인 사용법을 구별합니다."
58
+ "summary": "Claude Code, Grok, Codex, git을 연결하고 표면별 증인 사용법을 구별합니다."
59
59
  }
60
60
  },
61
61
  {
@@ -129,12 +129,12 @@
129
129
  "bundled": true,
130
130
  "en": {
131
131
  "path": "reference/cli/covenant-check.md",
132
- "title": "`pdks covenant check`",
132
+ "title": "pdks covenant check",
133
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
- "title": "`pdks covenant check`",
137
+ "title": "pdks covenant check",
138
138
  "summary": "stdin의 unified diff나 입력 IR을 판정하고 종료 코드를 읽는 방법을 설명합니다."
139
139
  }
140
140
  },
@@ -145,13 +145,13 @@
145
145
  "bundled": true,
146
146
  "en": {
147
147
  "path": "reference/cli/init.md",
148
- "title": "`pdks init`",
149
- "summary": "Create the project scaffold, and find the Claude Code and Grok installers."
148
+ "title": "pdks init",
149
+ "summary": "Create the project scaffold, and find the Claude Code, Grok, and Codex installers."
150
150
  },
151
151
  "ko": {
152
152
  "path": "reference/cli/init.ko.md",
153
- "title": "`pdks init`",
154
- "summary": "프로젝트 초기 파일을 만들고, Claude Code Grok 설치기를 찾습니다."
153
+ "title": "pdks init",
154
+ "summary": "프로젝트 초기 파일을 만들고, Claude Code, Grok, Codex 설치기를 찾습니다."
155
155
  }
156
156
  },
157
157
  {
@@ -161,12 +161,12 @@
161
161
  "bundled": true,
162
162
  "en": {
163
163
  "path": "reference/cli/explain.md",
164
- "title": "`pdks explain`",
164
+ "title": "pdks explain",
165
165
  "summary": "Inspect assembled registrations and their enforcement levels."
166
166
  },
167
167
  "ko": {
168
168
  "path": "reference/cli/explain.ko.md",
169
- "title": "`pdks explain`",
169
+ "title": "pdks explain",
170
170
  "summary": "조립된 등록과 강제 수준을 확인합니다."
171
171
  }
172
172
  },
@@ -177,12 +177,12 @@
177
177
  "bundled": true,
178
178
  "en": {
179
179
  "path": "reference/cli/docs.md",
180
- "title": "`pdks docs`",
180
+ "title": "pdks docs",
181
181
  "summary": "Search and retrieve installed documentation without network access."
182
182
  },
183
183
  "ko": {
184
184
  "path": "reference/cli/docs.ko.md",
185
- "title": "`pdks docs`",
185
+ "title": "pdks docs",
186
186
  "summary": "네트워크 없이 설치된 문서를 검색하고 조회합니다."
187
187
  }
188
188
  },
@@ -203,105 +203,121 @@
203
203
  }
204
204
  },
205
205
  {
206
- "id": "package-polydeukes",
206
+ "id": "declaration-language",
207
207
  "category": "reference",
208
208
  "order": 12,
209
209
  "bundled": true,
210
+ "en": {
211
+ "path": "reference/declaration-language/index.md",
212
+ "title": "Declaration language reference",
213
+ "summary": "Look up every source, extraction step, combinator, relation, and mechanism."
214
+ },
215
+ "ko": {
216
+ "path": "reference/declaration-language/index.ko.md",
217
+ "title": "선언 언어 참조",
218
+ "summary": "모든 소스, 추출 단계, 조합 연산, 관계, 기전의 문법과 제약을 조회합니다."
219
+ }
220
+ },
221
+ {
222
+ "id": "package-polydeukes",
223
+ "category": "reference",
224
+ "order": 13,
225
+ "bundled": true,
210
226
  "en": {
211
227
  "path": "reference/packages/polydeukes.md",
212
- "title": "`polydeukes`",
228
+ "title": "polydeukes",
213
229
  "summary": "Consult the polydeukes package contract and its limits."
214
230
  },
215
231
  "ko": {
216
232
  "path": "reference/packages/polydeukes.ko.md",
217
- "title": "`polydeukes`",
233
+ "title": "polydeukes",
218
234
  "summary": "polydeukes 패키지의 계약과 한계를 확인합니다."
219
235
  }
220
236
  },
221
237
  {
222
238
  "id": "package-core",
223
239
  "category": "reference",
224
- "order": 13,
240
+ "order": 14,
225
241
  "bundled": true,
226
242
  "en": {
227
243
  "path": "reference/packages/core.md",
228
- "title": "`@polydeukes/core`",
244
+ "title": "@polydeukes/core",
229
245
  "summary": "Consult the core package contract and its limits."
230
246
  },
231
247
  "ko": {
232
248
  "path": "reference/packages/core.ko.md",
233
- "title": "`@polydeukes/core`",
249
+ "title": "@polydeukes/core",
234
250
  "summary": "core 패키지의 계약과 한계를 확인합니다."
235
251
  }
236
252
  },
237
253
  {
238
254
  "id": "package-adapter-claude-code",
239
255
  "category": "reference",
240
- "order": 15,
256
+ "order": 16,
241
257
  "bundled": true,
242
258
  "en": {
243
259
  "path": "reference/packages/adapter-claude-code.md",
244
- "title": "`@polydeukes/adapter-claude-code`",
260
+ "title": "@polydeukes/adapter-claude-code",
245
261
  "summary": "Install the Claude Code session surface, and consult the adapter package contract and its limits."
246
262
  },
247
263
  "ko": {
248
264
  "path": "reference/packages/adapter-claude-code.ko.md",
249
- "title": "`@polydeukes/adapter-claude-code`",
265
+ "title": "@polydeukes/adapter-claude-code",
250
266
  "summary": "Claude Code 세션 표면을 설치하고, 어댑터 패키지의 계약과 한계를 확인합니다."
251
267
  }
252
268
  },
253
269
  {
254
270
  "id": "package-adapter-grok",
255
271
  "category": "reference",
256
- "order": 16,
272
+ "order": 17,
257
273
  "bundled": true,
258
274
  "en": {
259
275
  "path": "reference/packages/adapter-grok.md",
260
- "title": "`@polydeukes/adapter-grok`",
276
+ "title": "@polydeukes/adapter-grok",
261
277
  "summary": "Install the Grok session surface, and consult the adapter package contract and its limits."
262
278
  },
263
279
  "ko": {
264
280
  "path": "reference/packages/adapter-grok.ko.md",
265
- "title": "`@polydeukes/adapter-grok`",
281
+ "title": "@polydeukes/adapter-grok",
266
282
  "summary": "Grok 세션 표면을 설치하고, 어댑터 패키지의 계약과 한계를 확인합니다."
267
283
  }
268
284
  },
269
285
  {
270
286
  "id": "package-adapter-codex",
271
287
  "category": "reference",
272
- "order": 17,
288
+ "order": 18,
273
289
  "bundled": true,
274
290
  "en": {
275
291
  "path": "reference/packages/adapter-codex.md",
276
- "title": "`@polydeukes/adapter-codex`",
292
+ "title": "@polydeukes/adapter-codex",
277
293
  "summary": "Install the Codex session surface, and consult how patch text becomes file-change evidence."
278
294
  },
279
295
  "ko": {
280
296
  "path": "reference/packages/adapter-codex.ko.md",
281
- "title": "`@polydeukes/adapter-codex`",
297
+ "title": "@polydeukes/adapter-codex",
282
298
  "summary": "Codex 세션 표면을 설치하고, 패치 텍스트가 파일 변경 증거가 되는 방식을 확인합니다."
283
299
  }
284
300
  },
285
301
  {
286
302
  "id": "package-sdk-ts",
287
303
  "category": "reference",
288
- "order": 25,
304
+ "order": 26,
289
305
  "bundled": true,
290
306
  "en": {
291
307
  "path": "reference/packages/sdk-ts.md",
292
- "title": "`@polydeukes/sdk-ts`",
293
- "summary": "Call the judge from TypeScript with one verb, and read the three verdicts it returns."
308
+ "title": "@polydeukes/sdk-ts",
309
+ "summary": "Call checkCovenant from TypeScript and handle its three verdicts."
294
310
  },
295
311
  "ko": {
296
312
  "path": "reference/packages/sdk-ts.ko.md",
297
- "title": "`@polydeukes/sdk-ts`",
298
- "summary": "TypeScript에서 동사 하나로 판정기를 부르고, 돌아오는 판정 결과 셋을 읽습니다."
313
+ "title": "@polydeukes/sdk-ts",
314
+ "summary": "TypeScript에서 checkCovenant를 호출하고 가지 판정 결과를 처리합니다."
299
315
  }
300
316
  },
301
317
  {
302
318
  "id": "why-polydeukes",
303
319
  "category": "explanation",
304
- "order": 17,
320
+ "order": 18,
305
321
  "bundled": false,
306
322
  "en": {
307
323
  "path": "why-polydeukes.md",
@@ -317,7 +333,7 @@
317
333
  {
318
334
  "id": "contributing-docs",
319
335
  "category": "how-to",
320
- "order": 24,
336
+ "order": 25,
321
337
  "bundled": false,
322
338
  "en": {
323
339
  "path": "contributing.md",
@@ -329,134 +345,6 @@
329
345
  "title": "문서에 기여하기",
330
346
  "summary": "영한 쌍, 안정 ID, 카탈로그 규칙, 문서 변경 전에 실행할 명령을 적습니다."
331
347
  }
332
- },
333
- {
334
- "id": "post-1",
335
- "category": "history",
336
- "order": 18,
337
- "bundled": false,
338
- "en": {
339
- "path": "build-in-public/2026-07-v0.1-covenant-core.md",
340
- "title": "<!--",
341
- "summary": "Historical development account; not a current usage reference."
342
- },
343
- "ko": {
344
- "path": "build-in-public/2026-07-v0.1-covenant-core.ko.md",
345
- "title": "<!--",
346
- "summary": "당시의 개발 기록이며 현재 사용법을 설명하는 참조 문서는 아닙니다."
347
- }
348
- },
349
- {
350
- "id": "post-2",
351
- "category": "history",
352
- "order": 19,
353
- "bundled": false,
354
- "en": {
355
- "path": "build-in-public/2026-08-v0.2-user-disciplines.md",
356
- "title": "<!--",
357
- "summary": "Historical development account; not a current usage reference."
358
- },
359
- "ko": {
360
- "path": "build-in-public/2026-08-v0.2-user-disciplines.ko.md",
361
- "title": "<!--",
362
- "summary": "당시의 개발 기록이며 현재 사용법을 설명하는 참조 문서는 아닙니다."
363
- }
364
- },
365
- {
366
- "id": "post-3",
367
- "category": "history",
368
- "order": 20,
369
- "bundled": false,
370
- "en": {
371
- "path": "build-in-public/2026-08-v0.3-installable-release.md",
372
- "title": "<!--",
373
- "summary": "Historical development account; not a current usage reference."
374
- },
375
- "ko": {
376
- "path": "build-in-public/2026-08-v0.3-installable-release.ko.md",
377
- "title": "<!--",
378
- "summary": "당시의 개발 기록이며 현재 사용법을 설명하는 참조 문서는 아닙니다."
379
- }
380
- },
381
- {
382
- "id": "post-4",
383
- "category": "history",
384
- "order": 21,
385
- "bundled": false,
386
- "en": {
387
- "path": "build-in-public/2026-08-v0.4-gate-closing.md",
388
- "title": "<!--",
389
- "summary": "Historical development account; not a current usage reference."
390
- },
391
- "ko": {
392
- "path": "build-in-public/2026-08-v0.4-gate-closing.ko.md",
393
- "title": "<!--",
394
- "summary": "당시의 개발 기록이며 현재 사용법을 설명하는 참조 문서는 아닙니다."
395
- }
396
- },
397
- {
398
- "id": "post-5",
399
- "category": "history",
400
- "order": 22,
401
- "bundled": false,
402
- "en": {
403
- "path": "build-in-public/2026-08-v0.5-diagnostic-pivot.md",
404
- "title": "<!--",
405
- "summary": "Historical development account; not a current usage reference."
406
- },
407
- "ko": {
408
- "path": "build-in-public/2026-08-v0.5-diagnostic-pivot.ko.md",
409
- "title": "<!--",
410
- "summary": "당시의 개발 기록이며 현재 사용법을 설명하는 참조 문서는 아닙니다."
411
- }
412
- },
413
- {
414
- "id": "post-6",
415
- "category": "history",
416
- "order": 23,
417
- "bundled": false,
418
- "en": {
419
- "path": "build-in-public/2026-09-v0.6-algebra-refoundation.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-algebra-refoundation.ko.md",
425
- "title": "<!--",
426
- "summary": "당시의 개발 기록이며 현재 사용법을 설명하는 참조 문서는 아닙니다."
427
- }
428
- },
429
- {
430
- "id": "post-7",
431
- "category": "history",
432
- "order": 24,
433
- "bundled": false,
434
- "en": {
435
- "path": "build-in-public/2026-09-v0.6.1-docs-and-search.md",
436
- "title": "<!--",
437
- "summary": "Historical development account; not a current usage reference."
438
- },
439
- "ko": {
440
- "path": "build-in-public/2026-09-v0.6.1-docs-and-search.ko.md",
441
- "title": "<!--",
442
- "summary": "당시의 개발 기록이며 현재 사용법을 설명하는 참조 문서는 아닙니다."
443
- }
444
- },
445
- {
446
- "id": "post-8",
447
- "category": "history",
448
- "order": 25,
449
- "bundled": false,
450
- "en": {
451
- "path": "build-in-public/2026-09-v0.7-entrypoint-reshape.md",
452
- "title": "<!--",
453
- "summary": "Historical development account; not a current usage reference."
454
- },
455
- "ko": {
456
- "path": "build-in-public/2026-09-v0.7-entrypoint-reshape.ko.md",
457
- "title": "<!--",
458
- "summary": "당시의 개발 기록이며 현재 사용법을 설명하는 참조 문서는 아닙니다."
459
- }
460
348
  }
461
349
  ],
462
350
  "topics": {
@@ -6,6 +6,8 @@ Polydeukes는 연결된 표면이 공급하는 증거를 바탕으로 선언된
6
6
  에이전트가 관행을 지켰다고 말하는 것만으로 이행을 인정하지 않습니다. 정상 판정이
7
7
  설명하는 범위도 실제로 관측한 파일, 호출, 대화 기록에 한정됩니다.
8
8
 
9
+ 관계와 추출 연산의 전체 문법은 [선언 언어 참조](../reference/declaration-language/index.ko.md)에서 확인할 수 있습니다.
10
+
9
11
  <a id="terms"></a>
10
12
  ## 약속, 규율, 표면
11
13
 
@@ -6,6 +6,8 @@ Polydeukes checks a declared practice against evidence a connected surface suppl
6
6
  infer that a practice was followed merely because an agent says so. A passing result is bounded
7
7
  by the files, calls, and history actually observed.
8
8
 
9
+ For the complete syntax of relations and extraction steps, see the [Declaration language reference](../reference/declaration-language/index.md).
10
+
9
11
  <a id="terms"></a>
10
12
  ## Covenant, discipline, and surface
11
13
 
@@ -56,23 +56,35 @@ Codex에서 개발할 때 씁니다.
56
56
  제공합니다. 먼저 `pdks init`으로 초기 파일을 만든 뒤 Codex 등록 산출물을 씁니다.
57
57
  3. Codex에서 `/hooks`로 생성된 훅을 승인합니다. 승인하기 전까지는 훅을 건너뜁니다.
58
58
 
59
- Codex 프로젝트에는 `.codex/hooks/covenant-pretooluse.mjs` 위임자와 `.codex/hooks.json`의 항목이
60
- 생깁니다. JSON은 덮어쓰지 않고 병합합니다. 다른 이벤트, 다른 matcher, 설치기가 모르는 키는
61
- 그대로 둡니다. 초기 설정은 기본적으로 `.codex/hooks`를 보호합니다.
59
+ Codex 프로젝트에는 `.codex/hooks/covenant-pretooluse.mjs` 위임자와 `.codex/hooks.json`의
60
+ `PreToolUse`, `UserPromptSubmit`, `PostToolUse`, `SessionEnd` 항목이 생깁니다. JSON은
61
+ 덮어쓰지 않고 병합합니다. 사용자 항목, 같은 항목의 다른 handler, 다른 이벤트, 설치기가 모르는
62
+ 키는 그대로 둡니다. 초기 설정은 기본적으로 `.codex/hooks`를 보호합니다.
62
63
 
63
64
  **승인은 선택이 아닙니다.** Codex는 훅 정의의 해시로 신뢰를 기록하므로, 새로 쓴 훅은 검토
64
65
  대상으로 표시되고 누군가 승인하기 전까지 건너뛰어집니다. 그때까지는 아무것도 판정되지
65
66
  않습니다. `init`은 실행할 때마다 바이트가 같은 명령 문자열을 쓰므로, 다시 설치해도 이미 받은
66
67
  승인이 무효가 되지 않습니다.
67
68
 
68
- Codex는 모든 파일 편집을 `apply_patch` 하나로 정규화하고, 경로 인자가 아니라 패치 텍스트를
69
+ Codex는 훅에 도달하는 모든 파일 편집을 `apply_patch` 하나로 정규화하고, 경로 인자가 아니라 패치 텍스트를
69
70
  보냅니다. `Edit`과 `Write`는 훅 파일에 적을 수 있는 matcher 별칭이며 도구 이름으로 도착하지
70
71
  않습니다. 패치 하나가 여러 파일을 건드리면 파일마다 IR 원소 하나가 실리고, 그중 하나라도
71
72
  차단되면 호출 전체가 차단됩니다.
72
73
 
73
- Codex에는 대화 기록 채널이 없어서 세션 증인(witness) 밸브가 읽을 사람 메시지가 없습니다.
74
- 의도한 편집이 차단되면 자신의 터미널에서 수행하세요. 세션 어댑터를 한 프로젝트에 둘 이상
75
- 설치하면 호출마다 판정기가 번 실행될 수 있습니다.
74
+ **승인된 훅도 Code Mode는 덮지 못합니다.** codex-cli 0.154에서 Code Mode `exec` 호출과 그
75
+ JavaScript 안에 중첩된 도구 호출은 `PreToolUse`에 도달하지 않으므로
76
+ ([openai/codex#23411](https://github.com/openai/codex/issues/23411)), 경로로 이루어진 편집은
77
+ `/hooks`에 훅이 Active로 표시되는 동안에도 판정되지도 기록되지도 않습니다. `init`이 이 사실을
78
+ `note:` 줄로 출력하고, [패키지 레퍼런스](../reference/packages/adapter-codex.ko.md#limits)가
79
+ 다른 선언된 한계와 함께 나열합니다.
80
+
81
+ Codex의 대화 기록 형식은 계속 불안정하므로 해석하지 않습니다. 대신 `UserPromptSubmit`이
82
+ 시각을 붙인 사람 메시지를, `PostToolUse`가 완료된 도구 호출을 `.polydeukes/codex-sessions/`
83
+ 아래의 어댑터 소유 파일에 기록하고 `SessionEnd`가 지웁니다. 의도한 차단을 풀려면 설정된 증인
84
+ 토큰을 첫 줄에 단독으로 보낸 뒤 호출을 다시 시도합니다. 복구 메시지가
85
+ `UserPromptSubmit` 증거가 없다고 알리면 재시도가 증인 밸브에 닿지 못하므로 자신의 터미널을
86
+ 사용합니다. 세션 어댑터를 한 프로젝트에 둘 이상 설치하면 호출마다 판정기가 두 번 실행될 수
87
+ 있습니다.
76
88
 
77
89
  <a id="change-set-surface"></a>
78
90
  ## 변경 집합 표면
@@ -58,24 +58,36 @@ Use this when the project is developed in Codex.
58
58
  runs `pdks init` for the scaffold, then writes the Codex registration artifacts.
59
59
  3. Approve the generated hook with `/hooks` in Codex. Until you do, it is skipped.
60
60
 
61
- A Codex tree gets a delegator at `.codex/hooks/covenant-pretooluse.mjs` and an entry in
62
- `.codex/hooks.json`. That JSON is merged, not overwritten: other events, other matchers, and
63
- keys the installer does not know stay where they are. The scaffold config protects
64
- `.codex/hooks` by default.
61
+ A Codex tree gets a delegator at `.codex/hooks/covenant-pretooluse.mjs` and entries for
62
+ `PreToolUse`, `UserPromptSubmit`, `PostToolUse`, and `SessionEnd` in `.codex/hooks.json`.
63
+ That JSON is merged, not overwritten: user entries, sibling handlers, other events, and keys
64
+ the installer does not know stay where they are. The scaffold config protects `.codex/hooks`
65
+ by default.
65
66
 
66
67
  **Approval is not optional.** Codex records trust against the hash of a hook's definition, so a
67
68
  newly written hook is listed for review and skipped until someone approves it — until then
68
69
  nothing is judged. `init` writes a byte-identical command string on every run, so a re-install
69
70
  does not invalidate an approval you already gave.
70
71
 
71
- Codex normalises every file edit into one tool, `apply_patch`, and sends the patch text rather
72
- than a path argument. `Edit` and `Write` are matcher aliases you may write in the hooks file;
73
- they never arrive as the tool name. One patch that touches several files carries one IR element
74
- per file, and any one of them blocking blocks the whole call.
75
-
76
- Codex supplies no transcript channel, so the session witness valve has no human message to read.
77
- For an intentional blocked edit, use your own terminal. Installing more than one session adapter
78
- in one project can run the judge twice per call.
72
+ Codex normalises every file edit that reaches the hook into one tool, `apply_patch`, and sends
73
+ the patch text rather than a path argument. `Edit` and `Write` are matcher aliases you may
74
+ write in the hooks file; they never arrive as the tool name. One patch that touches several
75
+ files carries one IR element per file, and any one of them blocking blocks the whole call.
76
+
77
+ **An approved hook does not cover Code Mode.** In codex-cli 0.154 a Code Mode `exec` dispatch,
78
+ and the tool calls nested in its JavaScript, do not reach `PreToolUse`
79
+ ([openai/codex#23411](https://github.com/openai/codex/issues/23411)), so an edit made that way
80
+ is neither judged nor logged even while `/hooks` shows the hook Active. `init` prints this as a
81
+ `note:` line; the [package reference](../reference/packages/adapter-codex.md#limits)
82
+ lists it with the other declared limits.
83
+
84
+ Codex's transcript format remains unstable and is never parsed. Instead, `UserPromptSubmit`
85
+ records timestamped human messages and `PostToolUse` records completed tool calls in an
86
+ adapter-owned file under `.polydeukes/codex-sessions/`; `SessionEnd` removes it. To release an
87
+ intentional block, send the configured witness token alone on the first line, then retry the
88
+ call. If the recovery message says no `UserPromptSubmit` evidence was recorded, use your own
89
+ terminal because the retry cannot reach the witness valve. Installing more than one session
90
+ adapter in one project can run the judge twice per call.
79
91
 
80
92
 
81
93
  <a id="change-set-surface"></a>
@@ -6,6 +6,8 @@
6
6
  증거를 고르고, 추출 과정과 관계를 적은 다음 위반과 정상 사례를 각각 실행합니다.
7
7
  관측 결과를 보고 차단이 필요하다고 판단하기 전까지는 기본 강제 수준인 `advise`를 유지합니다.
8
8
 
9
+ 관계와 추출 연산의 전체 문법은 [선언 언어 참조](../reference/declaration-language/index.ko.md)에서 확인할 수 있습니다.
10
+
9
11
  <a id="locale-key-pairing"></a>
10
12
  ## 번역 키 짝 맞춤
11
13
 
@@ -90,13 +92,55 @@ git restore -- locales/en.json locales/ko.json
90
92
  소스 파일이 존재한다는 이유만으로 선언이 실행되지는 않습니다. 관측된 변경 중 하나
91
93
  이상이 해당 선언의 적용 범위와 일치해야 합니다.
92
94
 
95
+ <a id="locale-key-pairing-many"></a>
96
+ ### 번역 파일이 셋 이상일 때
97
+
98
+ `equal`은 추출 결과 두 개를 비교합니다. 파일이 셋 이상이면 모든 파일의 키를 모은 합집합을
99
+ 만들고, 파일마다 `subset` 하나로 그 합집합을 모두 가지고 있는지 확인합니다. `onlyIn`은
100
+ 합집합에 아직 없는 키만 더하므로, 여러 파일에 있는 키도 그 키가 빠진 파일마다 증인 1건으로
101
+ 나옵니다. 이 방법은 `flattenKeys`가 각 항목의 키와 값에 같은 점 경로를 싣는다는 점에 기댑니다.
102
+ `onlyIn`은 키를 비교하고 `subset`은 값을 비교하기 때문입니다. 줄 번호를 키로 삼는 `lines`처럼
103
+ 키와 값이 다른 추출에는 이 방법을 쓸 수 없습니다.
104
+
105
+ `ko`·`en`·`fr` 세 파일이라면 위 예제의 `locale-key-parity` 항목을 다음으로 바꿉니다. `supply:
106
+ 'error'`는 없는 파일을 거부하므로, 위 절차를 실행하기 전에 같은 키를 가진 `locales/fr.json`도
107
+ 만듭니다(`printf '{"home":"Accueil"}\n' > locales/fr.json`).
108
+
109
+ ```yaml
110
+ - id: 'locale-key-parity'
111
+ why: 'every locale file must carry the same keys'
112
+ declare:
113
+ mechanism: 'pairing'
114
+ sources:
115
+ ko: { file: 'locales/ko.json' }
116
+ en: { file: 'locales/en.json' }
117
+ fr: { file: 'locales/fr.json' }
118
+ supply: { ko: 'error', en: 'error', fr: 'error' }
119
+ scope: { source: 'target.path', include: ['^locales/(ko|en|fr)\.json$'] }
120
+ extract:
121
+ ko: [{ op: 'source', of: 'ko' }, { op: 'json' }, { op: 'flattenKeys' }]
122
+ en: [{ op: 'source', of: 'en' }, { op: 'json' }, { op: 'flattenKeys' }]
123
+ fr: [{ op: 'source', of: 'fr' }, { op: 'json' }, { op: 'flattenKeys' }]
124
+ enNew: [{ op: 'onlyIn', of: 'en', notIn: 'ko' }]
125
+ koEn: [{ op: 'union', of: ['ko', 'enNew'] }]
126
+ frNew: [{ op: 'onlyIn', of: 'fr', notIn: 'koEn' }]
127
+ all: [{ op: 'union', of: ['koEn', 'frNew'] }]
128
+ relate:
129
+ - { id: 'ko-full', relation: { op: 'subset', of: 'all', in: 'ko' }, message: '{value} is missing from ko' }
130
+ - { id: 'en-full', relation: { op: 'subset', of: 'all', in: 'en' }, message: '{value} is missing from en' }
131
+ - { id: 'fr-full', relation: { op: 'subset', of: 'all', in: 'fr' }, message: '{value} is missing from fr' }
132
+ ```
133
+
134
+ 기준이 되는 파일은 없습니다. `ko`에만 있는 키는 `en-full`과 `fr-full`을 위반하고, `en`과
135
+ `fr`에만 있는 키는 `ko-full` 하나만 위반합니다. 파일이 하나 늘 때마다 추출 세 개(그 파일의 키,
136
+ `onlyIn`, 다음 `union`)와 관계 항목 하나가 늘고, 모든 관계 항목의 `of`는 그 마지막 `union`으로
137
+ 옮깁니다.
138
+
93
139
  <a id="which-list"></a>
94
140
  ## 어느 목록에 적는가
95
141
 
96
- 규율 목록은 셋이고, 항목이 어느 목록에 속하는지는 소스 축이 정합니다. 기전이 정하지도 않고
97
- 관계가 정하지도 않습니다. 같은 `companion` 기전이라도 `file` 소스 위에 서면 `disciplines`에
98
- 있고 `changes` 위에 서면 `changeSetDisciplines`에 있습니다. 선언의 소스를 읽으면 목록이
99
- 따라 나옵니다.
142
+ 선언이 읽는 소스에 따라 규율 목록을 선택합니다. 예를 들어 `companion` 선언이 `file`
143
+ 소스만 읽으면 `disciplines`에, `changes`를 읽으면 `changeSetDisciplines`에 적습니다.
100
144
 
101
145
  | 선언이 읽는 것 | 목록 | 예 |
102
146
  |---|---|---|
@@ -112,37 +156,30 @@ git restore -- locales/en.json locales/ko.json
112
156
  됩니다. 규칙 자체와 오류 모양은
113
157
  [설정 참조](../reference/configuration/index.ko.md#placement-rule)에 있습니다.
114
158
 
115
- 표면이 공급해야 것을 본체가 읽지 않아도 실제로는 표면에 묶이는 항목이 있습니다. 대화
116
- 기록을 읽는 밸브(`witness`)가 달린 항목은 밸브 자신의 `extract`가 대화 기록을 묶으므로 세션
117
- 항목이 됩니다.
159
+ 목록을 고를 때는 `witness` 블록의 소스도 포함합니다. 블록의 `extract`가 대화 기록을
160
+ 읽으면 항목 전체를 `sessionDisciplines`에 적습니다.
118
161
 
119
162
  <a id="posture"></a>
120
163
  ## 무인 실시간 표면의 기본 자세
121
164
 
122
- 무인 실시간 표면은 터미널 앞에 사람이 없는 어댑터 훅이나 SDK 호출자입니다. 사람이 지켜보는
123
- 자리에는 적용되지 않는 규칙 둘이 이곳에 적용됩니다.
124
-
125
- **루프가 회차 안에서 스스로 고치지 못하는 항목을 `enforce: block`으로 올립니다.** 기준은
126
- "되돌릴 없는가"가 아닙니다. 실시간 차단의 비용은 단위입니다. 모델이 stderr의 사유를
127
- 읽고 다시 시도하므로 위반이 회차 안에서 고쳐집니다. `advise`로 두면 같은 위반이 뒤의
128
- 검사, 테스트 실행이나 CI나 리뷰어에게까지 가서 회차 하나를 쓰며 최대 45분이 듭니다.
129
- "무인이니 전부 차단"이라는 뜻은 아닙니다. 차단은 회피를 낳고 회피는 텔레메트리 행을 남기지
130
- 않으므로, 루프가 손댈 수 없는 항목은 위반이라도 기록되는 `advise`에 두는 편이 낫습니다. 이
131
- 기준은 설정 저자의 것입니다.
132
-
133
- **밸브가 없으므로 사유가 값으로 돌아옵니다.** 실시간 무인 표면에는 증인 밸브가 없습니다.
134
- TTY도 사람의 턴도 없고, SDK는 증인 인자를 받지 않으며 세션을 지어내지도 않습니다. 그 자리를
135
- 대신하는 것이 사유를 데이터로 돌려주는 일입니다. `checkCovenant`는
136
- `{ verdict: 'blocked', reason }`을 돌려주며 `reason`은 판정기 자신의 stderr이고,
137
- `{ verdict: 'upheld', advisories }`는 종료 코드 0인 실행의 권고 줄을 싣습니다. 소비자는 그
138
- 텍스트를 사람이 나중에 읽는 자리, 이슈나 로그에 적고 멈춥니다. 권고 텍스트를 모델에게
139
- 보일지도 소비자가 정합니다. 무인 루프에는 stderr 한 줄을 읽을 사람이 없으므로, 호출자가
140
- 전달해야 권고가 소비됩니다. 판정 결과의 모양은
141
- [`@polydeukes/sdk-ts` 참조](../reference/packages/sdk-ts.ko.md)에 있습니다.
142
-
143
- SDK 자신의 기본값은 실행 전체에 대한 `enforce: 'block'`이며, 이것은 표면의 강제 수준이지
144
- 항목의 것이 아닙니다. 보호 경로와 `enforce: block` 항목이 호출을 멈추고, 나머지 위반은
145
- `advised`로 기록됩니다. 두 어댑터도 같은 방식으로 판정기를 스폰합니다.
165
+ 사람이 지켜보지 않는 어댑터 훅이나 SDK 호출자는 차단과 권고를 받았을 어떻게 처리할지
166
+ 정해야 합니다.
167
+
168
+ **권고만으로는 루프가 위반을 수정하지 않을 `enforce: block`을 사용합니다.** 호출자는
169
+ 모델에게 사유와 재시도 방법을 전달해야 합니다. 루프가 진단에 따라 조치할 없는 항목은
170
+ `advise`로 두고, 기록된 위반을 사람이 검토할 있게 합니다. 해당 루프의 실제 관측 결과를
171
+ 바탕으로 강제 수준을 선택하세요.
172
+
173
+ **진단을 호출자에게 돌려줍니다.** `checkCovenant`는 판정기의 stderr를 담은
174
+ `{ verdict: 'blocked', reason }` 또는 종료 코드 0인 실행의 권고를 담은
175
+ `{ verdict: 'upheld', advisories }`를 반환합니다. SDK는 별도의 증인 인자를 받지 않습니다.
176
+ 호출자는 진단을 모델에게 전달할지, 이슈나 로그에 기록할지, 재시도하거나 중단할지 정합니다.
177
+ 권고도 호출자가 전달해야 모델이 읽을 있습니다.
178
+ 반환 타입은 [SDK 참조](../reference/packages/sdk-ts.ko.md#verdicts)에 있습니다.
179
+
180
+ SDK는 실행 전체에 기본값 `enforce: 'block'`을 적용합니다. 수준에서는 보호 경로와
181
+ `enforce: block` 항목이 호출을 멈출 있고, 나머지 규율 위반은 `advised`로 기록됩니다.
182
+ 에이전트 어댑터도 같은 설정을 사용합니다.
146
183
 
147
184
  <a id="when-to-draft"></a>
148
185
  ## 선언 대신 초안으로 남길 때