@scotthuang/agent-knock-knock 0.13.17 → 0.14.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 (291) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/CONTRIBUTING.md +212 -0
  3. package/README.md +105 -166
  4. package/connectors/deepseek-harness/LICENSE +21 -0
  5. package/connectors/deepseek-harness/README.md +406 -0
  6. package/connectors/pi/LICENSE +21 -0
  7. package/connectors/pi/README.md +446 -0
  8. package/dist/src/backend-recovery-semantic.d.ts +16 -0
  9. package/dist/src/backend-recovery-semantic.js +113 -0
  10. package/dist/src/backend-recovery-semantic.js.map +1 -0
  11. package/dist/src/backend-task-recovery.d.ts +103 -0
  12. package/dist/src/backend-task-recovery.js +142 -0
  13. package/dist/src/backend-task-recovery.js.map +1 -0
  14. package/dist/src/callback-transport.d.ts +8 -0
  15. package/dist/src/callback-transport.js +14 -0
  16. package/dist/src/callback-transport.js.map +1 -1
  17. package/dist/src/cli-core.js +18 -8
  18. package/dist/src/cli-core.js.map +1 -1
  19. package/dist/src/cli-runtime-context.d.ts +5 -0
  20. package/dist/src/cli-runtime-context.js.map +1 -1
  21. package/dist/src/codex-async-question-adapter.js +14 -4
  22. package/dist/src/codex-async-question-adapter.js.map +1 -1
  23. package/dist/src/codex-lifecycle-compatibility.d.ts +1 -1
  24. package/dist/src/codex-lifecycle-compatibility.js +9 -3
  25. package/dist/src/codex-lifecycle-compatibility.js.map +1 -1
  26. package/dist/src/codex-native-cli-adapter.d.ts +6 -0
  27. package/dist/src/codex-native-cli-adapter.js +273 -0
  28. package/dist/src/codex-native-cli-adapter.js.map +1 -0
  29. package/dist/src/codex-native-client-interactions.d.ts +6 -0
  30. package/dist/src/codex-native-client-interactions.js +124 -0
  31. package/dist/src/codex-native-client-interactions.js.map +1 -0
  32. package/dist/src/codex-native-client-rpc.d.ts +21 -0
  33. package/dist/src/codex-native-client-rpc.js +137 -0
  34. package/dist/src/codex-native-client-rpc.js.map +1 -0
  35. package/dist/src/codex-native-client.d.ts +42 -0
  36. package/dist/src/codex-native-client.js +326 -0
  37. package/dist/src/codex-native-client.js.map +1 -0
  38. package/dist/src/codex-native-identity.d.ts +6 -0
  39. package/dist/src/codex-native-identity.js +42 -0
  40. package/dist/src/codex-native-identity.js.map +1 -0
  41. package/dist/src/codex-native-monitor.d.ts +4 -0
  42. package/dist/src/codex-native-monitor.js +92 -0
  43. package/dist/src/codex-native-monitor.js.map +1 -0
  44. package/dist/src/codex-native-outbox.d.ts +16 -0
  45. package/dist/src/codex-native-outbox.js +120 -0
  46. package/dist/src/codex-native-outbox.js.map +1 -0
  47. package/dist/src/codex-native-public-projection.d.ts +545 -0
  48. package/dist/src/codex-native-public-projection.js +182 -0
  49. package/dist/src/codex-native-public-projection.js.map +1 -0
  50. package/dist/src/codex-native-record-store.d.ts +27 -0
  51. package/dist/src/codex-native-record-store.js +111 -0
  52. package/dist/src/codex-native-record-store.js.map +1 -0
  53. package/dist/src/codex-native-response-service.d.ts +69 -0
  54. package/dist/src/codex-native-response-service.js +244 -0
  55. package/dist/src/codex-native-response-service.js.map +1 -0
  56. package/dist/src/codex-native-runtime.d.ts +46 -0
  57. package/dist/src/codex-native-runtime.js +112 -0
  58. package/dist/src/codex-native-runtime.js.map +1 -0
  59. package/dist/src/codex-native-semantic.d.ts +17 -0
  60. package/dist/src/codex-native-semantic.js +175 -0
  61. package/dist/src/codex-native-semantic.js.map +1 -0
  62. package/dist/src/codex-native-snapshot.d.ts +19 -0
  63. package/dist/src/codex-native-snapshot.js +160 -0
  64. package/dist/src/codex-native-snapshot.js.map +1 -0
  65. package/dist/src/codex-native-state-store.d.ts +61 -0
  66. package/dist/src/codex-native-state-store.js +132 -0
  67. package/dist/src/codex-native-state-store.js.map +1 -0
  68. package/dist/src/codex-native-task-service.d.ts +71 -0
  69. package/dist/src/codex-native-task-service.js +502 -0
  70. package/dist/src/codex-native-task-service.js.map +1 -0
  71. package/dist/src/codex-native-types.d.ts +92 -0
  72. package/dist/src/codex-native-types.js +15 -0
  73. package/dist/src/codex-native-types.js.map +1 -0
  74. package/dist/src/codex-permission-surface.d.ts +1 -1
  75. package/dist/src/codex-permission-surface.js +1 -1
  76. package/dist/src/codex-permission-surface.js.map +1 -1
  77. package/dist/src/codex-terminal-agent-adapter.js +3 -1
  78. package/dist/src/codex-terminal-agent-adapter.js.map +1 -1
  79. package/dist/src/conversation-list.d.ts +12 -0
  80. package/dist/src/conversation-list.js +30 -0
  81. package/dist/src/conversation-list.js.map +1 -0
  82. package/dist/src/conversation-route-dispatch.d.ts +13 -0
  83. package/dist/src/conversation-route-dispatch.js +66 -0
  84. package/dist/src/conversation-route-dispatch.js.map +1 -0
  85. package/dist/src/conversation-route-legacy.d.ts +18 -0
  86. package/dist/src/conversation-route-legacy.js +54 -0
  87. package/dist/src/conversation-route-legacy.js.map +1 -0
  88. package/dist/src/conversation-route-store.d.ts +51 -0
  89. package/dist/src/conversation-route-store.js +126 -0
  90. package/dist/src/conversation-route-store.js.map +1 -0
  91. package/dist/src/conversation-routing-cli-adapter.d.ts +12 -0
  92. package/dist/src/conversation-routing-cli-adapter.js +211 -0
  93. package/dist/src/conversation-routing-cli-adapter.js.map +1 -0
  94. package/dist/src/conversation-routing-commands.d.ts +11 -0
  95. package/dist/src/conversation-routing-commands.js +85 -0
  96. package/dist/src/conversation-routing-commands.js.map +1 -0
  97. package/dist/src/conversation-routing-home.d.ts +26 -0
  98. package/dist/src/conversation-routing-home.js +105 -0
  99. package/dist/src/conversation-routing-home.js.map +1 -0
  100. package/dist/src/conversation-routing-identity.d.ts +40 -0
  101. package/dist/src/conversation-routing-identity.js +174 -0
  102. package/dist/src/conversation-routing-identity.js.map +1 -0
  103. package/dist/src/conversation-runtime-route-store.d.ts +11 -0
  104. package/dist/src/conversation-runtime-route-store.js +118 -0
  105. package/dist/src/conversation-runtime-route-store.js.map +1 -0
  106. package/dist/src/desktop-async-interactions.d.ts +15 -0
  107. package/dist/src/desktop-async-interactions.js +88 -0
  108. package/dist/src/desktop-async-interactions.js.map +1 -0
  109. package/dist/src/desktop-async-state.d.ts +5 -0
  110. package/dist/src/desktop-async-state.js +53 -0
  111. package/dist/src/desktop-async-state.js.map +1 -0
  112. package/dist/src/desktop-cli-adapter.d.ts +7 -0
  113. package/dist/src/desktop-cli-adapter.js +322 -0
  114. package/dist/src/desktop-cli-adapter.js.map +1 -0
  115. package/dist/src/desktop-cli-controls.d.ts +9 -0
  116. package/dist/src/desktop-cli-controls.js +45 -0
  117. package/dist/src/desktop-cli-controls.js.map +1 -0
  118. package/dist/src/desktop-command-presentation.d.ts +2 -0
  119. package/dist/src/desktop-command-presentation.js +31 -0
  120. package/dist/src/desktop-command-presentation.js.map +1 -0
  121. package/dist/src/desktop-control-semantic.d.ts +8 -0
  122. package/dist/src/desktop-control-semantic.js +68 -0
  123. package/dist/src/desktop-control-semantic.js.map +1 -0
  124. package/dist/src/desktop-identity.d.ts +5 -0
  125. package/dist/src/desktop-identity.js +40 -0
  126. package/dist/src/desktop-identity.js.map +1 -0
  127. package/dist/src/desktop-interaction-projection.d.ts +57 -0
  128. package/dist/src/desktop-interaction-projection.js +196 -0
  129. package/dist/src/desktop-interaction-projection.js.map +1 -0
  130. package/dist/src/desktop-interaction-state.d.ts +3 -0
  131. package/dist/src/desktop-interaction-state.js +48 -0
  132. package/dist/src/desktop-interaction-state.js.map +1 -0
  133. package/dist/src/desktop-ipc-async-answer.d.ts +9 -0
  134. package/dist/src/desktop-ipc-async-answer.js +71 -0
  135. package/dist/src/desktop-ipc-async-answer.js.map +1 -0
  136. package/dist/src/desktop-ipc-client.d.ts +47 -0
  137. package/dist/src/desktop-ipc-client.js +400 -0
  138. package/dist/src/desktop-ipc-client.js.map +1 -0
  139. package/dist/src/desktop-ipc-native-operations.d.ts +11 -0
  140. package/dist/src/desktop-ipc-native-operations.js +126 -0
  141. package/dist/src/desktop-ipc-native-operations.js.map +1 -0
  142. package/dist/src/desktop-ipc-transport.d.ts +13 -0
  143. package/dist/src/desktop-ipc-transport.js +123 -0
  144. package/dist/src/desktop-ipc-transport.js.map +1 -0
  145. package/dist/src/desktop-list.d.ts +25 -0
  146. package/dist/src/desktop-list.js +55 -0
  147. package/dist/src/desktop-list.js.map +1 -0
  148. package/dist/src/desktop-metadata-reader.d.ts +30 -0
  149. package/dist/src/desktop-metadata-reader.js +182 -0
  150. package/dist/src/desktop-metadata-reader.js.map +1 -0
  151. package/dist/src/desktop-monitor.d.ts +4 -0
  152. package/dist/src/desktop-monitor.js +101 -0
  153. package/dist/src/desktop-monitor.js.map +1 -0
  154. package/dist/src/desktop-public-projection.d.ts +6 -0
  155. package/dist/src/desktop-public-projection.js +134 -0
  156. package/dist/src/desktop-public-projection.js.map +1 -0
  157. package/dist/src/desktop-request-interactions.d.ts +14 -0
  158. package/dist/src/desktop-request-interactions.js +144 -0
  159. package/dist/src/desktop-request-interactions.js.map +1 -0
  160. package/dist/src/desktop-response-dispatch.d.ts +14 -0
  161. package/dist/src/desktop-response-dispatch.js +19 -0
  162. package/dist/src/desktop-response-dispatch.js.map +1 -0
  163. package/dist/src/desktop-response-evidence.d.ts +4 -0
  164. package/dist/src/desktop-response-evidence.js +19 -0
  165. package/dist/src/desktop-response-evidence.js.map +1 -0
  166. package/dist/src/desktop-response-service.d.ts +11 -0
  167. package/dist/src/desktop-response-service.js +188 -0
  168. package/dist/src/desktop-response-service.js.map +1 -0
  169. package/dist/src/desktop-response-store.d.ts +35 -0
  170. package/dist/src/desktop-response-store.js +58 -0
  171. package/dist/src/desktop-response-store.js.map +1 -0
  172. package/dist/src/desktop-response-types.d.ts +20 -0
  173. package/dist/src/desktop-response-types.js +2 -0
  174. package/dist/src/desktop-response-types.js.map +1 -0
  175. package/dist/src/desktop-response-value.d.ts +6 -0
  176. package/dist/src/desktop-response-value.js +31 -0
  177. package/dist/src/desktop-response-value.js.map +1 -0
  178. package/dist/src/desktop-runtime.d.ts +153 -0
  179. package/dist/src/desktop-runtime.js +88 -0
  180. package/dist/src/desktop-runtime.js.map +1 -0
  181. package/dist/src/desktop-semantic.d.ts +21 -0
  182. package/dist/src/desktop-semantic.js +140 -0
  183. package/dist/src/desktop-semantic.js.map +1 -0
  184. package/dist/src/desktop-session-catalog.d.ts +68 -0
  185. package/dist/src/desktop-session-catalog.js +225 -0
  186. package/dist/src/desktop-session-catalog.js.map +1 -0
  187. package/dist/src/desktop-session-controls.d.ts +145 -0
  188. package/dist/src/desktop-session-controls.js +176 -0
  189. package/dist/src/desktop-session-controls.js.map +1 -0
  190. package/dist/src/desktop-sidebar-metadata.d.ts +27 -0
  191. package/dist/src/desktop-sidebar-metadata.js +83 -0
  192. package/dist/src/desktop-sidebar-metadata.js.map +1 -0
  193. package/dist/src/desktop-sidebar-projects.d.ts +10 -0
  194. package/dist/src/desktop-sidebar-projects.js +31 -0
  195. package/dist/src/desktop-sidebar-projects.js.map +1 -0
  196. package/dist/src/desktop-sidebar-selection.d.ts +28 -0
  197. package/dist/src/desktop-sidebar-selection.js +85 -0
  198. package/dist/src/desktop-sidebar-selection.js.map +1 -0
  199. package/dist/src/desktop-snapshot-details.d.ts +4 -0
  200. package/dist/src/desktop-snapshot-details.js +116 -0
  201. package/dist/src/desktop-snapshot-details.js.map +1 -0
  202. package/dist/src/desktop-snapshot.d.ts +11 -0
  203. package/dist/src/desktop-snapshot.js +276 -0
  204. package/dist/src/desktop-snapshot.js.map +1 -0
  205. package/dist/src/desktop-state-store.d.ts +72 -0
  206. package/dist/src/desktop-state-store.js +269 -0
  207. package/dist/src/desktop-state-store.js.map +1 -0
  208. package/dist/src/desktop-task-interactions.d.ts +10 -0
  209. package/dist/src/desktop-task-interactions.js +93 -0
  210. package/dist/src/desktop-task-interactions.js.map +1 -0
  211. package/dist/src/desktop-task-recovery.d.ts +38 -0
  212. package/dist/src/desktop-task-recovery.js +171 -0
  213. package/dist/src/desktop-task-recovery.js.map +1 -0
  214. package/dist/src/desktop-task-service.d.ts +54 -0
  215. package/dist/src/desktop-task-service.js +441 -0
  216. package/dist/src/desktop-task-service.js.map +1 -0
  217. package/dist/src/desktop-types.d.ts +281 -0
  218. package/dist/src/desktop-types.js +13 -0
  219. package/dist/src/desktop-types.js.map +1 -0
  220. package/dist/src/host-monitor-reconciliation.js +36 -4
  221. package/dist/src/host-monitor-reconciliation.js.map +1 -1
  222. package/dist/src/host-profile-runtime.js +7 -3
  223. package/dist/src/host-profile-runtime.js.map +1 -1
  224. package/dist/src/local-codex-cli-adapter.d.ts +7 -0
  225. package/dist/src/local-codex-cli-adapter.js +13 -0
  226. package/dist/src/local-codex-cli-adapter.js.map +1 -0
  227. package/dist/src/openclaw-callback-transport.js +2 -1
  228. package/dist/src/openclaw-callback-transport.js.map +1 -1
  229. package/dist/src/semantic-conversation-target.d.ts +4 -0
  230. package/dist/src/semantic-conversation-target.js +20 -0
  231. package/dist/src/semantic-conversation-target.js.map +1 -0
  232. package/dist/src/semantic-permission-control.js +47 -9
  233. package/dist/src/semantic-permission-control.js.map +1 -1
  234. package/dist/src/semantic-private-authority-offers.d.ts +1 -1
  235. package/dist/src/semantic-private-authority-offers.js +3 -1
  236. package/dist/src/semantic-private-authority-offers.js.map +1 -1
  237. package/dist/src/semantic-tool-command-helpers.d.ts +6 -0
  238. package/dist/src/semantic-tool-command-helpers.js +199 -78
  239. package/dist/src/semantic-tool-command-helpers.js.map +1 -1
  240. package/dist/src/semantic-tool-descriptions.d.ts +2 -1
  241. package/dist/src/semantic-tool-descriptions.js +81 -35
  242. package/dist/src/semantic-tool-descriptions.js.map +1 -1
  243. package/dist/src/semantic-tool-list-projection.js +66 -2
  244. package/dist/src/semantic-tool-list-projection.js.map +1 -1
  245. package/dist/src/semantic-tool-presentation.js +76 -7
  246. package/dist/src/semantic-tool-presentation.js.map +1 -1
  247. package/dist/src/semantic-tool-runtime.js +129 -29
  248. package/dist/src/semantic-tool-runtime.js.map +1 -1
  249. package/dist/src/semantic-tool-schemas.d.ts +410 -27
  250. package/dist/src/semantic-tool-schemas.js +176 -88
  251. package/dist/src/semantic-tool-schemas.js.map +1 -1
  252. package/dist/src/terminal-action-contracts.js +10 -6
  253. package/dist/src/terminal-action-contracts.js.map +1 -1
  254. package/dist/src/terminal-list-cli-adapter.d.ts +1 -0
  255. package/dist/src/terminal-list-cli-adapter.js +6 -3
  256. package/dist/src/terminal-list-cli-adapter.js.map +1 -1
  257. package/dist/src/terminal-model-control-profile.d.ts +3 -1
  258. package/dist/src/terminal-model-control-profile.js +15 -7
  259. package/dist/src/terminal-model-control-profile.js.map +1 -1
  260. package/dist/src/terminal-monitor-decision-policy.d.ts +1 -1
  261. package/dist/src/terminal-native-inspection-profile.js +4 -0
  262. package/dist/src/terminal-native-inspection-profile.js.map +1 -1
  263. package/dist/src/terminal-permission-control-list-projection.d.ts +1 -1
  264. package/dist/src/terminal-permission-control.js +5 -1
  265. package/dist/src/terminal-permission-control.js.map +1 -1
  266. package/dist/src/terminal-questionnaire-adapter.js +5 -2
  267. package/dist/src/terminal-questionnaire-adapter.js.map +1 -1
  268. package/dist/src/terminal-user-send-intent.d.ts +2 -0
  269. package/dist/src/terminal-user-send-intent.js +11 -3
  270. package/dist/src/terminal-user-send-intent.js.map +1 -1
  271. package/docs/architecture/current-architecture.md +313 -0
  272. package/docs/architecture/interactive-terminal-response.md +276 -0
  273. package/docs/architecture/issue-126-final-report.md +248 -0
  274. package/docs/architecture/orchestration-refactor-history.md +2987 -0
  275. package/docs/architecture/orchestration-refactor.md +21 -0
  276. package/docs/backend-task-recovery.md +89 -0
  277. package/docs/bidirectional-agent-protocol.md +260 -0
  278. package/docs/codex-0.160.0-compatibility.md +126 -0
  279. package/docs/codex-cli-native-compatibility.md +246 -0
  280. package/docs/codex-desktop-compatibility.md +414 -0
  281. package/docs/codex-permissions.md +12 -1
  282. package/docs/openclaw-operations.md +281 -0
  283. package/docs/openclaw-session-turn-delivery-requirement.md +45 -0
  284. package/docs/operator-guide.md +543 -0
  285. package/docs/storage-and-logging.md +91 -0
  286. package/docs/test-performance-issue-108.md +80 -0
  287. package/docs/test-performance-issue-120.md +226 -0
  288. package/docs/testing.md +628 -0
  289. package/openclaw.plugin.json +7 -3
  290. package/package.json +6 -12
  291. package/templates/openclaw-skills/agent-knock-knock/SKILL.md +69 -18
