approval-md 0.2.0 → 0.4.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 (378) hide show
  1. package/README.md +85 -877
  2. package/SPEC.md +150 -19
  3. package/cli.js +66 -7
  4. package/dist/src/adapters/smtp.d.ts +18 -0
  5. package/dist/src/adapters/smtp.js +24 -3
  6. package/dist/src/adapters/smtp.js.map +1 -1
  7. package/dist/src/channels/contract.d.ts +53 -1
  8. package/dist/src/channels/contract.js +304 -7
  9. package/dist/src/channels/contract.js.map +1 -1
  10. package/dist/src/channels/relay-server.d.ts +90 -0
  11. package/dist/src/channels/relay-server.js +295 -0
  12. package/dist/src/channels/relay-server.js.map +1 -0
  13. package/dist/src/channels/relay.d.ts +273 -0
  14. package/dist/src/channels/relay.js +564 -0
  15. package/dist/src/channels/relay.js.map +1 -0
  16. package/dist/src/channels/tagging.js +6 -1
  17. package/dist/src/channels/tagging.js.map +1 -1
  18. package/dist/src/channels/telegram-webhook.d.ts +273 -0
  19. package/dist/src/channels/telegram-webhook.js +536 -0
  20. package/dist/src/channels/telegram-webhook.js.map +1 -0
  21. package/dist/src/channels/telegram.d.ts +394 -12
  22. package/dist/src/channels/telegram.js +621 -68
  23. package/dist/src/channels/telegram.js.map +1 -1
  24. package/dist/src/channels/web.d.ts +9 -0
  25. package/dist/src/channels/web.js +17 -0
  26. package/dist/src/channels/web.js.map +1 -1
  27. package/dist/src/cli/amend.js +564 -34
  28. package/dist/src/cli/amend.js.map +1 -1
  29. package/dist/src/cli/attest.d.ts +9 -0
  30. package/dist/src/cli/attest.js +177 -13
  31. package/dist/src/cli/attest.js.map +1 -1
  32. package/dist/src/cli/channel-relay.d.ts +108 -0
  33. package/dist/src/cli/channel-relay.js +334 -0
  34. package/dist/src/cli/channel-relay.js.map +1 -0
  35. package/dist/src/cli/channel-telegram-webhook.d.ts +273 -0
  36. package/dist/src/cli/channel-telegram-webhook.js +709 -0
  37. package/dist/src/cli/channel-telegram-webhook.js.map +1 -0
  38. package/dist/src/cli/channel-telegram.d.ts +347 -28
  39. package/dist/src/cli/channel-telegram.js +763 -28
  40. package/dist/src/cli/channel-telegram.js.map +1 -1
  41. package/dist/src/cli/channel.d.ts +10 -1
  42. package/dist/src/cli/channel.js +14 -1
  43. package/dist/src/cli/channel.js.map +1 -1
  44. package/dist/src/cli/codex-bridge.d.ts +819 -0
  45. package/dist/src/cli/codex-bridge.js +1607 -0
  46. package/dist/src/cli/codex-bridge.js.map +1 -0
  47. package/dist/src/cli/codex.d.ts +1 -1
  48. package/dist/src/cli/codex.js +304 -7
  49. package/dist/src/cli/codex.js.map +1 -1
  50. package/dist/src/cli/daemon.js +41 -6
  51. package/dist/src/cli/daemon.js.map +1 -1
  52. package/dist/src/cli/doctor.d.ts +63 -0
  53. package/dist/src/cli/doctor.js +1322 -122
  54. package/dist/src/cli/doctor.js.map +1 -1
  55. package/dist/src/cli/execute.d.ts +17 -1
  56. package/dist/src/cli/execute.js +366 -22
  57. package/dist/src/cli/execute.js.map +1 -1
  58. package/dist/src/cli/exit-codes.d.ts +12 -0
  59. package/dist/src/cli/exit-codes.js +13 -0
  60. package/dist/src/cli/exit-codes.js.map +1 -1
  61. package/dist/src/cli/gate.d.ts +2 -0
  62. package/dist/src/cli/gate.js +233 -2
  63. package/dist/src/cli/gate.js.map +1 -1
  64. package/dist/src/cli/help.d.ts +14 -2
  65. package/dist/src/cli/help.js +395 -82
  66. package/dist/src/cli/help.js.map +1 -1
  67. package/dist/src/cli/hook-codex.d.ts +49 -1
  68. package/dist/src/cli/hook-codex.js +60 -1
  69. package/dist/src/cli/hook-codex.js.map +1 -1
  70. package/dist/src/cli/hook.d.ts +828 -4
  71. package/dist/src/cli/hook.js +2972 -142
  72. package/dist/src/cli/hook.js.map +1 -1
  73. package/dist/src/cli/import.js +1 -1
  74. package/dist/src/cli/import.js.map +1 -1
  75. package/dist/src/cli/init.js +16 -7
  76. package/dist/src/cli/init.js.map +1 -1
  77. package/dist/src/cli/instructions.js +24 -3
  78. package/dist/src/cli/instructions.js.map +1 -1
  79. package/dist/src/cli/log-anchor.d.ts +55 -0
  80. package/dist/src/cli/log-anchor.js +199 -60
  81. package/dist/src/cli/log-anchor.js.map +1 -1
  82. package/dist/src/cli/main.d.ts +0 -12
  83. package/dist/src/cli/main.js +56 -3
  84. package/dist/src/cli/main.js.map +1 -1
  85. package/dist/src/cli/muse.d.ts +2 -0
  86. package/dist/src/cli/muse.js +62 -0
  87. package/dist/src/cli/muse.js.map +1 -0
  88. package/dist/src/cli/payload.js +79 -1
  89. package/dist/src/cli/payload.js.map +1 -1
  90. package/dist/src/cli/policy-apply.d.ts +195 -0
  91. package/dist/src/cli/policy-apply.js +573 -0
  92. package/dist/src/cli/policy-apply.js.map +1 -0
  93. package/dist/src/cli/policy.js +14 -1
  94. package/dist/src/cli/policy.js.map +1 -1
  95. package/dist/src/cli/preflight.d.ts +151 -13
  96. package/dist/src/cli/preflight.js +398 -41
  97. package/dist/src/cli/preflight.js.map +1 -1
  98. package/dist/src/cli/sandbox.js +17 -1
  99. package/dist/src/cli/sandbox.js.map +1 -1
  100. package/dist/src/cli/scaffold.d.ts +1 -1
  101. package/dist/src/cli/scaffold.js +7 -1
  102. package/dist/src/cli/scaffold.js.map +1 -1
  103. package/dist/src/cli/serve.d.ts +53 -0
  104. package/dist/src/cli/serve.js +270 -0
  105. package/dist/src/cli/serve.js.map +1 -0
  106. package/dist/src/cli/setup-channel.d.ts +9 -0
  107. package/dist/src/cli/setup-channel.js +28 -1
  108. package/dist/src/cli/setup-channel.js.map +1 -1
  109. package/dist/src/cli/setup-common.d.ts +3 -1
  110. package/dist/src/cli/setup-common.js +3 -2
  111. package/dist/src/cli/setup-common.js.map +1 -1
  112. package/dist/src/cli/setup.d.ts +2 -0
  113. package/dist/src/cli/setup.js +94 -2
  114. package/dist/src/cli/setup.js.map +1 -1
  115. package/dist/src/cli/up.js +134 -51
  116. package/dist/src/cli/up.js.map +1 -1
  117. package/dist/src/cli/values.js +3 -4
  118. package/dist/src/cli/values.js.map +1 -1
  119. package/dist/src/cli/verb-registry.d.ts +2 -0
  120. package/dist/src/cli/verb-registry.js +510 -47
  121. package/dist/src/cli/verb-registry.js.map +1 -1
  122. package/dist/src/cli/wordmark.d.ts +2 -2
  123. package/dist/src/cli/wordmark.js +2 -2
  124. package/dist/src/codex/broker.d.ts +229 -0
  125. package/dist/src/codex/broker.js +548 -0
  126. package/dist/src/codex/broker.js.map +1 -0
  127. package/dist/src/codex/runner.d.ts +178 -0
  128. package/dist/src/codex/runner.js +231 -0
  129. package/dist/src/codex/runner.js.map +1 -0
  130. package/dist/src/codex/serve.d.ts +56 -0
  131. package/dist/src/codex/serve.js +98 -0
  132. package/dist/src/codex/serve.js.map +1 -0
  133. package/dist/src/codex/workspace-commit.d.ts +219 -0
  134. package/dist/src/codex/workspace-commit.js +549 -0
  135. package/dist/src/codex/workspace-commit.js.map +1 -0
  136. package/dist/src/core/advance-cycle.d.ts +51 -0
  137. package/dist/src/core/advance-cycle.js +66 -2
  138. package/dist/src/core/advance-cycle.js.map +1 -1
  139. package/dist/src/core/agents-md.d.ts +20 -18
  140. package/dist/src/core/agents-md.js +33 -31
  141. package/dist/src/core/agents-md.js.map +1 -1
  142. package/dist/src/core/attest-bootstrap.d.ts +95 -0
  143. package/dist/src/core/attest-bootstrap.js +135 -0
  144. package/dist/src/core/attest-bootstrap.js.map +1 -0
  145. package/dist/src/core/attest.d.ts +234 -2
  146. package/dist/src/core/attest.js +342 -7
  147. package/dist/src/core/attest.js.map +1 -1
  148. package/dist/src/core/audit.d.ts +73 -3
  149. package/dist/src/core/audit.js +65 -5
  150. package/dist/src/core/audit.js.map +1 -1
  151. package/dist/src/core/channel-lease.d.ts +322 -0
  152. package/dist/src/core/channel-lease.js +663 -0
  153. package/dist/src/core/channel-lease.js.map +1 -0
  154. package/dist/src/core/channel-owner.d.ts +213 -0
  155. package/dist/src/core/channel-owner.js +358 -0
  156. package/dist/src/core/channel-owner.js.map +1 -0
  157. package/dist/src/core/command-class.d.ts +205 -0
  158. package/dist/src/core/command-class.js +1433 -28
  159. package/dist/src/core/command-class.js.map +1 -1
  160. package/dist/src/core/commit-guard.d.ts +272 -0
  161. package/dist/src/core/commit-guard.js +424 -0
  162. package/dist/src/core/commit-guard.js.map +1 -0
  163. package/dist/src/core/daemon-actor.d.ts +45 -0
  164. package/dist/src/core/daemon-actor.js +54 -0
  165. package/dist/src/core/daemon-actor.js.map +1 -0
  166. package/dist/src/core/daemon-host.d.ts +178 -0
  167. package/dist/src/core/daemon-host.js +228 -0
  168. package/dist/src/core/daemon-host.js.map +1 -0
  169. package/dist/src/core/daemon-identity.d.ts +238 -0
  170. package/dist/src/core/daemon-identity.js +252 -0
  171. package/dist/src/core/daemon-identity.js.map +1 -0
  172. package/dist/src/core/dark-session.d.ts +109 -8
  173. package/dist/src/core/dark-session.js +266 -82
  174. package/dist/src/core/dark-session.js.map +1 -1
  175. package/dist/src/core/decision-refusal.d.ts +23 -2
  176. package/dist/src/core/decision-refusal.js +24 -2
  177. package/dist/src/core/decision-refusal.js.map +1 -1
  178. package/dist/src/core/env-file.d.ts +5 -0
  179. package/dist/src/core/env-file.js +60 -1
  180. package/dist/src/core/env-file.js.map +1 -1
  181. package/dist/src/core/execute.d.ts +15 -2
  182. package/dist/src/core/execute.js +15 -2
  183. package/dist/src/core/execute.js.map +1 -1
  184. package/dist/src/core/gate.d.ts +392 -6
  185. package/dist/src/core/gate.js +852 -24
  186. package/dist/src/core/gate.js.map +1 -1
  187. package/dist/src/core/gesture-refusal.d.ts +166 -0
  188. package/dist/src/core/gesture-refusal.js +188 -0
  189. package/dist/src/core/gesture-refusal.js.map +1 -0
  190. package/dist/src/core/harness-version.d.ts +128 -4
  191. package/dist/src/core/harness-version.js +181 -12
  192. package/dist/src/core/harness-version.js.map +1 -1
  193. package/dist/src/core/harness-wait.d.ts +82 -3
  194. package/dist/src/core/harness-wait.js +89 -3
  195. package/dist/src/core/harness-wait.js.map +1 -1
  196. package/dist/src/core/instance.d.ts +59 -2
  197. package/dist/src/core/instance.js +113 -0
  198. package/dist/src/core/instance.js.map +1 -1
  199. package/dist/src/core/log-subscribe.d.ts +21 -0
  200. package/dist/src/core/log-subscribe.js +16 -6
  201. package/dist/src/core/log-subscribe.js.map +1 -1
  202. package/dist/src/core/log-write-layer.d.ts +55 -0
  203. package/dist/src/core/log-write-layer.js +91 -0
  204. package/dist/src/core/log-write-layer.js.map +1 -0
  205. package/dist/src/core/log.d.ts +89 -22
  206. package/dist/src/core/log.js +197 -19
  207. package/dist/src/core/log.js.map +1 -1
  208. package/dist/src/core/payload-census.d.ts +51 -0
  209. package/dist/src/core/payload-census.js +125 -2
  210. package/dist/src/core/payload-census.js.map +1 -1
  211. package/dist/src/core/payload-store.d.ts +31 -0
  212. package/dist/src/core/payload-store.js +113 -8
  213. package/dist/src/core/payload-store.js.map +1 -1
  214. package/dist/src/core/payload.d.ts +18 -3
  215. package/dist/src/core/payload.js +20 -4
  216. package/dist/src/core/payload.js.map +1 -1
  217. package/dist/src/core/policy-diff.d.ts +10 -0
  218. package/dist/src/core/policy-diff.js +10 -2
  219. package/dist/src/core/policy-diff.js.map +1 -1
  220. package/dist/src/core/policy-explain.d.ts +17 -1
  221. package/dist/src/core/policy-explain.js +48 -1
  222. package/dist/src/core/policy-explain.js.map +1 -1
  223. package/dist/src/core/policy-load.d.ts +65 -1
  224. package/dist/src/core/policy-load.js +21 -3
  225. package/dist/src/core/policy-load.js.map +1 -1
  226. package/dist/src/core/policy-match.d.ts +81 -0
  227. package/dist/src/core/policy-match.js +87 -0
  228. package/dist/src/core/policy-match.js.map +1 -1
  229. package/dist/src/core/policy-proposal.d.ts +75 -0
  230. package/dist/src/core/policy-proposal.js +110 -4
  231. package/dist/src/core/policy-proposal.js.map +1 -1
  232. package/dist/src/core/protected-path-guard.d.ts +117 -4
  233. package/dist/src/core/protected-path-guard.js +362 -48
  234. package/dist/src/core/protected-path-guard.js.map +1 -1
  235. package/dist/src/core/question-preempted.d.ts +141 -0
  236. package/dist/src/core/question-preempted.js +152 -0
  237. package/dist/src/core/question-preempted.js.map +1 -0
  238. package/dist/src/core/read-scope.d.ts +182 -0
  239. package/dist/src/core/read-scope.js +256 -0
  240. package/dist/src/core/read-scope.js.map +1 -0
  241. package/dist/src/core/run-payload.d.ts +160 -0
  242. package/dist/src/core/run-payload.js +304 -0
  243. package/dist/src/core/run-payload.js.map +1 -0
  244. package/dist/src/core/sandbox.d.ts +81 -0
  245. package/dist/src/core/sandbox.js +190 -1
  246. package/dist/src/core/sandbox.js.map +1 -1
  247. package/dist/src/core/sender-identity.d.ts +501 -0
  248. package/dist/src/core/sender-identity.js +609 -0
  249. package/dist/src/core/sender-identity.js.map +1 -0
  250. package/dist/src/core/shlex.d.ts +102 -0
  251. package/dist/src/core/shlex.js +159 -0
  252. package/dist/src/core/shlex.js.map +1 -0
  253. package/dist/src/core/state.d.ts +52 -1
  254. package/dist/src/core/state.js +52 -6
  255. package/dist/src/core/state.js.map +1 -1
  256. package/dist/src/core/telegram-config.d.ts +79 -0
  257. package/dist/src/core/telegram-config.js +108 -0
  258. package/dist/src/core/telegram-config.js.map +1 -1
  259. package/dist/src/core/values.d.ts +18 -8
  260. package/dist/src/core/values.js +36 -1
  261. package/dist/src/core/values.js.map +1 -1
  262. package/dist/src/core/verify.d.ts +23 -1
  263. package/dist/src/core/verify.js +20 -2
  264. package/dist/src/core/verify.js.map +1 -1
  265. package/dist/src/daemon/advance.d.ts +10 -0
  266. package/dist/src/daemon/advance.js +25 -4
  267. package/dist/src/daemon/advance.js.map +1 -1
  268. package/dist/src/daemon/audit.d.ts +80 -5
  269. package/dist/src/daemon/audit.js +126 -6
  270. package/dist/src/daemon/audit.js.map +1 -1
  271. package/dist/src/daemon/daemon.d.ts +174 -2
  272. package/dist/src/daemon/daemon.js +307 -7
  273. package/dist/src/daemon/daemon.js.map +1 -1
  274. package/dist/src/daemon/git-evidence.d.ts +2 -2
  275. package/dist/src/daemon/git-evidence.js +1 -1
  276. package/dist/src/daemon/projection.d.ts +13 -2
  277. package/dist/src/daemon/projection.js +39 -6
  278. package/dist/src/daemon/projection.js.map +1 -1
  279. package/dist/src/mcp/server.d.ts +39 -3
  280. package/dist/src/mcp/server.js +30 -3
  281. package/dist/src/mcp/server.js.map +1 -1
  282. package/dist/src/muse/server.d.ts +16 -0
  283. package/dist/src/muse/server.js +238 -0
  284. package/dist/src/muse/server.js.map +1 -0
  285. package/dist/src/serve/archive.d.ts +158 -0
  286. package/dist/src/serve/archive.js +354 -0
  287. package/dist/src/serve/archive.js.map +1 -0
  288. package/dist/src/serve/arguments.d.ts +93 -0
  289. package/dist/src/serve/arguments.js +228 -0
  290. package/dist/src/serve/arguments.js.map +1 -0
  291. package/dist/src/serve/credentials.d.ts +91 -0
  292. package/dist/src/serve/credentials.js +143 -0
  293. package/dist/src/serve/credentials.js.map +1 -0
  294. package/dist/src/serve/follow.d.ts +86 -0
  295. package/dist/src/serve/follow.js +101 -0
  296. package/dist/src/serve/follow.js.map +1 -0
  297. package/dist/src/serve/hook-thread.d.ts +134 -0
  298. package/dist/src/serve/hook-thread.js +333 -0
  299. package/dist/src/serve/hook-thread.js.map +1 -0
  300. package/dist/src/serve/hook-worker.d.ts +134 -0
  301. package/dist/src/serve/hook-worker.js +173 -0
  302. package/dist/src/serve/hook-worker.js.map +1 -0
  303. package/dist/src/serve/server.d.ts +412 -0
  304. package/dist/src/serve/server.js +1251 -0
  305. package/dist/src/serve/server.js.map +1 -0
  306. package/docs/README-extended.md +766 -0
  307. package/docs/cli-reference.md +2563 -73
  308. package/docs/codex-enforced-session.md +75 -2
  309. package/docs/codex-workspace-broker.md +118 -0
  310. package/package.json +6 -2
  311. package/schema/event.schema.json +595 -9
  312. package/schema/fixtures/event/invalid/approval-granted-sender-hashed-false.json +20 -0
  313. package/schema/fixtures/event/invalid/approval-granted-sender-hashed-raw-id.json +20 -0
  314. package/schema/fixtures/event/invalid/audit-gesture-refused-human-actor.json +16 -0
  315. package/schema/fixtures/event/invalid/audit-gesture-refused-no-actor-no-sender.json +15 -0
  316. package/schema/fixtures/event/invalid/audit-gesture-refused-unknown-gesture.json +16 -0
  317. package/schema/fixtures/event/invalid/audit-question-preempted-agent-actor.json +16 -0
  318. package/schema/fixtures/event/invalid/audit-question-preempted-no-question-id.json +16 -0
  319. package/schema/fixtures/event/invalid/audit-question-preempted-unknown-source.json +15 -0
  320. package/schema/fixtures/event/invalid/daemon-id-malformed.json +15 -0
  321. package/schema/fixtures/event/invalid/execution-started-truncated-policy-sha256.json +18 -0
  322. package/schema/fixtures/event/invalid/gate-path-signed-off-absolute-path.json +14 -0
  323. package/schema/fixtures/event/invalid/gate-path-signed-off-agent-actor.json +14 -0
  324. package/schema/fixtures/event/invalid/gate-path-signed-off-missing-path.json +13 -0
  325. package/schema/fixtures/event/invalid/harness-cap-at-margin.json +16 -0
  326. package/schema/fixtures/event/invalid/harness-cap-fractional.json +16 -0
  327. package/schema/fixtures/event/invalid/harness-cap-negative.json +16 -0
  328. package/schema/fixtures/event/invalid/harness-cap-string.json +16 -0
  329. package/schema/fixtures/event/invalid/harness-cap-without-harness-execution.json +16 -0
  330. package/schema/fixtures/event/invalid/harness-cap-zero.json +16 -0
  331. package/schema/fixtures/event/valid/approval-granted-sender-hashed.json +20 -0
  332. package/schema/fixtures/event/valid/approval-requested-harness-cap.json +18 -0
  333. package/schema/fixtures/event/valid/audit-gesture-refused-review-note.json +21 -0
  334. package/schema/fixtures/event/valid/audit-gesture-refused-sender-key-unavailable.json +19 -0
  335. package/schema/fixtures/event/valid/audit-gesture-refused.json +19 -0
  336. package/schema/fixtures/event/valid/audit-question-preempted-no-verdict.json +16 -0
  337. package/schema/fixtures/event/valid/audit-question-preempted.json +20 -0
  338. package/schema/fixtures/event/valid/daemon-identity-declared.json +17 -0
  339. package/schema/fixtures/event/valid/daemon-identity.json +15 -0
  340. package/schema/fixtures/event/valid/execution-started-policy-sha256.json +18 -0
  341. package/schema/fixtures/event/valid/gate-path-signed-off.json +14 -0
  342. package/schema/fixtures/event/valid/harness-kind-claude-code.json +23 -0
  343. package/schema/fixtures/event/valid/harness-kind-codex.json +23 -0
  344. package/schema/fixtures/event/valid/harness-kind-cursor.json +23 -0
  345. package/schema/fixtures/event/valid/harness-kind-grok.json +23 -0
  346. package/schema/fixtures/event/valid/harness-kind-hermes.json +23 -0
  347. package/schema/fixtures/event/valid/harness-kind-muse.json +23 -0
  348. package/schema/fixtures/policy/invalid/daemons-malformed-id.json +10 -0
  349. package/schema/fixtures/policy/invalid/senders-half-keyed.json +20 -0
  350. package/schema/fixtures/policy/valid/canonical.json +1 -1
  351. package/schema/fixtures/policy/valid/daemons-allowlist.json +19 -0
  352. package/schema/fixtures/policy/valid/senders-keyed.json +24 -0
  353. package/schema/fixtures/policy-md/invalid/schema-invalid-agent-may-request.md +21 -0
  354. package/schema/fixtures/policy-md/valid/agent-may-request.md +24 -0
  355. package/schema/fixtures/policy-md/valid/canonical.md +1 -1
  356. package/schema/fixtures/policy-md/valid/with-values.md +5 -7
  357. package/schema/fixtures/values/invalid/class-shaped.json +1 -1
  358. package/schema/fixtures/values/invalid/duplicate-entry.json +1 -1
  359. package/schema/fixtures/values/invalid/non-string-item.json +1 -1
  360. package/schema/fixtures/values/invalid/over-cap.json +1 -1
  361. package/schema/fixtures/values/invalid/unknown-key.json +1 -1
  362. package/schema/fixtures/values/invalid/version-float.json +1 -0
  363. package/schema/fixtures/values/invalid/version-integer.json +1 -0
  364. package/schema/fixtures/values/invalid/version-wrong-string.json +1 -0
  365. package/schema/fixtures/values/valid/empty-lists.json +2 -3
  366. package/schema/fixtures/values/valid/full.json +5 -7
  367. package/schema/fixtures/values/valid/minimal.json +1 -1
  368. package/schema/fixtures/values-md/invalid/schema-invalid.md +5 -3
  369. package/schema/fixtures/values-md/invalid/two-blocks.md +3 -3
  370. package/schema/fixtures/values-md/invalid/unterminated.md +2 -2
  371. package/schema/fixtures/values-md/invalid/version-1.md +69 -0
  372. package/schema/fixtures/values-md/invalid/version-unquoted.md +64 -0
  373. package/schema/fixtures/values-md/invalid/yaml-error.md +2 -2
  374. package/schema/fixtures/values-md/valid/absent.md +1 -1
  375. package/schema/fixtures/values-md/valid/with-values.md +5 -7
  376. package/schema/policy.schema.json +100 -4
  377. package/schema/values.schema.json +7 -11
  378. package/schema/fixtures/values/invalid/version-string.json +0 -1
