polydeukes 0.8.0 → 0.9.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.
@@ -97,23 +97,26 @@ npx pdks-codex init
97
97
  - `.codex/hooks/covenant-pretooluse.mjs`
98
98
  - `.codex/hooks.json`
99
99
 
100
- `hooks.json`은 덮어쓰지 않고 병합합니다. 다른 이벤트, 다른 matcher, 설치기가 모르는 키는
101
- 그대로 둡니다. 초기 설정은 기본적으로 `.codex/hooks`를 보호하므로, 이 설치기가 만드는 등록
102
- 파일은 같은 설치가 만든 설정이 지킵니다.
100
+ `hooks.json`에는 `PreToolUse`, `UserPromptSubmit`, `PostToolUse`, `SessionEnd` 항목이
101
+ 생깁니다. 파일은 덮어쓰지 않고 병합합니다. 사용자 항목, 같은 항목의 다른 handler, 다른
102
+ 이벤트, 설치기가 모르는 키는 그대로 둡니다. 초기 설정은 기본적으로 `.codex/hooks`를
103
+ 보호하므로, 이 설치기가 만드는 등록 파일은 같은 설치가 만든 설정이 지킵니다.
103
104
 
104
105
  **훅 승인까지가 설치입니다.** Codex는 훅 정의의 해시로 신뢰를 기록하므로, 생성된 훅은 검토
105
106
  대상으로 표시되고 `/hooks`에서 승인하기 전까지 건너뛰어집니다. 누군가 승인하기 전까지는
106
107
  아무것도 판정되지 않습니다. `init`이 실행할 때마다 바이트가 같은 명령 문자열을 쓰는 이유가
107
108
  이것입니다. 문자열이 바뀌면 다시 승인해야 합니다.
108
109
 
109
- Codex는 모든 파일 편집을 `apply_patch` 하나로 정규화하고, 경로 인자가 아니라 패치 텍스트를
110
+ Codex는 훅에 도달하는 모든 파일 편집을 `apply_patch` 하나로 정규화하고, 경로 인자가 아니라 패치 텍스트를
110
111
  보냅니다. `Edit`과 `Write`는 `.codex/hooks.json`에 적을 수 있는 matcher 별칭이며 도구 이름으로
111
112
  도착하지 않습니다. 패치 하나가 여러 파일을 건드리면 파일마다 IR 원소 하나가 실리고, 그중
112
113
  하나라도 차단되면 호출 전체가 차단됩니다.
113
114
 