@@ -0,0 +1,21 @@
1
+ # Orchestration architecture documents
2
+
3
+ This path is a stable index. It intentionally contains no current tool count,
4
+ Store protocol number, action-contract version, or module-size snapshot.
5
+
6
+ Use these documents according to purpose:
7
+
8
+ - [Current architecture and health budget](./current-architecture.md) is the
9
+ only authoritative description of the source tree and public surface now.
10
+ - [Issue #126 orchestration refactor history](./orchestration-refactor-history.md)
11
+ is an immutable chronological record of the v0.12 refactor baseline, phase
12
+ reports, and later issue addenda. Numbers such as 14 or 16 tools, Watch v2,
13
+ and writer protocol 6 describe their explicitly dated historical snapshot;
14
+ they are not current product documentation.
15
+ - [Issue #126 final report](./issue-126-final-report.md) records that refactor's
16
+ closeout evidence.
17
+ - [Interactive terminal response](./interactive-terminal-response.md) describes
18
+ the dedicated questionnaire-response architecture.
19
+
20
+ For operator workflows and the current semantic-tool surface, use the
21
+ [operator guide](../operator-guide.md) and the canonical packaged Skill.
@@ -0,0 +1,89 @@
1
+ # Backend task recovery
2
+
3
+ AKK 0.14.0 introduces exact-task recovery for its backend adapters. See the
4
+ [README](../README.md) for installation and the first-task workflow.
5
+
6
+ Codex CLI direct connections and Codex Desktop use persisted exact task identities
7
+ for recovery. These operations do not require tmux or Herdr and do not send task
8
+ text, slash commands, approvals, cancellation, or lifecycle commands to Codex.
9
+
10
+ ## Management and observation
11
+
12
+ A backend Send creates a managed task with automatic observation. Its response
13
+ includes `turn_id` and `watch_id` identifying that same stored record. A standalone
14
+ Watch observes an existing task and does not acquire Send management. Inspect
15
+ `task_kind`, `management_state`, and `observation_state` separately.
16
+
17
+ | Operation | Meaning |
18
+ | --- | --- |
19
+ | `unwatch({watch_id})` | Stop observation and withdraw notifications not yet dispatched. A managed Send stays managed. |
20
+ | `close({turn_id})` | Close a managed Send, stop observation, and release its AKK management. A standalone Watch must use Unwatch. |
21
+ | `renew({watch_id, minutes})` | Verify the original task and extend observation; an expired or explicitly stopped Watch can resume while that same task is still active. |
22
+ | `recover({watch_id})` | Reconnect/read the original task, reconcile its receipt and state, and supervise eligible monitor work. Does not extend the deadline or resume an explicitly stopped Watch. |
23
+ | `retry_callback({watch_id, notification_id})` | Retry one persisted notification with its original event ID and controller target. Does not rerun the task. |
24
+
25
+ The tool prefix is `agent_knock_knock_`. Native Send `turn_id` is also accepted
26
+ by Recover, Renew, Close, Retry Callback, and Status. Unwatch uses `watch_id`.
27
+ Copy the exact IDs and available actions
28
+ from Send, List or Status. A conversation ID alone cannot select a task to close,
29
+ renew, recover, or retry. Multiple eligible failed notifications require an
30
+ explicit `notification_id`.
31
+
32
+ Closed management cannot be reopened. Unwatch does not release an unresolved
33
+ Send reservation; Close explicitly releases management without asserting that
34
+ the native submission failed. Reusing the original Send message ID still returns
35
+ its original record and never resends its text. None of these operations cancels
36
+ the actual Codex task or closes its conversation.
37
+
38
+ ## Identity and outcomes
39
+
40
+ Close and Unwatch update the saved AKK record and do not require reconnecting
41
+ to Codex. Recover and Renew read the original native task. Retry Callback reuses
42
+ the saved notification; an interaction notification additionally requires fresh
43
+ confirmation that its original question or approval is still pending. These
44
+ different checks do not rediscover or select another task.
45
+
46
+ Recovery uses the saved Codex home, thread, native turn, original submission
47
+ receipt and client message identity. It never substitutes the latest task, a
48
+ matching project directory, or another terminal. If the original task cannot be
49
+ verified, it remains unknown rather than being rebound. Renewal requires exact
50
+ task evidence; if that task has already settled, its actual outcome is recorded
51
+ instead of declaring it running. Each new observation deadline has its own
52
+ timeout notification generation; old unsent expiry notices are withdrawn.
53
+
54
+ Manual callback retry accepts only a recorded `retryable_failure`, including a
55
+ failure whose automatic attempts were exhausted. It preserves the notification
56
+ body, destination, event ID and cumulative attempt history. It cannot replay an
57
+ accepted notification, an in-flight attempt, an uncertain result, or a withdrawn
58
+ or obsolete interaction. Interaction notifications require fresh evidence that
59
+ the same question or approval is still pending. A closed or unwatched record
60
+ cannot dispatch callbacks. Already in-flight notifications cannot be recalled;
61
+ their eventual acknowledgement remains visible.
62
+
63
+ Callback acceptance means that the controller accepted the notification. It
64
+ does not prove that a downstream channel, such as WeChat, delivered a user-visible
65
+ message. Retry Callback is not a repair for a controller-to-channel failure.
66
+
67
+ ## Terminal recovery remains separate
68
+
69
+ Existing terminal `reconcile_binding`, `identify_foreground`, and
70
+ `repair_model_control` repair or inspect a physical terminal binding or menu.
71
+ They retain their terminal requirements. Backend `recover` reconciles an exact
72
+ stored task; it does not detach a terminal binding or manufacture new authority.
73
+ Native conversation creation, clearing, restoration, model controls, and
74
+ cancellation retain their separately documented provider capabilities.
75
+
76
+ ## Validation boundary
77
+
78
+ The backend recovery paths are covered by the fast regression tier, including
79
+ ownership, exact task retention, expired/stopped observation, duplicate and
80
+ uncertain sends, callback leases and retry identity. This change does not itself
81
+ establish a new live Desktop/CLI or user-visible channel delivery result. Existing
82
+ user sessions and historical notifications must not be used as implicit tests.
83
+
84
+ Development validation on 2026-10-10: `npm run test:fast` passed all 2,788 tests
85
+ and its build/Skill synchronization gates. `npm run validate:architecture` and
86
+ `npm run validate:refactor-evidence` also passed. Full, integration and release
87
+ tiers were not run during that development check, in accordance with the
88
+ repository test policy. This records development evidence, not the separate
89
+ publication gate.
@@ -0,0 +1,260 @@
1
+ # Terminal Handoff Protocol
2
+
3
+ Agent Knock Knock coordinates a controller Host, a local coding agent, and a human through one visible tmux or Herdr terminal.
4
+
5
+ - OpenClaw, Pi, DeepSeek Harness, or another compatible Host is the orchestrator, requirements owner, and final acceptance decision maker.
6
+ - Codex or Claude Code performs the engineering work inside tmux or Herdr.
7
+ - AKK owns terminal delivery, monitoring, lifecycle state, and callbacks.
8
+ - A human can attach to the same terminal at any time, continue directly, and later hand control back to the Host.
9
+ - AKK sends input only after it verifies the selected agent, pane, process, pane/process working directory, approval state, and action-specific composer. Managed paths require idle; an advertised user-explicit physical Send may steer a working mutable composer.
10
+ - AKK labels the evidence behind every notification. Managed Turns and exact-task Watches report completion only from correlated evidence; a user-selected terminal-activity Watch may instead report a clearly marked best-effort stable-idle observation that is not exact task-completion proof.
11
+
12
+ ## Identity Model
13
+
14
+ AKK models shared work as:
15
+
16
+ ```text
17
+ tmux or Herdr terminal / verified process incarnation
18
+ ├─ native Codex or Claude Code session
19
+ │ └─ AKK session (session_id)
20
+ │ ├─ Turn (turn_id)
21
+ │ └─ Turn (turn_id)
22
+ └─ Terminal Watch schema v3 (watch_id + exact task anchor or terminal-activity epoch)
23
+ ```
24
+
25
+ - The terminal is the physical pane and coding-agent process incarnation.
26
+ - The native session is the continuing context owned by Codex or Claude Code.
27
+ - The AKK `session_id` identifies a continuing context and is the strict `session_exact` send target. The physical `terminal_id` is the separate `terminal_follow_current` or user-priority `terminal_user_explicit` send target, exactly as advertised.
28
+ - A `turn_id` identifies exactly one accepted dispatch through its final monitor and callback state.
29
+ - A `watch_id` identifies an independent observation aggregate for a user-selected exact terminal. It prefers one provider-correlated task, may fall back to that terminal/process activity epoch, and may also identify one exact request already delivered through user-explicit unmanaged fallback. It is never a Session, Turn, dispatch receipt, or terminal owner. A new exact Watch may hold a narrowly scoped native-interaction response lease, but only after same-controller Status and fresh exact terminal/native-task revalidation; activity Watches never receive such authority.
30
+ - A terminal binding generation identifies one verified terminal-to-native-thread attachment. Native lifecycle transitions advance it even though they create no Turn.
31
+
32
+ List and Status preserve three independent evidence axes. `screen_state`
33
+ classifies the bounded live TUI, `native_identity_state` reports whether the
34
+ foreground native session is resolved, ambiguous, verified absent, or
35
+ unavailable, and `durable_activity_state` reports exact artifact-backed task
36
+ activity when available. The legacy `activity_state` remains conservative for
37
+ compatibility; it can be `unknown` while the screen is visibly idle because
38
+ native identity or durable activity is ambiguous. These axes are diagnostic
39
+ and never replace a current `available_actions` entry as mutation authority.
40
+
41
+ Human-friendly selectors such as `only`, `codex`, `claude`, and `@short-ref` remain slash-command discovery inputs. The v30 structured model contract carries semantic IDs only and does not expose selectors or opaque authority values. Its core shapes are `send({session_id|terminal_id,request})` with mutually exclusive targets, `watch({terminal_id})`, `model_options({terminal_id})`, the separately advertised Codex-only `repair_model_control({terminal_id})`, followed by `set_model({terminal_id,model,reasoning_effort})`, `native_inspect({terminal_id,inspection})`, `identify_foreground({terminal_id})`, `identify_and_send({terminal_id,request})`, `new_thread({terminal_id})`, `resume_thread({terminal_id,native_thread_id})`, `respond_interaction({turn_id|watch_id,interaction_id,answers,delivery_mode?})` with exactly one subject target and `delivery_mode` present only for an `async_question`, managed `approve({turn_id,decision})` or approve-once-only terminal-scoped `approve({terminal_id})`, and `reconcile_binding({terminal_id,conflicting_session_id})`. Model selection, model-control residue repair, approval, native interaction response, handoff takeover, and reconciliation require explicit user intent and fresh source state. The trusted plugin/CLI privately derives and revalidates terminal, catalog, binding, candidate, prompt, interaction, composer, handoff, revision, and compare-and-swap fences; the model never transports them. Store format remains 1 and writer protocol is 8; Terminal Watch schema is 3.
42
+
43
+ ## Managed Turn Flow
44
+
45
+ This flow describes managed Session/Turn delivery. Codex 0.158.0/0.159.0/0.159.2 physical Send
46
+ uses an independent exact paginated task Watch and returns `watch_id` without
47
+ creating a managed `turn_id`. Its foreground binding, native answer receipts,
48
+ and session-only/new/resume and first-modal limits are described in the
49
+ [0.158.0/0.159.0/0.159.2 compatibility review](codex-0.159.2-compatibility.md).
50
+
51
+ 1. The controller Host calls ordinary send using the exact current listed action and the user-facing request. `session_exact` carries `session_id`; `terminal_follow_current` and `terminal_user_explicit` carry `terminal_id`. Both target fields may be omitted only when AKK must prove one unique send-ready pane. Initial discovery may first resolve one eligible Codex or Claude Code terminal into an AKK session.
52
+ 2. AKK verifies that the session is bound to the expected native session, terminal, and idle coding-agent process.
53
+ 3. AKK creates a unique `turn_id`, writes the request to the verified idle pane, and starts a monitor bound to that Turn, pane, process, and message.
54
+ 4. The coding agent works in the same terminal that the human can inspect or take over.
55
+ 5. AKK sends a structured callback containing both `session_id` and `turn_id` to the originating Host session when it has reliable approval, completion, cancellation, stall, or failure evidence.
56
+ 6. After completion, refresh the terminal list. Another ordinary send through that row's current exact action creates a new Turn without clearing the native coding-agent context.
57
+
58
+ Steps 2–6 describe managed delivery, which may require an exact empty Composer before input. For an advertised `terminal_user_explicit` Send, the selected live terminal/process and direct input-safety checks authorize the one physical Send; rollout, Session, Store, and callback state are sidecar management evidence rather than vetoes. Parsed working activity, an existing draft, and ordinary main-Composer visibility do not veto this user-priority path, but a blocked native approval or a proven input-owning questionnaire, editor, menu, or read-only viewer remains a zero-input boundary. Profiled Codex 0.154.0/0.155.1 exact collapsed async-question summaries remain sendable because the main Composer owns input; their expanded, clipped, or ambiguous async editors do not. Codex clears the current Composer once with `C-u`; Claude Code uses a sentinel-backed native `C-s` stash-clear transaction that is independent of the cursor position and does not interrupt an active turn, then proves the main Composer empty. Each then injects the request, waits through the paste window, and dispatches Enter exactly once. Codex also freezes the complete pre-send open-rollout inventory and scans those candidates together with newly opened roots after submission. One rollout that uniquely accepts the exact request hash is promoted to the managed Session/Turn; zero matches remain pending/unproven, while multiple matches or changed file/process authority become uncertain without replay. After either agent's text injection, no Composer observation may veto Enter.
59
+
60
+ If managed preparation still fails before input, physical-terminal authority performs the same single Send and best-effort persists an exact request-bound Terminal Watch. That Watch supplies completion callbacks. Before exact native acceptance it remains notify-only; after acceptance it can emit an idempotent `interaction_required` wake-up and, through same-controller Status, expose one supported native-interaction response offer. Activity/best-effort or manual-only observations emit `interaction_manual_required` and require direct TUI input. Watch attachment failure is reported without changing or retrying the successful Send. Send output treats transport, native acceptance, management, and observation as separate facts through `terminal_input_dispatched`, `agent_acceptance`, `management_mode`, `observation_mode`, and `capabilities`; legacy delivery fields remain compatibility aliases. Once clear or request input may have occurred, an uncertain result must never be retried automatically.
61
+
62
+ P2 adds an explicit path for an exact-empty idle Codex pane whose foreground
63
+ rollout cannot be selected safely. `identify_foreground({terminal_id})` holds
64
+ the exact terminal lock and dispatches the closed `/status` probe once. It is
65
+ read-only with respect to the AKK Store, but it is terminal input. Its proof is
66
+ bound to the pane, process incarnation, real cwd, agent version, and screen
67
+ generation, expires after 30 seconds, and grants no binding or mutation
68
+ authority after the lock is released. It creates no Session, Turn, receipt,
69
+ monitor, or callback.
70
+
71
+ `identify_and_send({terminal_id,request})` is the atomic actionable form. It
72
+ retains one terminal lock from the probe through the requested task, rechecks
73
+ the live boundary before task input, and still grants durable Session/Turn
74
+ identity only to the rollout that uniquely accepts the exact request. The
75
+ status UUID is provisional evidence, never durable ownership. Probe or boundary
76
+ uncertainty stops before the task and cannot be retried automatically. This
77
+ operation is optional: ordinary human Send continues to follow its independent
78
+ user-priority contract and is never implicitly redirected through these
79
+ identification actions. List never types an identity probe, and exact bound-task
80
+ Status stays read-only. A targeted conversation Status for an unbound, idle
81
+ Codex terminal may use a separate closed routing identity inspection; see
82
+ [Status and native inspection](operator-guide.md#akk-status-and-native-inspection).
83
+ Codex 0.158.0/0.159.0/0.159.2 physical Send
84
+ and exact Watch creation use their separate closed `/status` transaction to
85
+ bind the foreground paginated thread.
86
+
87
+ An ordinary send never targets a completed or historical `turn_id`. If the current Turn is in the compatibility state `waiting_for_openclaw` because the coding agent asked a question, the controller Host uses `respond(turn_id, answer)`; that answer remains inside the same Turn.
88
+
89
+ A native Claude Code or Codex interaction is a separate status-bound flow. In the same owning controller conversation, call Status for the exact managed Turn or exact Watch and present its current `interaction_state` to the user. If that projection is pending and advertises response capability, submit exactly one subject (`turn_id` or `watch_id`) plus only its opaque `interaction_id`, `question_id`, and `option_id` values or bounded typed text. A blocking `questionnaire` owns the input surface and forbids `delivery_mode`. A Codex `async_question` is a parallel pending interaction while terminal activity and its Turn remain `working`; its projection advertises one or both semantic delivery modes, and its response defaults to advertised `steer_current_turn` (or explicitly selects advertised `queue_next_turn`): `steer_current_turn` delivers the answer to the running turn, while `queue_next_turn` queues it for the next turn. One response resolves only the current step; refresh Status before every later question or final confirmation. The callback itself never grants mutation authority. Changed, unprovable, secret-bearing, unsupported, multi-select, manual-required, or uncertain interactions fail closed and must not receive guessed keys, shortcut chords, menu indexes, or automatic retries. Expiry is a freshness boundary: an elapsed offer requires an exact live recapture rather than an unconditional rejection or replay. Codex 0.154.0 and 0.155.1 are separate version-bound TUI profiles; notification and stable-question-identity wrappers added to main after 0.155.1 are not part of either released contract.
90
+
91
+ If no eligible terminal exists, AKK stops and returns an actionable setup message. It does not launch an invisible replacement agent.
92
+
93
+ ### Trusted controller callback boundary
94
+
95
+ Callback routing is an administrator/trusted-host concern, never a model
96
+ argument. The OpenClaw plugin captures its own authenticated controller
97
+ session identity and gives AKK a versioned, secretless `callback_route`; the
98
+ durable outbox freezes that route together with a canonical callback envelope
99
+ before delivery. A transport returns one explicit outcome: accepted,
100
+ retryable failure, permanent failure, or uncertain. Permanent and uncertain
101
+ outcomes are not blindly retried, while an accepted checkpoint remains
102
+ authoritative if a later wake or observation step fails.
103
+
104
+ The core outbox, managed-Turn monitor, stall notification, and Terminal Watch
105
+ use the host-neutral route/envelope/outcome boundary. First-party adapters
106
+ translate that boundary into the Host's own lifecycle: OpenClaw uses its
107
+ Gateway session, while Pi and DeepSeek Harness use a local `command_json_v1`
108
+ callback path. Existing OpenClaw Store fields remain readable and dual-written
109
+ for compatibility; OpenClaw-specific `sessionKey`, Gateway calls, executable
110
+ paths, and credentials stay inside the trusted OpenClaw adapter. No route,
111
+ profile, controller-session identity, token, composer digest, draft text, or
112
+ transport evidence is exposed through the v30 model-facing contract. A new
113
+ controller Host still needs a trusted session-context adapter and runtime
114
+ integration; the protocol boundary is not a standalone supervisor.
115
+
116
+ ## User-Selected Terminal Watch
117
+
118
+ Terminal Watch is the read-only, user-intent-first path for observing an exact visible Codex or Claude Code terminal:
119
+
120
+ 1. The user selects one complete `terminal_id`. A fresh `/akk list` and its advertised `available_actions.watch` are the safest discovery path, but advertisement is not authorization and its absence does not veto an explicit Watch request.
121
+ 2. `agent_knock_knock_watch({terminal_id})`, or `/akk watch <exact-terminal-id>`, observes that exact endpoint/process and attempts to construct one privacy-safe exact task anchor. It does not acquire terminal-input or managed-owner authority.
122
+ 3. If a unique provider task anchor is available, AKK creates `watch_mode="exact_task"`, `confidence="exact"`; missing or mismatched version evidence remains a warning and does not weaken that otherwise exact anchor. If task artifacts, native identity, or task boundaries cannot establish an anchor, AKK records warnings and creates `watch_mode="terminal_activity"`, `confidence="best_effort"` instead.
123
+ 4. Status and cancellation target only the returned ID: `agent_knock_knock_status({watch_id})`, `/akk status <watch-id>`, `agent_knock_knock_unwatch({watch_id})`, or `/akk unwatch <watch-id>`.
124
+ 5. Startup and periodic supervision observe and settle the same Watch, then deliver its durable notification outbox to the originating controller session.
125
+
126
+ Creating a Watch hard-fails only when the exact terminal is absent, its endpoint/process cannot be identified, neither a durable exact-task anchor nor a read-only screen-status activity path exists, or AKK cannot create/write the durable Watch Store. A missing or mismatched coding-agent version, unusable rollout/transcript artifact when screen activity remains observable, existing managed Turn or other ownership record, missing binding metadata, and missing `available_actions.watch` are diagnostics, never Watch vetoes. If the same exact active Watch already exists, AKK may return it rather than treating the request as a conflict. Because Watch is read-only, it can coexist with a managed monitor without adopting, superseding, or changing its Session/Turn; the managed monitor remains preferable when the user wants exact Turn attribution.
127
+
128
+ Every aggregate records a revision, exact terminal endpoint/process epoch, workspace, creation warnings, controller route, timestamps/deadline, lifecycle status, last activity, optional settlement, and an append-only notification outbox. An exact-task Watch additionally stores one privacy-safe provider anchor: Codex binds rollout identity and task request/turn byte boundaries; Claude binds transcript identity, root prompt, and current-turn byte boundaries. Exact durable completion already written to that anchor wins, while later replacement, truncation, successor task, changed boundary or fingerprint, or process/thread/endpoint drift invalidates that exact Watch instead of following a different task.
129
+
130
+ A terminal-activity Watch makes no task-identity claim. Its checkpoint must first observe activity (`working` or `awaiting_approval`) in the selected terminal/process epoch and then observe stable `idle` across consecutive reconciliation sweeps. That transition emits a completion-shaped callback with reason `terminal_activity_became_stably_idle`, but the callback and public status remain labeled `best_effort`: they prove only that observed terminal activity became idle, not that a particular task completed or succeeded. They carry no exact-task completion text. Starting from idle or unknown does not immediately settle; later activity must be seen first.
131
+
132
+ An approval observation appends at most one notification per exact fingerprint and leaves either Watch mode active. It never sends approval keys and never enters automatic approval; a human must inspect and decide in the TUI. Exact-task completion/failure, best-effort stable idle, timeout, invalidation, or explicit `unwatch` settles once and enqueues one terminal notification. Deterministic notification IDs and idempotency keys, append-only receipts, claim leases, and retry timestamps make callback recovery crash-safe: transport is at-least-once, while the idempotency key makes the logical notification effectively at-most-once.
133
+
134
+ The current core Host Adapter surface has 22 registered tools and emits list action-contract v30. Its Watch tools map to four internal CLI entries: `watch-terminal`, `watch-status`, `unwatch-terminal`, and `reconcile-watches`. These entries are an internal adapter boundary, not alternate raw terminal controls. The v30 ordinary Send shape remains `send({session_id|terminal_id,request})`; the agent-neutral user-explicit composer policy is advertised as `replace_current_composer_and_submit`, not as another model-supplied argument. The v28 Codex-named field remains a compatibility alias. The interaction tool consumes only the current same-controller Status projection and never exposes its private prompt fingerprint or terminal-key plan. The two foreground-identification tools are separate, advertised Codex-only operations and are never implicit ordinary-Send preprocessing.
135
+
136
+ ## Native Thread Transitions
137
+
138
+ New/clear and resume are lifecycle transitions, not message types and not ordinary sends:
139
+
140
+ ```text
141
+ verified idle terminal + private current-binding fence
142
+ ├─ new_thread ────> new native thread + new AKK Session
143
+ └─ resume_thread ─> exact historical native thread + restored/new AKK Session
144
+ (no Turn created)
145
+ ```
146
+
147
+ Before either transition, the public action supplies the exact full `terminal_id`; resume additionally supplies the complete `native_thread_id`. AKK then derives a fresh compare-and-swap binding fence and candidate fence privately, and requires a recognized adapter, a complete `x.y.z` agent version, an idle prompt, and no active or unresolved Turn. An exact regression-tested profile is a verification level, not an authorization gate; an unverified version remains callable and carries a compatibility warning. Human-facing numbers and collision-safe short IDs are scoped to a five-minute private runtime snapshot; AKK resolves them to the complete UUID before the structured action and revalidates the entire ordered candidate set, terminal dispatch generation, process, workspace, and binding before input. They are never model arguments or stored as native identity. A replaced or changed transcript/rollout cannot be resumed under stale metadata. `previous` is derived only from the current bound Session's latest committed transition and is advertised only when fresh discovery proves exactly one resumable source; static lineage and recency are not authority. Candidates from another workspace, archived or ambiguous threads, and threads active in another process are not resumable.
148
+
149
+ The lifecycle operation is serialized against send, approval, monitor, cancellation, and recovery work for that pane. AKK records the previous and next native identities, verifies the post-operation identity and idle prompt, creates or reactivates the corresponding AKK Session, and advances the binding generation. It fails closed if any identity or capability evidence is missing or changed. Monitor supervision never reclassifies a historical binding: only a later lifecycle listing may classify one bound historical Session as resumable when its recorded process has conclusively exited, and the resume mutation compare-and-swap detaches that binding before terminal input. Every first-line native slash command is rejected as ordinary task or answer text, including clear/new/resume/status, Codex fork/side-thread commands, and Claude conversation branching; supported context changes must use the lifecycle boundary.
150
+
151
+ For the next ordinary send, refresh `agent_knock_knock_list` and use only the resulting terminal row's advertised action. A `session_exact` action supplies `session_id`; a `terminal_follow_current` action supplies `terminal_id`. Either accepted action creates the context's first new `turn_id`. A callback, monitor, approval, receipt, or recovery action bound to an earlier Session, native identity, terminal incarnation, or binding generation cannot mutate the newly active context.
152
+
153
+ ## Native Status Inspection
154
+
155
+ `agent_knock_knock_status` is an AKK Turn/screen inspection. It does not execute a coding-agent slash command. Native inspection is a separate terminal action advertised when the adapter, terminal identity, private binding fence, idle composer, and ownership state are currently safe. An unverified semantic agent version adds a warning but does not hide the action.
156
+
157
+ The `agent_knock_knock_native_inspect` contract accepts exactly two fields: the full `terminal_id` and `inspection="status"`. The adapter owns the closed command, and AKK derives the fresh binding fence internally; callers cannot supply a command string or opaque authority. Regression-tested profiles cover Codex 0.146.0/0.146.1/0.147.0/0.148.0/0.149.1/0.150.1/0.151.0/0.153.0/0.153.4/0.154.0/0.155.1 and Claude Code 2.1.218/2.1.226/2.1.237/2.1.251/2.1.259/2.1.263/2.1.266/2.1.267/2.1.285. Other complete `x.y.z` versions use the generic runtime profile with a compatibility warning; unchanged UI behavior succeeds, while incompatible behavior fails or is reported uncertain without automatic retry. Claude's modal Status panel must be freshly proven, parsed, dismissed once, and followed by the same idle empty composer. `/usage`, `/cost`, `/stats`, `/usage-credits`, `/model`, `/compact`, and arbitrary slash commands remain unavailable. Bare Codex `/usage` opens an interactive menu whose later Enter can select an account-side usage-limit reset, so it must not be treated as a read-only inspection.
158
+
159
+ Native model control is a separate two-step mutation based on explicit authority
160
+ for one exact physical pane/process. `model_options({terminal_id})` dynamically
161
+ captures the native model/reasoning catalog; `set_model` accepts only one exact
162
+ tuple from that same-controller offer. Profiled Codex 0.154.0/0.155.1 accepts either one exact
163
+ current native Session or a verified-zero-rollout pane, where
164
+ `identify_foreground` is not a prerequisite; Claude Code still requires one
165
+ exact current native Session. Both steps require no active Turn, approval,
166
+ questionnaire/editor, or read-only viewer. `model_options` normally requires
167
+ an idle empty Composer, but current List may bind it to one exact stable Codex
168
+ 0.154 `/model` residual and authorize continuing only that slash command into
169
+ read-only discovery. Every native frame is revalidated under lock. An unproven
170
+ postcondition is `uncertain` and must not be retried automatically. Codex reports
171
+ `current_and_new_sessions` with the existing current-only Ultra exception;
172
+ Claude Code reports `current_session`.
173
+
174
+ A failed profiled Codex 0.154.0/0.155.1 model-control operation can expose both residual-bound
175
+ `model_options({terminal_id})` and the distinct cleanup-only
176
+ `repair_model_control({terminal_id})` action when List proves the same
177
+ exact physical pane/process, an exact profiled `/model` popup or exact bare
178
+ `/model` Composer, no active Turn, and no approval, questionnaire/editor, or
179
+ viewer. The trusted adapter consumes the residual-entry authority at the
180
+ `model_options` Enter boundary. After exact catalog discovery and dismissal to
181
+ an empty Composer, AKK derives a fresh ordinary binding/catalog offer for one
182
+ `set_model` attempt. Neither residual-entry nor repair authority is accepted by
183
+ `set_model`. Repair never presses Enter or accepts raw text/keys; success
184
+ requires an empty Composer. Refresh List and obtain a new model catalog
185
+ afterward. An uncertain repair cannot be retried automatically.
186
+
187
+ Foreground identification is a separate Codex-only capability for a physically
188
+ exact but durably ambiguous pane. `agent_knock_knock_identify_foreground`
189
+ accepts only the advertised `terminal_id`; it sends `/status` once and returns
190
+ a 30-second diagnostic proof while leaving the Store unchanged. That proof is
191
+ not an authority object and cannot be supplied to any later call.
192
+ `agent_knock_knock_identify_and_send` accepts the advertised `terminal_id` and
193
+ one `request`, and consumes the foreground observation only while the same
194
+ terminal lock remains held. It neither weakens exact request acceptance nor
195
+ turns the status UUID into durable identity.
196
+
197
+ Native inspection is serialized against send, lifecycle transition, approval, cancellation, monitoring terminal access, and recovery. It verifies the exact slash composer beyond the versioned Enter-suppression window, sends at most one Enter, proves one fresh bounded/redacted status result, and requires an idle postcondition. It creates no Session, Turn, dispatch receipt, monitor, callback, or response-round state. Any stale private fence, non-empty composer, identity/version drift, unresolved Turn/transition/dispatch, unproven Enter, or ambiguous result fails closed without a blind second Enter.
198
+
199
+ Ordinary `send` and `respond` continue to reject every first-line native slash command. Native inspection is a narrow capability boundary, not a slash-command allowlist.
200
+
201
+ ## Message Types
202
+
203
+ | Type | Purpose |
204
+ | --- | --- |
205
+ | `task` | The controller Host starts a new Turn with work for the coding agent. |
206
+ | `answer` | The controller Host answers a question inside a `waiting_for_openclaw` Turn. |
207
+ | `progress` | AKK reports reliable non-final progress. |
208
+ | `blocked` | AKK reports that the task needs attention. |
209
+ | `done` | AKK reports that the current terminal turn completed. |
210
+ | `error` | AKK reports a terminal, monitor, callback, or protocol failure. |
211
+ | `control` | AKK records Turn-level control such as cancellation or timeout. |
212
+
213
+ The coding agent does not run a callback command and does not need an AKK-specific hook or plugin. AKK's terminal monitor owns callback delivery.
214
+
215
+ ## Terminal Identity
216
+
217
+ Each managed Turn is bound to a concrete identity, including:
218
+
219
+ - coding agent (`codex` or `claude`)
220
+ - canonical working directory captured for this pane and Turn
221
+ - terminal provider endpoint and pane target
222
+ - pane and agent process identity
223
+ - native session evidence, AKK `session_id`, `turn_id`, and message identity
224
+ - terminal binding ID and generation, including the transition that established it
225
+ - monitor owner and lease
226
+
227
+ AKK revalidates that identity before sending tasks, interrupt keys, or approval input. Stale, changed, ambiguous, or replayed actions are rejected.
228
+
229
+ Approval authorization is prompt-scoped. Managed approval carries only `turn_id`; terminal-scoped approval carries only `terminal_id`, and both require explicit user confirmation. An adapter isolates one complete bounded approval region and keeps its exact unredacted bytes and fingerprint local. The plugin/CLI retains the private confirmation offer, recaptures it under lock, and rejects before an approval key if any prompt, choice, command/secret, process, cwd, owner, or request evidence changed. Missing or ambiguous prompt evidence is never downgraded to whole-screen or parsed-display authority. No prompt fingerprint or terminal token crosses the model-facing boundary.
230
+
231
+ The active Host runtime supervises eligible terminal monitors and Terminal Watches
232
+ independently of interactive commands. At startup and in one non-overlapping
233
+ five-second cycle, it runs managed-Turn monitor reconciliation and Terminal
234
+ Watch reconciliation as separate coordination steps with separate error
235
+ boundaries; a failure in either step does not starve the other. Managed monitor
236
+ reconciliation distinguishes a transient Store-lock timeout from proven binding
237
+ supersession and preserves the Turn's exactly-once completion claim across
238
+ monitor replacement. Watch reconciliation restores observation and retries its
239
+ durable idempotent callback outbox. Codex managed completion first scans the
240
+ exact accepted native turn in the rollout bound to the Turn; it does not fall
241
+ back to another same-workspace rollout after that exact detector reports an
242
+ identity or integrity failure. Detector limitations are retained in the Turn
243
+ event history for diagnosis.
244
+
245
+ ## Human Handoff
246
+
247
+ The tmux or Herdr pane remains the source of visible truth:
248
+
249
+ - Attach to the shared terminal to inspect or continue the work yourself.
250
+ - Use AKK status for a bounded remote view.
251
+ - Send the next request to `session_id` only when AKK verifies the pane is idle; this creates a new Turn.
252
+ - Answer an in-flight agent question only through `respond(turn_id, answer)`.
253
+ - Interrupt the current turn without closing the pane.
254
+ - Renew monitoring only when the same live task remains in that pane.
255
+
256
+ This makes handoff reversible: the controller Host and the human operate the same coding-agent session instead of creating parallel, hidden conversations.
257
+
258
+ If a human context switch conflicts with an active Turn, AKK presents a decision rather than redirecting automatically. After explicit takeover confirmation, the model calls `agent_knock_knock_close({turn_id,reason:"superseded_by_human_context_switch"})`; the plugin/CLI privately resolves and revalidates the exact advertised handoff decision, so no live native UUID or handoff token is transported. Low-level binding repair is similarly explicit: `reconcile_binding({terminal_id,conflicting_session_id})` carries no Session revision, binding ID/generation, or token. Reconciliation only detaches the proven stale binding; it neither adopts the live thread nor sends terminal input.
259
+
260
+ Native clear/new/resume operations are separate Session-lifecycle features. Ordinary send and Turn creation do not invoke them; successful lifecycle transitions create no Turn.
@@ -0,0 +1,126 @@
1
+ # Codex CLI 0.160.0 compatibility
2
+
3
+ This review follows the official stable `rust-v0.160.0` release (2026-10-01),
4
+ not the `0.162.0-alpha` channel. AKK 0.13.18 also reviews the 0.159.3
5
+ foreground client because already-running clients can share the upgraded
6
+ 0.160.0 app-server.
7
+
8
+ ## Contract review
9
+
10
+ The native binaries generate byte-identical experimental TypeScript schemas
11
+ across 0.159.2, 0.159.3, and 0.160.0 (875 files), and byte-identical JSON
12
+ schemas between 0.159.3 and 0.160.0 (440 files). The official source comparison
13
+ also preserves paginated history, thread/turn identity, request-user-input,
14
+ and async-answer wire shapes. Runtime response validation remains required;
15
+ schema equality alone does not authorize a native write.
16
+
17
+ The 0.160.0 macOS Option-key hint no longer contains a plus sign:
18
+ `⌥↑ to answer`, `⌥↓ main prompt`, and `⌥↑ next question`. AKK uses a distinct
19
+ async UI profile for this grammar. Older frontends retain their old spelling;
20
+ unknown or mixed keymaps remain non-executable. The native status reader
21
+ accepts both closed display spellings without granting input authority.
22
+
23
+ Native model, permission, questionnaire, and status profiles cover 0.159.3 and
24
+ 0.160.0. The new projectless `Workspace (granular)` default is represented as
25
+ `workspace_granular`, a current-only state. Its actual native picker offers
26
+ three standard presets with no current marker. AKK may select a freshly
27
+ advertised preset; it never treats granular as Ask for approval, exposes it as
28
+ a selectable target, or accepts arbitrary custom/granular labels. New status cards may omit reasoning summaries on server connections;
29
+ this field is not an identity requirement. Plan footer hints remain display
30
+ information, not task identity.
31
+
32
+ Exact audited interaction pairs are:
33
+
34
+ | Foreground CLI | app-server | Basis |
35
+ | --- | --- | --- |
36
+ | 0.159.3 | 0.159.3 | Identical protocol and reviewed source; regression tests |
37
+ | 0.159.3 | 0.160.0 | Shared-backend upgrade pair; native verification below |
38
+ | 0.160.0 | 0.160.0 | Current stable pair; native verification below |
39
+
40
+ Existing audited older pairs remain available. The reverse 0.160.0/0.159.3
41
+ pair, 0.159.2/0.160.0, and unreviewed later pairs do not gain answer authority.
42
+ Read-only contract negotiation continues to support compatible newer backends;
43
+ a changed backend can retain exact observation, but withdraws an executable
44
+ question offer until its own fresh authority is established.
45
+
46
+ ## Verification
47
+
48
+ On 2026-10-04, isolated macOS tmux sessions ran the actual 0.159.3/0.160.0
49
+ and 0.160.0/0.160.0 foreground/backend combinations. Every launch used the
50
+ existing `mycodes` wrapper; an owned PATH shim selected the old executable for
51
+ the mixed pair. No user terminal or shared daemon was restarted.
52
+
53
+ Both pairs passed two real model turns each, through built production adapters:
54
+
55
+ - Discover the exact process and pane; capture a fresh native status/thread.
56
+ - Send once, prove exact native request acceptance, and attach an automatic
57
+ paginated task Watch.
58
+ - Attach another exact Watch while the same async task is working.
59
+ - Receive the async question callback; answer once to that exact turn, then
60
+ prove the matching durable user-message/question ID.
61
+ - Receive and answer a native Plan-mode blocking question; prove the canonical
62
+ function output before treating its answer as confirmed.
63
+ - Prove the exact native turn completed with the requested nonce and answer;
64
+ repeated reconciliation delivers exactly one completion callback per Watch.
65
+
66
+ A separate real 0.160.0 pane passed native `/status` identity, model catalog
67
+ inspection without changing its model/effort, and permission discovery followed
68
+ by Ask for approval → Full Access (including native confirmation) → Ask for
69
+ approval. Every permission result was confirmed against the same thread and
70
+ fresh status/menu, with `defaults_changed=false`. The initial read-only state
71
+ was not selectable in this platform's picker; cleanup retained the final
72
+ standard preset only in the disposable test session.
73
+
74
+ The final candidate also passed the production permission APIs starting from
75
+ an actual `Workspace (granular)` session: discovery returned only the three
76
+ standard choices, followed by granular → Full Access → Ask for approval. Both
77
+ changes had fresh same-thread status/menu confirmation and unchanged defaults;
78
+ model and effort remained unchanged. The prior invalidated Watch stayed
79
+ invalidated throughout, and no task was resent or revived.
80
+
81
+ Callbacks were collected at the production Watch transport boundary in a local
82
+ sink. This proves AKK callback generation/deduplication, not delivery to an
83
+ external chat service. The live terminal used the `shift+arrow` keymap; the new
84
+ macOS Option spelling and Plan-cycle hint have official-source and regression
85
+ coverage, not live-keymap coverage. Herdr transport, remote endpoints, other
86
+ platforms, native model-setting commits, and command approval prompts were not
87
+ newly exercised live in this review.
88
+
89
+ An initial isolated attempt exposed the existing strict cwd boundary: macOS
90
+ `/var/...` was later persisted as `/private/var/...`, so its Watch was correctly
91
+ invalidated and was not revived or resent. Passing runs used physical canonical
92
+ workspace paths from launch. Launching through other symlink paths can still
93
+ encounter this conservative identity limitation.
94
+
95
+ `npm run test:fast` passed 2,464 tests; type checking, build, and architecture
96
+ validation passed. The immediate pre-publication `npm run test:release` gate
97
+ passed 2,979 tests, isolated OpenClaw 2026.9.1 compatibility (24 tools,
98
+ callback delivery, install/update/uninstall), ClawHub runtime validation, and
99
+ publication dry-run. The general native lifecycle smoke was not run because
100
+ paginated new/resume remains outside the supported path; the targeted native
101
+ proof above covers this release's actual task and permission paths.
102
+
103
+ ## Retained boundaries
104
+
105
+ - Ordinary List/Status reads live terminal activity. Without an existing exact
106
+ anchor it does not invent a native task identity, type `/status`, or create a
107
+ Watch. A same-workspace history guess cannot prove task completion.
108
+ - Exact Send/Watch preparation uses the existing locked native status
109
+ transaction, then validates the native thread, turn, request, and durable
110
+ completion. Compatible reads do not bypass input-owning modal or styled
111
+ Composer checks.
112
+ - A first Watch on an already-blocking question without a prior task anchor
113
+ remains activity-only/manual-response. Safe fallback is explicitly labeled
114
+ `terminal_activity`; idle is not proof of task completion.
115
+ - Paginated managed session-only dispatch and native new/resume remain outside
116
+ this adapter. The upstream permission-resume changes do not enable them.
117
+ - No existing user TUI or shared daemon needs to restart for installation.
118
+ Updating the CLI changes future launches; running processes retain their
119
+ loaded version. Explicit restarts must preserve the wrapper and exact UUID.
120
+
121
+ ## Sources
122
+
123
+ - [Official 0.160.0 release](https://github.com/openai/codex/releases/tag/rust-v0.160.0)
124
+ - [Official app-server documentation](https://learn.chatgpt.com/docs/app-server)
125
+ - [0.159.2 to 0.159.3 source comparison](https://github.com/openai/codex/compare/rust-v0.159.2...rust-v0.159.3)
126
+ - [0.159.3 to 0.160.0 source comparison](https://github.com/openai/codex/compare/rust-v0.159.3...rust-v0.160.0)