@@ -47,6 +47,10 @@ Usage:
47
47
  [--yes] [--json]
48
48
  approval register <task-file> [--as <id>] [--log <path>] [--json]
49
49
  approval request <task> --action <key> [--as <id>] [--json]
50
+ approval propose --class <c> --key <k> --summary <s> --payload-json <j>
51
+ [--as <id>] [--json]
52
+ approval start <task> --action <key> --payload-json <j> [--as <id>]
53
+ [--json]
50
54
  approval grant|reject|revoke <action-key> [--note <text>] [--as human:<id>] [--json]
51
55
  approval expire <action-key> [--json]
52
56
  approval token <action-key> [--policy <path>] [--dir <path>] [--json]
@@ -54,7 +58,7 @@ Usage:
54
58
  [--as <id>] [--json] (internal)
55
59
  approval run <action-key> [--token <t>] [--payload-hash <64hex>]
56
60
  [--as <id>] [--no-sandbox] [--json] -- <cmd…>
57
- approval sandbox [--allow-loopback] [--log <path>] -- <cmd…>
61
+ approval sandbox [--allow-loopback] [--read-jail] [--log <path>] -- <cmd…>
58
62
  approval adapter email <action-key> [--token <t>] --payload <file|->
59
63
  [--as <id>] [--vault <path>] [--timeout <ms>] [--json]