114
- Codex에는 대화 기록 채널이 없어서 세션 증인(witness) 밸브가 읽을 사람 메시지 증거가
115
- 없습니다. 의도한 편집이 차단되면 자신의 터미널에서 수행하세요. 산출물별 동작은
116
- [표면 연결하기](../../how-to/connect-surfaces.ko.md#codex)에 있습니다.
115
+ 불안정한 Codex 대화 기록은 해석하지 않습니다. `UserPromptSubmit`은 시각을 붙인 사람
116
+ 메시지를, `PostToolUse`는 완료된 도구 호출을 공급하고, `SessionEnd`는 어댑터 소유 증거
117
+ 파일을 정리합니다. 따라서 설정된 증인 토큰으로 다시 시도한 보호 호출을 허용할 수 있습니다.
118
+ 프롬프트 증거가 기록되지 않았다면 복구 메시지가 안내하는 사용자 터미널을 사용합니다.
119
+ 산출물별 동작은 [표면 연결하기](../../how-to/connect-surfaces.ko.md#codex)에 있습니다.
117
120
 
118
121
  <a id="init-results"></a>
119
122
  ## 결과와 실패 조건
@@ -96,23 +96,28 @@ That command runs `pdks init` for the scaffold, then writes the Codex registrati
96
96
  - `.codex/hooks/covenant-pretooluse.mjs`
97
97
  - `.codex/hooks.json`
98
98
 
99
- `hooks.json` is merged rather than overwritten: other events, other matchers, and keys the
100
- installer does not know are left in place. The scaffold config protects `.codex/hooks` by
101
- default, so the registration this installer writes is covered by the config it writes.
99
+ `hooks.json` receives entries for `PreToolUse`, `UserPromptSubmit`, `PostToolUse`, and
100
+ `SessionEnd`. It is merged rather than overwritten: user entries, sibling handlers, other
101
+ events, and keys the installer does not know are left in place. The scaffold config protects
102
+ `.codex/hooks` by default, so the registration this installer writes is covered by the config
103
+ it writes.
102
104
 
103
105
  **Approving the hook is part of the install.** Codex records trust against the hash of a hook's
104
106
  definition, so the generated hook is listed for review and skipped until you approve it with
105
107
  `/hooks`. Until someone does, nothing is judged. This is why `init` writes a byte-identical
106
108
  command string on every run — a changed string needs approving again.
107
109
 
108
- Codex normalises every file edit into one tool, `apply_patch`, and delivers the patch text
109
- rather than a path argument. `Edit` and `Write` are matcher aliases you may write in
110
- `.codex/hooks.json`; they never arrive as the tool name. One patch that touches several files
111
- carries one IR element per file, and any one of them blocking blocks the whole call.
112
-
113
- Codex supplies no transcript channel, so the session witness valve has no human-message
114
- evidence to read. For an intentional blocked edit, use your own terminal. Details are in
115
- [Connect the surfaces](../../how-to/connect-surfaces.md#codex).
110
+ Codex normalises every file edit that reaches the hook into one tool, `apply_patch`, and
111
+ delivers the patch text rather than a path argument. `Edit` and `Write` are matcher aliases
112
+ you may write in `.codex/hooks.json`; they never arrive as the tool name. One patch that
113
+ touches several files carries one IR element per file, and any one of them blocking blocks
114
+ the whole call.
115
+
116
+ The unstable Codex transcript is never parsed. `UserPromptSubmit` supplies timestamped human
117
+ messages, `PostToolUse` supplies completed tool calls, and `SessionEnd` cleans up the
118
+ adapter-owned evidence file. A configured witness token can therefore release a retried
119
+ protected call. If no prompt evidence was recorded, use the user terminal named by the recovery
120
+ message. Details are in [Connect the surfaces](../../how-to/connect-surfaces.md#codex).
116
121
 
117
122
  <a id="init-results"></a>
118
123
  ## Results and failure conditions
@@ -2,9 +2,9 @@
2
2
 
3
3
  [English](adapter-codex.md) · **한국어**
4
4
 
5
- > **Codex의 설치 단위**입니다. `PreToolUse` 페이로드가 약속(covenant) 입력 IR이 되고, 패치가
6
- > 건드리는 파일마다 원소 하나가 실립니다. 세션 표면을 프로젝트에 설치하는 것도 이 패키지가
7
- > 합니다.
5
+ > **Codex의 설치 단위**입니다. 생명주기 이벤트는 어댑터 소유 세션 증거가 되고,
6
+ > `PreToolUse` 페이로드는 패치가 건드리는 파일마다 원소 하나를 실은 약속(covenant) 입력 IR이
7
+ > 됩니다.
8
8
  >
9
9
  > 베타입니다. `polydeukes`와 함께 설치하며, `polydeukes`는 이 패키지의 `peerDependency`입니다.
10
10
 
@@ -17,13 +17,16 @@ Codex의 입력을 공통 형식으로 번역합니다. 에이전트와 도구
17
17
  | 단위 | 하는 일 |
18
18
  |---|---|
19
19
  | `pdks-codex` 실행 파일 | 하위 명령 하나 `pdks-codex init`으로 프로젝트에 세션 표면을 등록합니다 |
20
- | `runHook` | `PreToolUse` 페이로드 하나를 입력 IR로 바꾸고 판정기를 스폰합니다 |
20
+ | `runHook` | 생명주기 증거를 기록하거나, `PreToolUse` 페이로드 하나를 입력 IR로 바꾸고 판정기를 스폰합니다 |
21
+ | 세션 증거 | 시각을 붙인 사람 메시지와 완료된 도구 호출을 SHA-256 세션 파일에 저장하고 `SessionEnd`에서 지웁니다 |
21
22
  | 페이로드 검증 | 호스트의 생성 스키마가 필수로 지정한 키를 모두 요구하며, 그 호스트가 보내는 한 가지 표기만 받습니다 |
22
23
  | 패치 해석 | `apply_patch` 호출의 원본 패치 텍스트를 건드리는 파일마다 변경 하나로 풉니다 |
23
24
  | 경로 기준 변환 | 패치 경로를 호출의 작업 디렉터리 기준으로 해석한 뒤 프로젝트 루트 기준으로 실습니다 |
24
25
 
25
- 생성된 훅 위임자가 불러오는 것이 `runHook({ repoRoot })`입니다. `tools` 명부를 실은 입력 IR을
26
- 만든 뒤 — `session`과 `actor` 키는 없습니다 — `repoRoot`에서
26
+ 생성된 훅 위임자가 불러오는 것이 `runHook({ repoRoot })`입니다. `UserPromptSubmit`과
27
+ `PostToolUse`는 `.polydeukes/codex-sessions/` 아래에 엄격한 JSONL 레코드를 추가하고,
28
+ `SessionEnd`는 그 세션 파일만 지웁니다. `PreToolUse`는 `tools` 명부와 이 레코드에서 만든
29
+ `session`을 싣되 `actor`나 `channels`를 합성하지 않은 뒤, `repoRoot`에서
27
30
  `pdks covenant check --enforce block`을 스폰하고 그 자식 프로세스의 종료 코드를 그대로
28
31
  돌려줍니다. 판정은 그 자식 프로세스가 하며, 이 패키지에는 판정 코드가 없습니다.
29
32
 
@@ -33,7 +36,7 @@ Codex의 입력을 공통 형식으로 번역합니다. 에이전트와 도구
33
36
  <a id="apply-patch"></a>
34
37
  ## 형제 어댑터는 인자를 읽는데 이 어댑터가 텍스트를 해석하는 이유
35
38
 
36
- Codex는 모든 파일 편집을 `apply_patch`라는 이름 하나로 정규화하고, 패치 자체를
39
+ Codex는 훅에 도달하는 모든 파일 편집을 `apply_patch`라는 이름 하나로 정규화하고, 패치 자체를
37
40
  `tool_input.command`에 담습니다. 셸 호출이 명령줄을 싣는 것과 같은 자리입니다. 읽을 경로
38
41
  인자가 없습니다. `Edit`과 `Write`는 `.codex/hooks.json`에 적을 수 있는 matcher 별칭이지만,
39
42
  페이로드는 언제나 도구 이름을 `apply_patch`로 보냅니다. 그래서 별칭을 기준으로 삼은 명부나
@@ -55,7 +58,8 @@ npx pdks-codex init
55
58
  ```
56
59
 
57
60
  `pdks-codex init`은 프로젝트에서 `polydeukes`를 찾아 확인한 뒤, 에이전트 중립 초기 구성을
58
- 위해 `pdks init`을 스폰하고, 위임자를 쓰고 자기 항목을 `.codex/hooks.json`에 병합합니다.
61
+ 위해 `pdks init`을 스폰하고, 위임자를 쓴 뒤 `PreToolUse`, `UserPromptSubmit`, `PostToolUse`,
62
+ `SessionEnd` 항목을 `.codex/hooks.json`에 병합합니다.
59
63
  병합은 기존 내용을 지우지 않습니다. 다른 이벤트, 다른 matcher, 이 패키지가 모르는 키는 그대로
60
64
  둡니다. 다시 실행하면 이미 있는 산출물을 건너뛴 것으로 보고하고 아무것도 덮어쓰지 않습니다.
61
65
  전체 산출물 목록은 [`pdks init`](../cli/init.ko.md#init-codex)에 있습니다.
@@ -77,19 +81,32 @@ npx pdks-codex init
77
81
  <a id="limits"></a>
78
82
  ## 선언된 한계
79
83
 
80
- 앞의 셋은 호스트 자신의 한계이고 호스트 훅 문서가 밝힌 사항입니다. 어떤 어댑터도 이 범위를
81
- 좁힐 수 없습니다.
82
-
84
+ 앞의 넷은 호스트 자신의 한계이고 어떤 어댑터도 이 범위를 좁힐 수 없습니다. 첫째는 문서가
85
+ 아니라 실제 측정으로 확인한 사항이고, 다음 셋은 호스트 훅 문서가 밝힌 사항입니다.
86
+
87
+ - **Code Mode의 `exec` 호출은 관측되지 않습니다.** codex-cli 0.154는 Code Mode `exec` 호출에도,
88
+ 그 JavaScript 안에 중첩된 `tools.apply_patch` · `tools.exec_command` 호출에도 `PreToolUse`를
89
+ 발화하지 않습니다([openai/codex#23411](https://github.com/openai/codex/issues/23411),
90
+ [#38850](https://github.com/openai/codex/issues/38850)). `/hooks`에 Active로 표시된 훅도 그
91
+ 표면에서는 아무것도 보지 못하고, 거기서 편집된 보호 경로는 telemetry 행을 남기지 않습니다.
92
+ `pdks-codex init`이 이 사실을 `note:` 줄로 출력합니다.
93
+ - **무엇을 판정하는지는 matcher가 아니라 명부가 정합니다.** 어댑터는 `apply_patch`와 `Bash`만
94
+ 번역하고, 그 밖의 이름(Code Mode 이름, MCP 도구, `write_stdin`)은 판정기를 띄우기 전에
95
+ exit 2와 `blocked` 러너 행으로 거부합니다. `.codex/hooks.json`의 matcher를 그런 이름까지
96
+ 넓히면 그 아래의 모든 호출이 판정 대신 차단되고, 그 편집은 신뢰 해시를 바꾸므로 `/hooks`에서
97
+ 다시 승인하기 전까지 훅이 건너뛰어집니다.
83
98
  - **`write_stdin`은 다시 판정되지 않습니다.** 이미 `PreToolUse`를 통과한 unified-exec 세션에
84
99
  입력을 전달합니다. 입력을 받으려고 열어 둔 셸은 그것을 연 호출에서 한 번 판정됩니다.
85
100
  - **호스트가 제공하는 도구는 이 경로를 지나지 않습니다.** 웹 검색 같은 도구는 로컬 함수 도구
86
101
  훅을 거치지 않으므로 어떤 약속에도 닿지 않습니다.
87
102
  - **호스트는 자기 도구 훅을 완전한 차단 경계가 아니라 보조 장치라고 밝힙니다.** 일부 특수한
88
103
  도구 경로는 기본 훅 경로를 지나지 않을 수 있습니다.
89
- - **대화 기록 채널이 없습니다.** IR에 `session`과 `actor` 키가 없습니다. 페이로드가 대화 기록
90
- 경로를 지목하지만 호스트가 그 형식을 안정된 인터페이스가 아니라고 밝혔으므로 어떤 판정도
91
- 그것을 읽지 않습니다. 그래서 세션 증인 밸브가 필요로 하는 사람 메시지 증거를 얻을 수
92
- 없습니다. 의도적으로 차단된 편집을 하려면 사용자의 터미널을 쓰십시오.
104
+ - **불안정한 대화 기록은 채널로 쓰지 않습니다.** 페이로드가 대화 기록 경로를 지목하지만
105
+ 호스트가 그 형식을 안정된 인터페이스가 아니라고 밝혔으므로 어떤 판정도 그것을 읽지
106
+ 않습니다. 대신 어댑터가 `UserPromptSubmit`과 `PostToolUse`로 `session`을 만듭니다. 설정된
107
+ 토큰을 사람 메시지의 첫 줄에 단독으로 보내면 다시 시도한 보호 호출을 허용할 수 있습니다.
108
+ 사람 증거가 기록되지 않았거나 저장에 실패했다면 복구 메시지가 사용자 터미널을 안내합니다.
109
+ `actor`, `channels`, 도구 성공 여부는 합성하지 않습니다.
93
110
  - **프로젝트 밖으로 해석되는 패치는 판정하지 않고 거부합니다.** 그런 경로는 프로젝트 기준
94
111
  상대 경로가 없고, 그것을 실은 원소는 어떤 관측 범위에도 들어가지 않아 판정 없이 지나가게
95
112
  됩니다.
@@ -2,9 +2,8 @@
2
2
 
3
3
  **English** · [한국어](adapter-codex.ko.md)
4
4
 
5
- > **The Codex install unit** — `PreToolUse` payloads become the covenant input IR, with one
6
- > element per file the patch touches, and the package installs the session surface into a
7
- > project.
5
+ > **The Codex install unit** — lifecycle events become adapter-owned session evidence, and
6
+ > `PreToolUse` payloads become covenant input IR with one element per file the patch touches.
8
7
  >
9
8
  > Beta. Install it next to `polydeukes`, which it names as a `peerDependency`.
10
9
 
@@ -17,13 +16,16 @@ by design, so that they never reach the core.
17
16
  | Unit | What it does |
18
17
  |---|---|
19
18
  | `pdks-codex` bin | One subcommand, `pdks-codex init`, which registers the session surface in a project |
20
- | `runHook` | Translates one `PreToolUse` payload into the input IR and spawns the judge |
19
+ | `runHook` | Records lifecycle evidence, or translates one `PreToolUse` payload into the input IR and spawns the judge |
20
+ | Session evidence | Stores timestamped human messages and completed tool calls under a SHA-256 session filename, then removes it at `SessionEnd` |
21
21
  | Payload validation | Demands every key the host's generated schema marks required, in the one spelling that host sends |
22
22
  | Patch parsing | Turns the raw patch text of an `apply_patch` call into one file change per file it touches |
23
23
  | Path rebasing | Resolves a patch path against the call's working directory and carries it relative to the project root |
24
24
 
25
- `runHook({ repoRoot })` is what the generated hook delegator imports. It builds the IR — the
26
- `tools` roster included, with no `session` or `actor` key — then spawns
25
+ `runHook({ repoRoot })` is what the generated hook delegator imports. `UserPromptSubmit` and
26
+ `PostToolUse` append strict JSONL records under `.polydeukes/codex-sessions/`; `SessionEnd`
27
+ removes only that session's file. `PreToolUse` builds the IR with the `tools` roster and a
28
+ `session` sourced from those records, but no synthesized `actor` or `channels`, then spawns
27
29
  `pdks covenant check --enforce block` in `repoRoot` and returns the child's exit code. The
28
30
  judging happens in that child process; this package carries no judgment logic.
29
31
 
@@ -33,11 +35,11 @@ stdin, so the row that call earns is written by the one writer.
33
35
  <a id="apply-patch"></a>
34
36
  ## Why this adapter parses text where its siblings read arguments
35
37
 
36
- Codex normalises every file edit into a single tool name, `apply_patch`, and puts the patch
37
- itself in `tool_input.command` — the same field a shell call uses for its command line. There
38
- is no path argument to read. `Edit` and `Write` exist as matcher aliases you may write in
39
- `.codex/hooks.json`, but the payload always names the tool `apply_patch`, so a roster or a
40
- branch keyed on the aliases matches nothing that ever arrives.
38
+ Codex normalises every file edit that reaches the hook into a single tool name, `apply_patch`,
39
+ and puts the patch itself in `tool_input.command` — the same field a shell call uses for its
40
+ command line. There is no path argument to read. `Edit` and `Write` exist as matcher aliases
41
+ you may write in `.codex/hooks.json`, but the payload always names the tool `apply_patch`, so
42
+ a roster or a branch keyed on the aliases matches nothing that ever arrives.
41
43
 
42
44
  One patch can create, update, delete and rename files in one call. The adapter carries each as
43
45
  its own element of one IR, on one spawn: every file is judged, and any one of them blocking
@@ -55,7 +57,8 @@ npx pdks-codex init
55
57
  ```
56
58
 
57
59
  `pdks-codex init` resolves `polydeukes` from the project, spawns `pdks init` for the
58
- agent-neutral scaffold, then writes the delegator and merges its entry into
60
+ agent-neutral scaffold, then writes the delegator and merges its entries for `PreToolUse`,
61
+ `UserPromptSubmit`, `PostToolUse`, and `SessionEnd` into
59
62
  `.codex/hooks.json` non-destructively — other events, other matchers and keys it does not know
60
63
  are left alone. A re-run reports each existing artifact as skipped and overwrites nothing. The
61
64
  full artifact list is in [`pdks init`](../cli/init.md#init-codex).
@@ -77,9 +80,22 @@ by default, so the registration this installer creates is covered by the config
77
80
  <a id="limits"></a>
78
81
  ## Declared limits
79
82
 
80
- The first three are the host's own, stated in its hook documentation, and no adapter can
81
- narrow them.
82
-
83
+ The first four are the host's own, and no adapter can narrow them. The first is measured
84
+ rather than documented; the next three are stated in the host's hook documentation.
85
+
86
+ - **A Code Mode `exec` dispatch is not observed.** In codex-cli 0.154 the host does not emit
87
+ `PreToolUse` for a Code Mode `exec` call, nor for the `tools.apply_patch` and
88
+ `tools.exec_command` calls nested in its JavaScript
89
+ ([openai/codex#23411](https://github.com/openai/codex/issues/23411),
90
+ [#38850](https://github.com/openai/codex/issues/38850)). A hook that `/hooks` lists as
91
+ Active still sees nothing on that surface, and a protected path edited there leaves no
92
+ telemetry row. `pdks-codex init` prints this as a `note:` line.
93
+ - **The roster, not the matcher, decides what is judged.** The adapter translates
94
+ `apply_patch` and `Bash`; every other name — a Code Mode name, an MCP tool, `write_stdin` —
95
+ is refused with exit 2 and a `blocked` runner row before the judge runs. Widening the
96
+ matcher in `.codex/hooks.json` to such a name blocks every call under it rather than
97
+ judging it, and the edit changes the trust hash, so the hook is skipped until `/hooks`
98
+ approves it again.
83
99
  - **`write_stdin` is not judged again.** It delivers input to a unified-exec session that
84
100
  already passed `PreToolUse`. A shell left open for input is judged once, at the call that
85
101
  opened it.
@@ -87,10 +103,12 @@ narrow them.
87
103
  function-tool hooks, so they reach no covenant.
88
104
  - **The host calls its tool hooks a guardrail rather than a complete enforcement boundary.**
89
105
  Some specialized tool paths can opt out of the default hook path.
90
- - **There is no transcript channel.** The IR omits `session` and `actor`. The payload names a
91
- transcript path, but the host documents that format as unstable, so no judgment reads it —
92
- which leaves the session witness valve without the human-message evidence it needs. For an
93
- intentional blocked edit, use your own terminal.
106
+ - **The unstable transcript is not a channel.** The payload names a transcript path, but the
107
+ host documents that format as unstable, so no judgment reads it. The adapter instead builds
108
+ `session` from `UserPromptSubmit` and `PostToolUse`. A fresh configured token, alone on the
109
+ first line of a human message, can release the retried protected call. If no human evidence
110
+ was recorded, or evidence storage failed, the recovery message directs the repair to the user
111
+ terminal. `actor`, `channels`, and tool success are never synthesized.
94
112
  - **A patch resolving outside the project is refused rather than judged.** Such a path has no
95
113
  project-relative form, and an element carrying one would land in no scope — judged over
96
114
  nothing, and passed.
@@ -113,7 +113,7 @@ IR의 `session` 키는 다른 것을 말합니다. 호스트가 그 호출에
113
113
  | 등록 | 축 | 판정 대상 |
114
114
  |---|---|---|
115
115
  | self-mod | 도구 | 편집 도구를 통한 보호 경로 변형입니다. 호출의 증명된 변형 대상만 대조하므로, 편집 **내용** 안의 보호 경로는 언급이고 통과합니다 |
116
- | shell-mod | 셸 | 같은 것을 명령줄로 합니다. 보호 경로를 언급하는 명령은 첫 낱말이 읽기 전용임을 증명할 때만 통과합니다 |
116
+ | shell-mod | 셸 | 같은 것을 명령줄로 합니다. 보호 경로를 언급하는 명령은 읽기 전용임이 증명될 때만 통과합니다. 허용 목록의 첫 낱말이나, `git ls-files`·변형·실행·실행 확인·파일 출력 동작이 없는 `find`·숫자 범위 `sed -n …p`처럼 지원하는 인자 판정형 읽기 명령이 이를 증명합니다 |
117
117
  | transcript-mod | 대화 기록 | 라이브 세션 대화 기록에 대한 쓰기입니다. 전체 경로 **등가**로 판정하고 보호 조상으로는 결코 보지 않습니다 |
118
118
 
119
119
  **낱말 여섯**이 텔레메트리 계약입니다. 판정 결과 다섯과 관측 하나입니다. `.polydeukes/roi.log`의
@@ -174,7 +174,7 @@ fail-open입니다.
174
174
  - **완전 봉쇄는 목표가 아닙니다.** 여기에 차단 목록은 없습니다. 우회 철자를 열거하는 일은
175
175
  언제나 한 걸음 뒤지므로 논리를 뒤집었습니다. 보호 경로를 언급하면 안전이 증명되지 않는
176
176
  한 차단합니다. 간접 경로 계산 같은 잔여 벡터는 차단 대상이 아니라 텔레메트리 대상입니다.
177
- 마찰 밸브 둘, 곧 읽기 전용 허용 목록과 TTL 증인은 둘 다 측정 가능한 흔적을 남깁니다.
177
+ 마찰 밸브 둘, 곧 읽기 전용 증명과 TTL 증인은 둘 다 측정 가능한 흔적을 남깁니다.
178
178
  - **밸브는 판정 뒤에 확인합니다.** 실제로 차단한 판정만 증언으로 열 수 있고, 문장 중간의 토큰
179
179
  언급은 밸브를 무장시키지 않으며, AI는 자기 밸브를 결코 스스로 열 수 없습니다.
180
180
 
@@ -114,7 +114,7 @@ vocabulary below applies to them unchanged.
114
114
  | Registration | Axis | Judges |
115
115
  |---|---|---|
116
116
  | self-mod | Tool | Mutations to protected paths through editing tools. Only the call's proven mutation target is compared — a protected path inside an edit's *content* is a mention and passes |
117
- | shell-mod | Shell | The same, through a command line. A command mentioning a protected path passes only if its leading word proves it read-only |
117
+ | shell-mod | Shell | The same, through a command line. A command mentioning a protected path passes only with read-only proof: an allowlisted leading word, or a supported argument-sensitive reader such as `git ls-files`, `find` without mutation, execution, prompting, or file-output actions, or numeric-range `sed -n …p` |
118
118
  | transcript-mod | Transcript | Writes to the live session transcript, judged by whole-path **equality** — never as a protected ancestor |
119
119
 
120
120
  **Six words** are the telemetry contract — five verdicts and one observation. A row in
@@ -179,8 +179,8 @@ No import. The umbrella assembles the module for both surfaces.
179
179
  - **Complete containment is a non-goal.** There are no blocklists here — enumerating bypass
180
180
  spellings is always one step behind, so the logic is inverted: a mention of a protected
181
181
  path blocks unless proven safe. Residual vectors such as indirect path computation are
182
- telemetry targets, not block targets. The two friction valves — the read-only allowlist
183
- and the TTL witness — both leave a measurable trace.
182
+ telemetry targets, not block targets. The two friction valves — read-only proof and the TTL
183
+ witness — both leave a measurable trace.
184
184
  - **The valve stands after the verdict.** Only a judgment that actually blocked can be
185
185
  witnessed open, a mid-sentence mention of the token does not arm it, and an AI can never
186
186
  open the valve for itself.
@@ -67,11 +67,15 @@ Git에서 원래 파일을 복원하세요. 새 프로젝트라면 `pdks init`,
67
67
  바뀌면 `/hooks`에서 승인하기 전까지 신뢰하지 않으므로, 설치기가 성공해도 실행되는 훅이
68
68
  없을 수 있습니다. 실제 도구를 호출하고 텔레메트리를 확인하세요.
69
69
  - Codex는 대화 기록 경로를 알려 주지만 그 형식을 안정된 것으로 문서화하지 않으므로 어떤
70
- 판정도 읽지 않고, IR은 `session`과 `actor`를 생략합니다. 따라서 세션 증인(witness)
71
- 밸브가 쓸 인간 메시지 증거가 없으며, 훅을 다시 승인해도 이 기능이 생기지는 않습니다.
72
- 복구가 필요하면 본인의 터미널에서 작업하세요.
73
-
74
- 커밋 증인은 차단된 Codex 도구 호출도 허용하지 않습니다.
70
+ 판정도 읽지 않습니다. 대신 어댑터가 `UserPromptSubmit`과 `PostToolUse`를 자기 세션 증거
71
+ 파일에 기록하고 `SessionEnd`에서 지웁니다. IR은 이 `session`을 싣되 `actor`를 합성하지
72
+ 않습니다.
73
+ - 의도한 차단 뒤에는 설정된 증인 토큰을 첫 줄에 단독으로 보내고 다시 시도합니다. stderr가
74
+ `UserPromptSubmit` 증거가 없다고 알리면 생명주기 항목 넷이 모두 승인됐는지 확인합니다.
75
+ 그래도 증거가 없다면 토큰을 반복해도 관측되지 않은 호출을 풀 수 없으므로 본인의 터미널에서
76
+ 작업합니다.
77
+
78
+ 커밋 증인은 스테이징 검사만 허용하며 Codex 세션 증인을 대신하지 않습니다.
75
79
 
76
80
  <a id="config-fault"></a>
77
81
  ## 선언을 판정으로 구성하지 못할 때
@@ -65,12 +65,16 @@ The same two problems are distinct here, and the first has its own cause:
65
65
  - After `pdks-codex init`, hook trust is bound to the hash of the hook definition. A changed
66
66
  `.codex/hooks.json` is not trusted until you approve it through `/hooks`, so an installer that
67
67
  succeeded can still leave no hook running. Verify an actual call and its telemetry.
68
- - Codex names a transcript path but documents the format as unstable, so no judgment reads it
69
- and the IR omits `session` and `actor`. The session witness valve therefore has no
70
- human-message evidence to work from, and approving the hook again does not add that
71
- capability. Perform a necessary repair from your own terminal.
72
-
73
- A commit witness cannot release a blocked Codex tool call either.
68
+ - Codex names a transcript path but documents the format as unstable, so no judgment reads it.
69
+ The adapter records `UserPromptSubmit` and `PostToolUse` into its own session evidence file
70
+ and removes it at `SessionEnd`; the IR carries that `session` without synthesizing `actor`.
71
+ - After an intentional block, send the configured witness token alone on the first line and
72
+ retry. If stderr says no `UserPromptSubmit` evidence was recorded, confirm all four lifecycle
73
+ entries are approved. If evidence is still unavailable, perform the repair from your own
74
+ terminal; repeating the token cannot release an unobserved call.
75
+
76
+ A commit witness authorizes only its staged check; it does not substitute for the Codex session
77
+ witness.
74
78
 
75
79
  <a id="config-fault"></a>
76
80
  ## Config-fault
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polydeukes",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "A development discipline framework for building alongside an AI coding partner — deterministic covenants, a verifiable work ledger, local memory, and adversarial verification. Beta.",
5
5
  "author": "huskyhoochu <dfg1499@gmail.com>",
6
6
  "keywords": [
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "yaml": "2.9.0",
47
- "@polydeukes/core": "^0.8.0"
47
+ "@polydeukes/core": "^0.9.0"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/node": "^24.0.0",