60
64
  approval adapter agentmail <action-key> [--token <t>] --payload <file|->
@@ -93,6 +97,7 @@ Usage:
93
97
  approval doctor [--log <path>] [--policy <path>] [--dir <path>]
94
98
  [--api-base <url>] [--json]
95
99
  approval payload hash <file|-> [--json]
100
+ approval payload run [--cwd <dir>] [--hash] [--json] -- <cmd…>
96
101
  approval payload agentmail-draft <inbox-id> <draft-id> [--api-base <url>]
97
102
  [--json]
98
103
  approval journal write --message "<text>" | - [--task <id>] [--session <id>]
@@ -121,6 +126,11 @@ Usage:
121
126
  approval codex prepare|setup|doctor|start|serve (strict host workflow)
122
127
  approval mcp serve --as agent:<id> [--dir <path>] [--log <path>]
123
128
  [--policy <path>] (MCP over stdio; foreground)
129
+ approval serve --as agent:<id> [--dir <path>] [--log <path>]
130
+ [--policy <path>] [--port <n> | --listen <host:port>
131
+ | --listen unix:<path>]
132
+ [--allow-non-loopback] (HTTP; foreground)
133
+ approval muse [--dir <path>] [--port <n>] (local prototype; foreground)
124
134
  approval reindex [--log <path>] [--index <path>] [--force] [--json]
125
135
  approval render [--log <path>] [--out <path>] [--policy <path>]
126
136
  [--dir <path>] [--json]
@@ -184,6 +194,12 @@ Ask — an agent declares an action and acts on the answer:
184
194
  request ask the gate to admit a declared action (manual classes append
185
195
  approval.requested; supervised/autonomous append nothing and
186
196
  proceed straight to execution, per amended SPEC.md §6.3)
197
+ propose register and request one action in one call, payload inline as
198
+ JSON, in a class the policy declares by name and opens to agents
199
+ (agent_may_request); retry-safe on the same class, key and bytes
200
+ start record execution.started for a proposed action its requester is
201
+ carrying out: spends the harness grant, or records the policy's
202
+ own authorization for a non-manual class. REQUESTER-ONLY
187
203
  token report whether a live single-use execution token exists for an
188
204
  action (the RAW token is printed once, by grant, and stored nowhere)
189
205
  consume spend a token and append execution.started (internal plumbing;
@@ -204,7 +220,10 @@ Ask — an agent declares an action and acts on the answer:
204
220
  draft the agent composed, refused if the draft changed after the
205
221
  snapshot a human approved
206
222
  wait block until a task's requests are decided; the exit code IS the
207
- decision (0 granted, 1 rejected/revoked/withdrawn, 3 expired, 6 timeout)
223
+ decision (0 granted or nothing-to-wait-for, 1 rejected/revoked/
224
+ withdrawn/not-registered, 3 expired, 6 timeout, 7 void: a
225
+ re-attest voided it, ask again); run only on --json status
226
+ "granted", which means an unspent grant
208
227
  withdraw take back your OWN pending request (timeout, cancelled, superseded);
209
228
  terminal, requester-only, and a late grant then authorizes nothing
210
229
  hook put the gate in front of an agent HARNESS. "hook claude-code" and
@@ -245,6 +264,15 @@ Ask — an agent declares an action and acts on the answer:
245
264
  channels are not published, because an MCP client is an agent's
246
265
  harness and SPEC.md §11 makes the agent the untrusted policy. It
247
266
  runs as ONE agent identity, fixed at startup, that nothing changes
267
+ serve the same agent-facing surface over HTTP, for a harness in a sandbox
268
+ with no local log and no local policy. It adds the three things MCP
269
+ withheld for transport reasons: hook <harness> taking the harness
270
+ envelope as the request body, log follow paged by an exclusive
271
+ (seq, hash) cursor, and the store as an archive. TWO CREDENTIALS
272
+ from the launch environment, and authorization is per verb: the
273
+ agent one opens the hook and an allowlist of what a harness under
274
+ oversight needs to ask and to act on a grant, the tenant one opens
275
+ everything else, so the agent never reads the log it is judged by
248
276
 
249
277
  Decide — a human answers, and only a human can:
250
278
  queue the pending-decision INBOX: requests awaiting a human, inside their
@@ -300,6 +328,9 @@ Inspect — what the log says, and whether anything needs repair:
300
328
  over its RFC 8785 canonical serialization), the value a declaration
301
329
  carries and a grant binds to. Most flows never need it: "request
302
330
  --payload" hashes, verifies and stores the bytes in one step.
331
+ "payload run" prints the payload a gated command binds to: its
332
+ argv, its cwd, and the digest of the script that argv names, so a
333
+ grant over a script binds the script and not its path.
303
334
  "payload agentmail-draft" snapshots one AgentMail draft with the
304
335
  AGENT's key, so a human approves the words and not a draft id
305
336
  daemon "daemon run" is the watch loop of SPEC.md §10.2, in the FOREGROUND:
@@ -607,24 +638,49 @@ const POLICY_MANUAL_BECAUSE = `manualBecause is "matched-rule", "irreversibility
607
638
  export const POLICY_HELP = `approval policy — explain what policy does with an action class
608
639
 
609
640
  Usage:
610
- approval policy check|test <class> [--reversible true|false] [--policy <p>]
611
- [--dir <p>] [--json]
612
- approval policy attest [--policy <p>] [--dir <p>] [--as human:<id>] [--json]
613
- approval policy amend [--policy <p>] [--dir <p>] [--log <p>] [--as human:<id>]
614
- [--require-load] [--dry-run] [--commit] [--yes] [--json]
641
+ approval policy check|test <class> [--reversible true|false] [--policy|--dir <p>] [--json]
642
+ approval policy attest [--policy|--dir <p>] [--as human:<id>] [--json]
643
+ approval policy amend [--policy|--dir|--log <p>] [--as human:<id>] [--require-load]
644
+ [--dry-run] [--commit|--pr] [--yes] [--json]
645
+ approval policy apply <proposal.md> [--dry-run] [--no-amend] [--pr] [--yes]
615
646
 
616
647
  Subcommands:
617
648
  check explain the autonomy resolution for <class>
618
649
  test exact alias of check (SPEC.md §10.1 names both)
619
650
  attest record a human's sign-off on the policy file's bytes (human-only)
620
651
  amend the whole amendment ceremony: diff, advisory, attestation, commit
652
+ apply apply a proposal document's quoted replacements, then amend (human-only)
621
653
 
622
- Nothing is executed, requested, or logged: this reads APPROVAL.md and answers a
623
- hypothetical. Discovery is APPROVAL.md then APPROVALS.md in --dir.
624
- ${POLICY_MANUAL_BECAUSE}
654
+ check and test read APPROVAL.md and answer a hypothetical, executing and logging nothing.
655
+ Discovery is APPROVAL.md then APPROVALS.md in --dir. ${POLICY_MANUAL_BECAUSE}
625
656
 
626
657
  ${POLICY_EXIT_CODES}
627
658
  ${why("policy")}`;
659
+ export const POLICY_APPLY_HELP = `approval policy apply — apply a proposal document to APPROVAL.md, then amend
660
+
661
+ Usage:
662
+ approval policy apply <proposal.md> [--policy <p>] [--dir <p>] [--log <p>]
663
+ [--as human:<id>] [--dry-run] [--no-amend] [--no-publish] [--yes] [--json]
664
+
665
+ Flags:
666
+ <proposal.md> the document whose Current/Replace-with pairs to apply
667
+ --policy <p> / --dir <p> the policy file, or the directory to discover it in
668
+ --dry-run / --no-amend show the replacements only / write them and stop
669
+ --no-publish / --yes / --json stop at the commit / skip both prompts / machine
670
+
671
+ HUMAN-ONLY: an agent identity refuses apply-agent-actor, and the verb classifies
672
+ policy.core, human-only in this project's policy. Every pair resolves against an
673
+ in-memory copy FIRST, so a stale proposal writes nothing at all. A pair is two
674
+ fenced blocks WITH a declared language (APRV-273), labelled \`Current:\` and
675
+ \`Replace with:\` above; \`Supersedes:\` names an earlier section's result to match
676
+ instead. Whole-file replacement is NOT accepted: every byte written is anchored
677
+ to a byte proved present. The values block is treated as the policy block is.
678
+ Refusals: usage, io, apply-agent-actor, proposal-empty, proposal-malformed,
679
+ proposal-stale, proposal-ambiguous. Then it runs \`policy amend --pr\`, which
680
+ PUBLISHES: refspec push, pull request, merge armed, checkout never moved.
681
+
682
+ ${EXIT_CODES_POINTER}
683
+ ${why("policy-apply")}`;
628
684
  function policyVerbHelp(verb, alias) {
629
685
  return `approval policy ${verb} — explain what policy does with an action class
630
686
 
@@ -652,22 +708,22 @@ export const POLICY_TEST_HELP = policyVerbHelp("test", "check");
652
708
  export const POLICY_ATTEST_HELP = `approval policy attest — record a human's sign-off on the policy file
653
709
 
654
710
  Usage:
655
- approval policy attest [--policy <path>] [--dir <path>] [--organ <path>]
656
- [--as human:<id>] [--log <path>] [--json]
711
+ approval policy attest [--policy|--dir <path>] [--organ|--path <path>]
712
+ [--bootstrap] [--as human:<id>] [--log <path>] [--json]
657
713
 
658
714
  Flags:
659
715
  --policy <path> / --dir <path> the policy file, or where to discover it
660
716
  --organ <path> attest a GATE ORGAN instead; one path per call, under --dir
717
+ --path <path> sign off a PROTECTED path's current bytes; one path per call
718
+ --bootstrap a store's FIRST policy only; re-run: policy-already-attested
661
719
  --as human:<id> the human attesting; overrides APPROVAL_HUMAN
662
720
  --log <path> log file to append to (default .approval/log/events.jsonl)
663
- --json machine-readable output
664
- -h, --help this text
721
+ --json / -h, --help machine-readable output / this text
665
722
 
666
- Appends one policy.updated event carrying the SHA-256 of the policy file's exact
667
- bytes; gate operations refuse while it differs ("policy-not-attested").
668
- Human-only, identity CONFIG-DECLARED: the trust boundary is the local machine,
669
- so it proves someone with local control signed off, not who. Bytes, not parse.
670
- --organ appends gate.organ.attested for a policy.core harness file instead.
723
+ Appends policy.updated with the file's exact SHA-256; gates refuse while it
724
+ differs ("policy-not-attested"). Bytes, not parse. Human-only, CONFIG-DECLARED:
725
+ the trust boundary is the local machine (local control, not who). No TTY needed.
726
+ --organ appends gate.organ.attested (policy.core); --path gate.path.signed_off.
671
727
 
672
728
  JSON shape: docs/cli-reference.md#policy-attest
673
729
  ${EXIT_CODES_POINTER}
@@ -677,22 +733,22 @@ export const POLICY_AMEND_HELP = `approval policy amend — the whole amendment
677
733
 
678
734
  Usage:
679
735
  approval policy amend [--policy|--dir|--log <p>] [--as human:<id>|agent:<id>] [--require-load]
680
- [--dry-run] [--commit] [--no-publish] [--yes] [--json] [--branch <n>|--direct] [--wait <d>]
736
+ [--dry-run] [--commit|--pr] [--no-publish] [--yes] [--json] [--branch <n>|--direct] [--wait <d>]
681
737
 
682
738
  Flags:
683
739
  --policy <p> / --dir <p> / --log <p> policy, its discovery dir, and the log
684
740
  --as human:<id> / agent:<id> attest HERE, or ask for a TAP (--wait/--interval/--note)
685
741
  --require-load refuse to attest a policy that does not load
686
742
  --dry-run / --commit / --no-publish write nothing / the ceremony / stop at commit
687
- --branch <name> / --direct force the BRANCH or the DIRECT flow
743
+ --pr / --branch <name> / --direct FINISH it (branch, push, PR, arm) / force either flow
688
744
  --yes / --json / -h, --help skip the prompt / machine-readable / this text
689
745
 
690
- Hashes the policy, diffs it against the BASELINE (classes AND every policy key), attests, then
691
- commits EXACTLY the policy, the log and the pins when they moved. commit-preconditions, the pins
692
- and the DOGFOOD SUITE refuse BEFORE the append; git-failed, push-rejected, pr-failed break after it.
693
- Attested TEXT is NOT recoverable from the log: HASH-ONLY MODE. Flows, in PRECEDENCE, highest first:
694
- --branch <name>, --direct; a refused push PUBLISHES ITSELF, dropping to a RUNBOOK. MERGE COMMIT it.
695
- --as agent: appends policy.proposed; the TAP attests. Fail closed: no-channel, declined, timeout.
746
+ Hashes the policy, diffs it against the BASELINE (classes AND every policy key), attests, then commits
747
+ EXACTLY the policy, the log and the pins when they moved. commit-preconditions, staged-unrelated,
748
+ dirty-tree, the pins and the DOGFOOD SUITE refuse BEFORE the append; git-failed, push-rejected and
749
+ pr-failed break after it, into a RUNBOOK. Attested TEXT is NOT recoverable from the log:
750
+ HASH-ONLY MODE. Flows, in PRECEDENCE, highest first: --branch <name>, --pr (opens or UPDATES the open
751
+ pull request, arms --auto), --direct. MERGE COMMIT it. --as agent: appends policy.proposed, TAP attests.
696
752
 
697
753
  ${EXIT_CODES_POINTER}
698
754
  ${JSON_ERRORS}
@@ -754,6 +810,45 @@ JSON shape: docs/cli-reference.md#request
754
810
  ${GATE_CODES_POINTER}
755
811
  ${JSON_ERRORS}
756
812
  ${why("request")}`;
813
+ export const PROPOSE_HELP = `approval propose — register and request one action, payload inline
814
+
815
+ Usage:
816
+ approval propose --class <c> --key <k> --summary <text> --payload-json <json>
817
+ [--as <id>] [--policy <p>] [--dir <p>] [--log <p>] [--json]
818
+
819
+ Flags:
820
+ --class <c> an EXACT key of the policy's classes, opened to agents by
821
+ agent_may_request: true on it or a <prefix>.* family
822
+ --key <k> "<class>:<id>", recorded verbatim as action_key (≤1 KiB)
823
+ --summary <text> the line the approver reads (in the log, in cleartext)
824
+ --payload-json <j> the payload, a JSON object of at most 262144 bytes
825
+ --as <id> human:<id> or agent:<id>; else APPROVAL_HUMAN
826
+
827
+ decision "requested": poll \`approval wait <task> --timeout 0\` (7 void or 3
828
+ expired: propose again). "autonomous"/"supervised": act, then \`approval start\`.
829
+ A retry appends nothing (idempotent:true) unless the answer can't be used.
830
+
831
+ ${GATE_CODES_POINTER}
832
+ ${JSON_ERRORS}
833
+ ${why("propose")}`;
834
+ export const START_HELP = `approval start — record that you are carrying out a proposed action
835
+
836
+ Usage:
837
+ approval start <task> --action <key> --payload-json <json> [--as <id>]
838
+ [--policy <p>] [--dir <p>] [--log <p>] [--json]
839
+
840
+ Flags:
841
+ --action <key> the action's idempotency key (required)
842
+ --payload-json <j> the bytes you act on; must hash to the registered binding
843
+ --as <id> human:<id> or agent:<id>; else APPROVAL_HUMAN
844
+
845
+ Appends one execution.started, once per key. REQUESTER-ONLY. A key with a
846
+ request spends its harness grant; a key with none is recorded as authorized by
847
+ the policy, and a manual class is refused.
848
+
849
+ ${GATE_CODES_POINTER}
850
+ ${JSON_ERRORS}
851
+ ${why("start")}`;
757
852
  function decisionHelp(verb) {
758
853
  const noun = verb === "grant" ? "approval" : verb === "reject" ? "refusal" : "withdrawal";
759
854
  const body = verb === "grant"
@@ -958,19 +1053,21 @@ ${why("run")}`;
958
1053
  export const SANDBOX_HELP = `approval sandbox — run a command with no way out (APRV-193)
959
1054
 
960
1055
  Usage:
961
- approval sandbox [--allow-loopback] [--log <path>] -- <cmd> [args…]
1056
+ approval sandbox [--allow-loopback] [--read-jail] [--log <path>] -- <cmd…>
962
1057
 
963
1058
  Flags:
964
1059
  --allow-loopback also allow connections to localhost. For a suite that
965
1060
  starts its own server. A real widening: a port is a port
1061
+ --read-jail also deny file reads outside the gate root and the scratch
1062
+ roots. Already on when the policy declares read_scope, and
1063
+ nothing turns it off where it did (APRV-347)
966
1064
  --log <path> the log, so the credential material beside it can be made
967
1065
  unreadable to the child (vault, env map, sealing keys)
968
1066
  -h, --help this text ("--help --long" adds the reference section)
969
1067
 
970
- Denies the child outbound network (macOS sandbox-exec), scrubs the
971
- credential-bearing variables out of its environment, and exits with the child's
972
- own exit code. It appends NOTHING: it removes a capability rather than
973
- authorizing anything, and the gate stays reachable because its IPC is a file.
1068
+ Denies outbound network (macOS sandbox-exec), scrubs the credential variables
1069
+ from the child's environment, exits with its code, and appends NOTHING: it
1070
+ removes a capability rather than authorizing anything.
974
1071
 
975
1072
  The point is laundered exec: "npm test" runs whatever was written a minute ago,
976
1073
  so the command's NAME stopped describing its effect. An agent HARNESS cannot run
@@ -985,7 +1082,7 @@ Usage:
985
1082
  [--as <id>] [--policy <p>] [--dir <p>] [--log <p>] [--json]
986
1083
 
987
1084
  Flags:
988
- --timeout <d> how long to wait, in the duration grammar (e.g. 6h). Required
1085
+ --timeout <d> how long to wait (e.g. 6h; 0 reads the state once). Required
989
1086
  --interval <d> poll interval (default 500ms)
990
1087
  --withdraw-on-timeout on timeout, withdraw the requests THIS actor opened
991
1088
  --as <id> the withdrawing actor; read only with the flag above
@@ -993,12 +1090,12 @@ Flags:
993
1090
  --json machine-readable output; -h, --help this text
994
1091
 
995
1092
  Polls until every approval.requested of the task has a decision, or the timeout
996
- elapses. WRITES NOTHING unless --withdraw-on-timeout. Only the MANUAL path
997
- produces requests to wait for; a task with none returns at once, exit 0.
1093
+ elapses. WRITES NOTHING unless --withdraw-on-timeout. Only the MANUAL path makes
1094
+ requests; none left to wait on is exit 0, nothing-to-wait-for, never granted.
998
1095
 
999
1096
  JSON shape: docs/cli-reference.md#wait
1000
- ${EXIT_CODES_POINTER}. THE CODE IS THE DECISION: 0 granted, 1 rejected, revoked
1001
- or withdrawn (--json status says which), 3 expired, 4 I/O, and
1097
+ ${EXIT_CODES_POINTER}. THE CODE IS THE DECISION: 0 granted or nothing-to-wait-for,
1098
+ 1 rejected/revoked/withdrawn/not-registered (--json says which), 3 expired, 4 I/O, 7 VOID, and
1002
1099
  6 TIMEOUT — the wait elapsed with request(s) still undecided.
1003
1100
  ${JSON_ERRORS}
1004
1101
  ${why("wait")}`;
@@ -1039,9 +1136,9 @@ Flags:
1039
1136
 
1040
1137
  THIS IS NOT "approval queue": queue is what a human must answer, status is what
1041
1138
  an operator must fix. Writes nothing, and reports in one object: attestation,
1042
- verification, dangling executions, budget headroom per global limit,
1043
- loop_escalations, harness_outcomes, git coverage, payload_store, and anomalies
1044
- when there are any. The coverage numbers move neither health nor the exit code.
1139
+ verification, dangling executions, budget headroom, loop_escalations,
1140
+ harness_outcomes, payload_store, git coverage, the daemon id, plus anomalies and
1141
+ refusals when there are any. The last three report rather than judge.
1045
1142
 
1046
1143
  JSON shape: docs/cli-reference.md#status
1047
1144
  ${EXIT_CODES_POINTER} (1 when anything needs attention, including a torn tail)
@@ -1292,14 +1389,13 @@ Usage:
1292
1389
  approval channel web [--port <n>] [--payload-dir <path>] [--as human:<id>]
1293
1390
  [--policy <path>] [--dir <path>] [--log <path>] [--json]
1294
1391
  approval channel telegram listen|health [--once] [--as human:<id>] [--json]
1392
+ approval channel relay [--listen [host:]port | --port <n>] [--proposer <a>] [--json]
1295
1393
 
1296
1394
  Subcommands:
1297
- cli render the pending queue in this terminal and, when it IS a
1298
- terminal, collect decisions with a prompt
1299
- web serve the pending queue as a page on 127.0.0.1 ONLY, with
1300
- Grant/Reject forms and a batch gesture
1301
- telegram deliver the queue to a Telegram chat and long-poll for
1302
- Approve/Reject taps
1395
+ cli render the pending queue here; on a terminal, collect decisions
1396
+ web the queue as a page on 127.0.0.1 ONLY, with Grant/Reject forms
1397
+ telegram deliver the queue to a Telegram chat; collect Approve/Reject taps
1398
+ relay take gestures an operator's authenticated relay carries (EdgeOS)
1303
1399
 
1304
1400
  A channel is TRANSPORT: it renders what the runtime derived and reports the
1305
1401
  gesture a human made. Every decision collected here is recorded by the same
@@ -1408,27 +1504,103 @@ ${why("quickstart")}`;
1408
1504
  export const HOOK_HELP = `approval hook — put the gate in front of an agent harness
1409
1505
 
1410
1506
  Usage:
1411
- approval hook claude-code|cursor|codex [--as agent:<id>] [--timeout <d>] [--interval <d>] [--retry-grace <d>] [--policy <p>] [--dir <p>] [--log <p>]
1507
+ approval hook claude-code|cursor|codex|grok|muse|hermes [--as agent:<id>] [--timeout <d>] [--interval <d>] [--retry-grace <d>] [--harness-cap <d>] [--policy <p>] [--dir <p>] [--log <p>]
1412
1508
  approval hook classify [--json] [--policy <p>] [--dir <p>] -- <command…>
1413
1509
 
1414
1510
  Commands:
1415
1511
  claude-code Claude Pre/PostToolUse JSON in; decision JSON out. REGISTER BOTH
1416
1512
  cursor Cursor preToolUse JSON in; native {permission} JSON out
1417
1513
  codex Codex synchronous Pre/Post JSON; Bash denied, direct apply_patch experimentally gated
1514
+ grok Grok Build camelCase Pre/PostToolUse JSON in; {decision,reason} out, DENY IS EXIT 2. \`approval hook grok --help\` prints the config
1515
+ muse Muse Code snake_case Pre/PostToolUse; ONE dialect out or it fails open. \`approval hook muse --help\` prints the config
1516
+ hermes Hermes Agent snake_case pre_tool_call/post_tool_call; {action,message} out, DENY IS EXIT 2, allow is {}. fail_closed: true BLOCKS a broken hook (observed on main 118984d7; default false, and v0.21.3 ignores it silently). \`approval hook hermes --help\` prints the YAML
1418
1517
  classify print what the classifier makes of a command line and exit
1419
-
1420
- --as <id> proposing identity (default agent:claude-code / agent:cursor / agent:codex)
1421
- --timeout/--interval/--retry-grace <d> wait / poll / hold for a retry (9m/1s/5m)
1518
+ --as <id> proposing identity (default agent:<harness>)
1519
+ --timeout/--interval/--retry-grace/--harness-cap <d> wait / poll / hold for a retry / the harness's OWN kill timeout (9m/1s/5m/none), which lapses the request 60s inside it so approval.expired lands first
1422
1520
  --dir/--policy/--log <p> policy+log root; --dir sets BOTH, default primary
1423
1521
  -h, --help this text
1424
-
1425
1522
  Codex opt-in: register exact Bash|apply_patch synchronously with timeout 600s (default wait 9m). Bash is denied because native events hide per-call workdir; direct apply_patch is experimental. PostToolUse is diagnostic.
1426
1523
 
1427
- Deny: hook-unclassified, hook-class-human-only, hook-opaque, hook-unparseable, hook-rejected, hook-revoked, hook-expired, hook-withdrawn, hook-timeout,
1428
- hook-gate-refused:<c>, hook-grant-unverified, hook-sandbox-required, hook-policy-unavailable, hook-log-unreachable, hook-io.
1524
+ Deny: hook-unclassified, hook-class-human-only, hook-harness-launch-unruled, hook-opaque, hook-unparseable, hook-rejected, hook-revoked, hook-expired, hook-withdrawn, hook-timeout, hook-harness-cap-too-short,
1525
+ hook-gate-refused:<c>, hook-grant-unverified, hook-sandbox-required, hook-policy-unavailable, hook-log-unreachable, hook-unsupported-execution-context, hook-muse-contributor-model, hook-hermes-execute-code-unbound, hook-io.
1429
1526
 
1430
1527
  ${EXIT_CODES_POINTER} (harness verbs use 0 and 2 only; 0 is a verdict, never "ask")
1431
1528
  ${why("hook")}`;
1529
+ export const HOOK_GROK_HELP = `approval hook grok — the gate in front of Grok Build (APRV-243)
1530
+
1531
+ Usage:
1532
+ approval hook grok [--as agent:<id>] [--timeout <d>] [--interval <d>]
1533
+ [--retry-grace <d>] [--harness-cap <d>] [--policy <p>] [--dir <p>] [--log <p>]
1534
+
1535
+ camelCase in (hookEventName, sessionId, cwd, workspaceRoot, toolName, toolInput);
1536
+ {"decision":"allow"|"deny","reason":"…"} out, never "ask". DENY IS EXIT 2,
1537
+ allow is 0, post-execution always 0.
1538
+
1539
+ READ docs/grok-hook.md BEFORE COMMITTING THIS: Grok Build fails OPEN on hook
1540
+ timeout, crash and malformed output, with no setting to change that. It
1541
+ contradicts the fail-closed invariant and the adapter cannot fix it.
1542
+
1543
+ The file the human commits, .grok/hooks/pre-tool-use.json:
1544
+ {"hooks":{"PreToolUse":[{"matcher":"*","hooks":[
1545
+ {"type":"command","command":"approval hook grok --dir <repo>",
1546
+ "timeout": 600}]}]}}
1547
+
1548
+ That "timeout" MUST EXCEED --timeout (default 9m), or Grok abandons the call
1549
+ mid-wait and, failing open, runs the command while a human is still deciding.
1550
+ .grok/hooks/ classifies policy.core, like .cursor/hooks.json.
1551
+
1552
+ ${EXIT_CODES_POINTER} (0 allow, 2 deny; never "ask")
1553
+ ${why("hook")}`;
1554
+ export const HOOK_MUSE_HELP = `approval hook muse — the gate in front of Meta Muse Code (APRV-350)
1555
+
1556
+ Usage:
1557
+ approval hook muse [--as agent:<id>] [--timeout <d>] [--interval <d>]
1558
+ [--retry-grace <d>] [--harness-cap <d>] [--policy <p>] [--dir <p>] [--log <p>]
1559
+ snake_case in (hook_event_name, tool_name, tool_input, cwd, model); ONE dialect
1560
+ out, nested {"hookSpecificOutput":{"permissionDecision":…}} at exit 0, never
1561
+ "ask". Tools: bash (per-call workdir), write_file, read_file, search.
1562
+
1563
+ READ docs/muse-hook.md FIRST. Muse fails OPEN on hook crash, timeout and
1564
+ malformed output — and output MIXING dialects is itself malformed, so a payload
1565
+ satisfying every harness at once satisfies this one not at all.
1566
+ CONTRIBUTOR MODELS ARE REFUSED (hook-muse-contributor-model) on every tool call
1567
+ regardless of policy: Meta trains on that tier. The guard stops tool calls; it
1568
+ cannot recall a prompt already sent.
1569
+ The file the human commits, .muse/hooks.json (no "matcher"; policy.core):
1570
+ {"hooks":{"PreToolUse":[{"hooks":[
1571
+ {"type":"command","command":"approval hook muse --dir <repo>",
1572
+ "timeout": 600}]}],"PostToolUse":[{"hooks":[
1573
+ {"type":"command","command":"approval hook muse --dir <repo>",
1574
+ "timeout": 600}]}]}}
1575
+ That "timeout" MUST EXCEED --timeout (9m), or Muse abandons the call mid-wait
1576
+ and, failing open, runs it while a human is still deciding.
1577
+ ${EXIT_CODES_POINTER} (0 for every verdict; deny is the body, not the code)
1578
+ ${why("hook")}`;
1579
+ export const HOOK_HERMES_HELP = `approval hook hermes — the gate in front of Hermes Agent (APRV-398)
1580
+ Usage:
1581
+ approval hook hermes [--as agent:<id>] [--timeout <d>] [--interval <d>]
1582
+ [--retry-grace <d>] [--harness-cap <d>] [--policy <p>] [--dir <p>] [--log <p>]
1583
+ snake_case in (hook_event_name pre_tool_call|post_tool_call, tool_name, tool_input).
1584
+ ONE dialect out: {"action":"block","message":"…"} AT EXIT 2 deny, {} at exit 0 allow
1585
+ (no allow directive; reason on stderr). Tools: terminal (command + ABSOLUTE workdir),
1586
+ write_file, patch, read_file, search_files. REFUSED: execute_code
1587
+ (hook-hermes-execute-code-unbound), and a call with no absolute workdir or a relative
1588
+ or missing path (hook-unsupported-execution-context): Hermes resolves those against a session directory no event reports.
1589
+ OBSERVED on main 118984d7: fail_closed: true BLOCKS hook crash, timeout and garbage.
1590
+ ITS DEFAULT IS false, and v0.21.3 (2026.9.14) fails open SILENTLY: run a 2026-09-20+ build.
1591
+ No hooks_auto_accept and no TTY: Hermes SILENTLY SKIPS REGISTERING THE HOOK. --dir IS MANDATORY (a gateway session's cwd is the user HOME); docs/hermes-hook.md has the evidence.
1592
+ The file the human commits, $HERMES_HOME/config.yaml — the home's LAST SEGMENT must be .hermes or the classifier does not see the organ (export HERMES_HOME=/Users/you/dev/hermes/.hermes; policy.core):
1593
+ plugins: { hook_callback_timeout: 600 }
1594
+ hooks_auto_accept: true
1595
+ hooks:
1596
+ pre_tool_call:
1597
+ - { command: "approval hook hermes --dir <repo> --timeout 4m --harness-cap 300s", timeout: 300, fail_closed: true }
1598
+ post_tool_call:
1599
+ - { command: "approval hook hermes --dir <repo> --timeout 4m", timeout: 300 }
1600
+ The entry "timeout" caps at 300s; hook_callback_timeout (default 30s) fails closed
1601
+ by itself, so --timeout MUST BE UNDER 300s (4m). WITHOUT --harness-cap the hook assumes the 30s default and denies every manual call hook-harness-cap-too-short: raise hook_callback_timeout above the entry timeout, then pass --harness-cap <the smaller of the two>. The window is then cap-60s (240s above) or approval_ttl, whichever is shorter. Register BOTH events. Long form:
1602
+ ${EXIT_CODES_POINTER} (0 allow, 2 deny; post_tool_call always 0; never "ask")
1603
+ ${why("hook")}`;
1432
1604
  export const IMPORT_HELP = `approval import — turn existing permissions prose into a draft policy
1433
1605
 
1434
1606
  Usage:
@@ -1455,7 +1627,7 @@ Reads one markdown file, finds its permissions section, and prints a DRAFT
1455
1627
  \`\`\`yaml approval-policy block from a fixed, ordered keyword table.
1456
1628
  THE DRAFT AUTHORIZES NOTHING: this verb never writes APPROVAL.md, never logs and
1457
1629
  never attests. Fail closed: a bullet the table cannot place is kept verbatim.
1458
- "What I value"-style headings become a DRAFT values fence, all under \`wants\`.
1630
+ "What I value"-style headings become a DRAFT values fence, all under \`like\`.
1459
1631
 
1460
1632
  JSON shape (stdout, one object):
1461
1633
  {"ok":true,"source":"<path>","out":"<path>"|null,
@@ -1470,12 +1642,15 @@ export const PAYLOAD_HELP = `approval payload — work with the bytes an approva
1470
1642
 
1471
1643
  Usage:
1472
1644
  approval payload hash <file|-> [--json]
1645
+ approval payload run [--cwd <dir>] [--hash] [--json] -- <cmd…>
1473
1646
  approval payload agentmail-draft <inbox-id> <draft-id> [--api-base <url>]
1474
1647
  [--json]
1475
1648
 
1476
1649
  Commands:
1477
1650
  hash print the payload_hash of a JSON document: SHA-256 over its RFC 8785
1478
1651
  canonical serialization (SPEC.md §6.2)
1652
+ run print the payload \`approval run\` will recompute for a command: its
1653
+ argv, its cwd, and the digest of the script that argv names
1479
1654
  agentmail-draft
1480
1655
  snapshot one AgentMail draft as the payload a grant can bind to,
1481
1656
  read with the AGENT's key from AGENTMAIL_API_KEY
@@ -1507,6 +1682,30 @@ JSON shape (stdout, one object): {"ok":true,"hash":"<64hex>"}
1507
1682
  ${EXIT_CODES_POINTER}
1508
1683
  ${JSON_ERRORS}
1509
1684
  ${why("payload-hash")}`;
1685
+ export const PAYLOAD_RUN_HELP = `approval payload run — the payload a gated command binds to
1686
+
1687
+ Usage:
1688
+ approval payload run [--cwd <dir>] [--hash] [--json] -- <cmd…>
1689
+
1690
+ Flags:
1691
+ --cwd <dir> the directory the command will run in (default: this one)
1692
+ --hash print the payload_hash instead of the payload bytes
1693
+ --json / -h, --help machine-readable (with --hash) / this text
1694
+
1695
+ Prints what \`approval run\` recomputes before it spawns:
1696
+ {"argv":[…],"cwd":"…","script":{"argv_index":N,"path":…,bytes,sha256}}
1697
+
1698
+ THE SCRIPT IS THE POINT (APRV-401): a known interpreter followed by a path, or
1699
+ a path at argv[0], binds THAT FILE'S BYTES, so a script edited before the run is
1700
+ payload-mismatch rather than a silent substitution. An argv naming no script
1701
+ carries no "script" key and hashes as it always did. NOT bound: an inline
1702
+ program, the interpreter, an unlisted launcher, what the script itself runs.
1703
+
1704
+ approval payload run --hash -- bash install.sh # the declaration
1705
+ approval payload run -- bash install.sh | approval request … --payload -
1706
+ ${EXIT_CODES_POINTER}
1707
+ ${JSON_ERRORS}
1708
+ ${why("payload-run")}`;
1510
1709
  export const PAYLOAD_AGENTMAIL_DRAFT_HELP = `approval payload agentmail-draft — snapshot a draft as an approvable payload
1511
1710
 
1512
1711
  Usage:
@@ -1611,8 +1810,8 @@ Flags:
1611
1810
  --json / -h, --help machine-readable output / this text
1612
1811
 
1613
1812
  Prints the optional \`\`\`yaml approval-values block of APPROVAL.md: what the
1614
- operator loves, likes and dislikes, what they want from you as behaviour, and
1615
- how they read and answer. EVERY FORM CARRIES THE LABEL: this is GUIDANCE and
1813
+ operator loves, likes (including what they ask of you as behaviour) and
1814
+ dislikes, and how they read and answer. EVERY FORM CARRIES THE LABEL: this is GUIDANCE and
1616
1815
  never policy. It grants nothing, forbids nothing and changes no verdict; what
1617
1816
  you MAY do is the policy block, answered by \`approval policy check\`.
1618
1817
 
@@ -1676,19 +1875,23 @@ ${why("render")}`;
1676
1875
  export const TELEGRAM_HELP = `approval channel telegram — the Telegram push channel
1677
1876
 
1678
1877
  Usage:
1679
- approval channel telegram listen [--once] [--as human:<id>] [--payloads <f>]
1680
- [--policy <path>] [--dir <path>]
1681
- [--log <path>] [--api-base <url>]
1682
- [--poll-timeout <seconds>] [--json]
1683
- approval channel telegram health [--json]
1878
+ approval channel telegram listen [--once] [--as human:<id>] [--payloads <f>]
1879
+ [--policy <p>] [--dir <p>] [--log <p>] [--api-base <url>] [--poll-timeout <s>] [--json]
1880
+ approval channel telegram webhook --url <https://...> [--listen [host:]port]
1881
+ [--path <p>] [--cycle <d>] and every listen flag above
1882
+ approval channel telegram health [--dir <path>] [--log <path>] [--json]
1883
+
1884
+ Two transports, MUTUALLY EXCLUSIVE per bot: listen long-polls getUpdates;
1885
+ webhook has Telegram post each update to a url you register (no poller).
1684
1886
 
1685
1887
  Configuration is ENVIRONMENT-ONLY: APPROVAL_TG_TOKEN holds the bot token and
1686
- APPROVAL_TG_CHAT the approver chat id. APPROVAL.md carries only those variable
1687
- NAMES, and there is no flag that would put a bot token into a shell history.
1888
+ APPROVAL_TG_CHAT the approver chat id; APPROVAL.md carries only those NAMES,
1889
+ and no flag puts a bot token into a shell history.
1688
1890
 
1689
1891
  Anyone in the configured chat can approve as the actor this process was started
1690
1892
  with, so the chat's membership is part of your trust boundary. Use a private
1691
- chat with the bot.
1893
+ chat with the bot — or map senders: approvers.<id>.senders.telegram: "<id>"
1894
+ records each decision against the attested person and refuses every other account.
1692
1895
 
1693
1896
  ${EXIT_CODES_POINTER}
1694
1897
  ${JSON_ERRORS}
@@ -1707,7 +1910,7 @@ Flags:
1707
1910
  --as human:<id> the approver every decision is recorded against. REQUIRED
1708
1911
  --payloads <f> OPTIONAL OVERRIDE: JSON file of action key -> payload
1709
1912
  --policy <p> / --dir <p> / --log <p> the policy, its dir, the log written to
1710
- --api-base <url> / --poll-timeout <s> Bot API base / long-poll seconds (25)
1913
+ --api-base <url> / --poll-timeout <s> / --allow-cross-instance Bot API base / long-poll seconds (25) / start on another instance's bot
1711
1914
  -h, --help this text
1712
1915
  Config is ENVIRONMENT-ONLY and the policy names the variables. Delivery is per cycle;
1713
1916
  a new request reaches the phone without restart. THE TOKEN IS PRINTED HERE, NEVER SENT TO TELEGRAM.
@@ -1717,6 +1920,54 @@ JSON shape: docs/cli-reference.md#channel-telegram-listen
1717
1920
  ${EXIT_CODES_POINTER}
1718
1921
  ${JSON_ERRORS}
1719
1922
  ${why("channel-telegram-listen")}`;
1923
+ export const TELEGRAM_WEBHOOK_HELP = `approval channel telegram webhook — decisions arrive by webhook, no poller
1924
+
1925
+ Usage:
1926
+ approval channel telegram webhook --url <https://host/path> [--path <p>]
1927
+ [--listen [host:]port | --port <n>] [--allow-non-loopback] [--cycle <d>]
1928
+ [--reclaim] [--as human:<id>] [--policy <p>] [--dir <p>] [--log <p>]
1929
+ [--payloads <f>] [--api-base <url>] [--no-gloss] [--json]
1930
+
1931
+ Flags:
1932
+ --url <https://...> REQUIRED: the PUBLIC url registered with setWebhook. https only, on port 443, 80, 88 or 8443 (Telegram's list), and no user:password
1933
+ --port <n> / --listen <[host:]port> this process's own bind. LOOPBACK by default (4683); routable also needs --allow-non-loopback. Never 0
1934
+ --path <p> / --cycle <d> must equal the url's own path / dispatch period (30s)
1935
+ --reclaim register over the webhook already holding this bot
1936
+ -h, --help this text
1937
+
1938
+ APPROVAL_TG_WEBHOOK_SECRET is REQUIRED, from the launch environment: it is
1939
+ Telegram's secret_token, echoed on every delivery, and a post without the
1940
+ matching header is refused and never a decision. NO TLS HERE: plain HTTP
1941
+ behind a proxy or tunnel you own (--url names it); long polling then refuses.
1942
+
1943
+ JSON shape: docs/cli-reference.md#channel-telegram-webhook
1944
+ ${EXIT_CODES_POINTER}
1945
+ ${JSON_ERRORS}
1946
+ ${why("channel-telegram-webhook")}`;
1947
+ export const CHANNEL_RELAY_HELP = `approval channel relay — gestures an operator's authenticated relay carries
1948
+
1949
+ Usage:
1950
+ approval channel relay [--listen [host:]port | --port <n>] [--allow-non-loopback]
1951
+ [--proposer agent:<id>] [--policy <p>] [--dir <p>] [--log <p>] [--json]
1952
+
1953
+ Flags:
1954
+ --port <n> / --listen <[host:]port> LOOPBACK by default (4684); routable also needs --allow-non-loopback
1955
+ --proposer <actor> who a propose gesture is recorded under (default agent:edgeos-relay)
1956
+ -h, --help this text
1957
+
1958
+ APPROVAL_RELAY_SECRET is REQUIRED, from the launch environment: the control
1959
+ plane sends it in x-approval-relay-secret, and a post without it is refused
1960
+ and never written to the log. POST /relay/gesture takes one closed JSON body:
1961
+ propose, attest or decline a policy by sha256, or grant or reject a request by
1962
+ action key, each with a nonce and issued_at. The sender is an EdgeOS id, and
1963
+ it is resolved against approvers.<id>.senders.edgeos in the policy in force:
1964
+ an unmapped account is refused sender-unmapped. This process holds NO human
1965
+ identity and NO TLS. Trust: the daemon trusts the relay's attribution.
1966
+
1967
+ JSON shape: docs/cli-reference.md#channel-relay
1968
+ ${EXIT_CODES_POINTER}
1969
+ ${JSON_ERRORS}
1970
+ ${why("channel-relay")}`;
1720
1971
  export const TELEGRAM_HEALTH_HELP = `approval channel telegram health — is this runtime configured for Telegram?
1721
1972
 
1722
1973
  Usage:
@@ -1796,7 +2047,7 @@ Flags (every "daemon run" flag, unchanged, plus):
1796
2047
  --payloads <f> / --payload-dir <d> payload overrides: telegram / web
1797
2048
  --api-base <url> / --poll-timeout <s> Bot API base / long-poll seconds
1798
2049
  --port <n> queue-page port. Precedence: --port, channels.web.port
1799
- --no-telegram / --no-web leave that channel out of this process
2050
+ --no-telegram / --no-web / --allow-cross-instance leave that channel out / start on another instance's bot
1800
2051
  --no-gloss / --restart-backoff <d> drop gloss / first retry wait
1801
2052
  --gloss-provider <p> / --gloss-model <id> choose claude|codex (default claude); Codex requires model; no fallback
1802
2053
  -h, --help this text
@@ -2030,14 +2281,14 @@ ${why("env")}`;
2030
2281
  export const SETUP_HELP = `approval setup — interactive configuration (SPEC.md §5.2, §10.1)
2031
2282
 
2032
2283
  Usage:
2033
- approval setup identity|vault|sampling|checkpoint [--as human:<id>] …
2284
+ approval setup identity|vault|sampling|sender-key|checkpoint [--as human:<id>] …
2034
2285
  approval setup channel|adapter <name> [--api-base <url>] [--as human:<id>] …
2035
2286
  approval setup service [--platform launchd|systemd] [--uninstall] …
2036
-
2037
2287
  Subcommands:
2038
2288
  identity declare who the human is (APPROVAL_HUMAN); not human-only
2039
2289
  vault mint a vault passphrase, store it, and record where it lives
2040
2290
  sampling mint the audit sampling secret and print the policy line for it
2291
+ sender-key mint the key that hashes sender ids; --id prints one mapping line
2041
2292
  checkpoint mint the Ed25519 key you sign the log's head with (--rotate/--retire)
2042
2293
  channel configure one CHANNEL's transport credential (OS keystore)
2043
2294
  adapter fill the VAULT with one ADAPTER's credentials, from its manifest
@@ -2110,6 +2361,28 @@ does not edit an attested policy file: it prints the block to add and the
2110
2361
  ${EXIT_CODES_POINTER}
2111
2362
  ${JSON_ERRORS}
2112
2363
  ${why("setup-sampling")}`;
2364
+ export const SETUP_SENDER_KEY_HELP = `approval setup sender-key — mint the key that hashes sender ids (HUMAN-ONLY)
2365
+
2366
+ Usage:
2367
+ approval setup sender-key [--as human:<id>] [--log <path>] [--dir <path>]
2368
+ approval setup sender-key --id <account-id> [--log <path>] [--json]
2369
+
2370
+ Bare, it mints the operator-held key that turns a channel account id into the
2371
+ value an approvers[id].senders block carries, stores it as approval-sender-key,
2372
+ and writes its source line. It edits no policy file (APRV-370).
2373
+
2374
+ WITH --id it mints and stores nothing: it reads the key from the environment,
2375
+ prints the hmac-sha256:<hex> for that account, and prints the senders line and
2376
+ the paste-ready proposal pair around it. Run \`eval "$(approval env)"\` first.
2377
+ That is the one setup path that needs no terminal.
2378
+
2379
+ A LISTENER THAT HOLDS NO KEY UNDER A KEYED MAPPING REFUSES EVERY DECISION on
2380
+ that channel (sender-key-unavailable), never falling back to a raw comparison.
2381
+ The key authenticates nothing; losing it costs the ability to resolve accounts.
2382
+
2383
+ ${EXIT_CODES_POINTER}
2384
+ ${JSON_ERRORS}
2385
+ ${why("setup-sender-key")}`;
2113
2386
  export const SETUP_CHECKPOINT_HELP = `approval setup checkpoint — mint the log-checkpoint key (HUMAN-ONLY)
2114
2387
 
2115
2388
  Usage:
@@ -2290,26 +2563,28 @@ ${why("setup-service")}`;
2290
2563
  // ---------------------------------------------------------------------------
2291
2564
  // The MCP wrapper (APRV-87)
2292
2565
  // ---------------------------------------------------------------------------
2293
- export const CODEX_HELP = `approval codex — prepare and inspect a constrained Codex host bundle (INERT)
2566
+ export const CODEX_HELP = `approval codex — prepare a constrained Codex host and broker its workspace writes
2294
2567
 
2295
2568
  Usage:
2296
2569
  approval codex prepare --instance <id> --workspace <abs> --primary <abs>
2297
2570
  --install-root <abs> --output <new-dir> --codex <abs> --node <abs> [--json]
2298
2571
  approval codex setup --check <bundle-dir> [--json]
2299
2572
  approval codex doctor --strict --manifest <abs> [--json]
2300
- approval codex start|serve --manifest <abs> [--json]
2301
-
2302
- prepare writes a fresh review bundle only. setup --check verifies its closed file
2303
- set, hashes, manifest and generated templates. Neither installs a package, edits
2304
- Codex configuration, creates principals, loads services, reads credentials, or
2305
- changes policy. doctor fails closed on unknown custody, executes no manifest
2306
- binary in this slice, and reports runtime versions as unchecked.
2307
-
2308
- start and serve currently refuse with codex-not-ready. The policy-bound broker
2309
- and confined runner arrive in APRV-325.2 and APRV-325.3. An npm or project
2310
- installation alone is never reported as enforcement.
2311
-
2312
- ${EXIT_CODES_POINTER} (1 means the strict boundary is absent or invalid)
2573
+ approval codex apply --manifest <abs> --proposal <file> [--json]
2574
+ [--token <class>=<token>]... [--require-exclusive-custody]
2575
+ approval codex serve|recover --manifest <abs> [--json]
2576
+ approval codex start --manifest <abs> [--timeout <dur>] [--json] [-- <cmd>...]
2577
+
2578
+ prepare, setup --check and doctor are the inert half: a review bundle, its exact
2579
+ file set and hashes, and host custody, executing no manifest binary. apply is the
2580
+ BROKER: a bounded create/replace/delete/move proposal, ONE ACTION PER PATH CLASS,
2581
+ gate-authorized, every leg started before any byte moves, then staged, journaled
2582
+ and applied under a workspace lock; the MANIFEST supplies actor, root, policy and
2583
+ log. recover READS a retained journal, repairing nothing. serve is EXACTLY ONE MCP
2584
+ tool, separate from \`approval mcp serve\`. start CONFINES a shell: one disposable
2585
+ writable path, read-only gate and workspace, no credentials, no egress, NO OPT-OUT.
2586
+
2587
+ ${EXIT_CODES_POINTER} (1: the boundary is absent, invalid, or the workspace mixed)
2313
2588
  ${JSON_ERRORS}
2314
2589
  why: docs/cli-reference.md#constrained-codex-preparation`;
2315
2590
  export const MCP_HELP = `approval mcp serve — the MCP wrapper of SPEC.md §10.5 (FOREGROUND)
@@ -2336,4 +2611,42 @@ SERIALLY, THIS SERVER READS NO .approval/env. POST-V1: tasks/elicitation.
2336
2611
  ${EXIT_CODES_POINTER} (2 is a startup refusal; 0 is a clean shutdown)
2337
2612
  ${JSON_ERRORS}
2338
2613
  ${why("mcp-serve")}`;
2614
+ export const MUSE_HELP = `approval muse — local synthetic Muse consumer prototype (FOREGROUND)
2615
+
2616
+ Usage:
2617
+ approval muse [--dir <path>] [--port <n>]
2618
+
2619
+ APPROVAL_MUSE_TENANT identifies one tenant per process. Distinct
2620
+ APPROVAL_MUSE_READ_TOKEN and APPROVAL_MUSE_PROPOSE_TOKEN (24+ characters) are
2621
+ required in the launch environment. Listens only on 127.0.0.1, port 4683 by
2622
+ default. This is a local prototype, not a verified native Muse protocol.
2623
+ Human decisions use the already configured Telegram listener. No decision,
2624
+ execution, export, or generic verb endpoint exists here.
2625
+
2626
+ ${EXIT_CODES_POINTER} (2 is a startup refusal; 0 is a clean shutdown)
2627
+ ${why("muse")}`;
2628
+ export const SERVE_HELP = `approval serve — the agent-facing surface over HTTP (FOREGROUND)
2629
+
2630
+ Usage:
2631
+ approval serve [--as agent:<id>] [--dir <p>] [--log <p>] [--policy <p>]
2632
+ [--port <n> | --listen <host:port>|unix:<path>]
2633
+
2634
+ Flags:
2635
+ --as agent:<id> the identity EVERY call is recorded under, or APPROVAL_AGENT
2636
+ --dir/--log/--policy <p> the store root, and the log and policy pinned
2637
+ --port <n>=4682 loopback. --listen <host:port> widens, non-loopback ALSO needs --allow-non-loopback; unix:<path> or APPROVAL_SERVE_LISTEN: a socket
2638
+ --hook-timeout/--hook-harness-cap <d> pinned on every hook call, as the stdin form's --timeout and --harness-cap (the CALLER's own kill timeout)
2639
+ --hook-threads <n>=16 / --hook-queue <n>=64 hook calls running at once (a thread each) / waiting; past both, refused serve-hook-saturated
2640
+
2641
+ For a harness in a sandbox with no local log and no policy. THE VERBS ARE mcp
2642
+ serve's: the registry less human_only, --as absent from every schema, the
2643
+ identity appended last, no grant. It adds hook/<harness> (envelope in, the
2644
+ bytes stdin prints out), log/follow (paged, exclusive (seq, hash) cursor) and
2645
+ export (the store, minus keys, env and vault). AUTHORIZATION IS PER VERB:
2646
+ APPROVAL_SERVE_AGENT_TOKEN opens the hook and an allowlist (ask, and act on a
2647
+ grant); APPROVAL_SERVE_TENANT_TOKEN opens the rest, records included. NO TLS.
2648
+
2649
+ ${EXIT_CODES_POINTER} (2 is a startup refusal; 0 is a clean shutdown)
2650
+ ${JSON_ERRORS}
2651
+ ${why("serve")}`;
2339
2652
  //# sourceMappingURL=help.js.map