approval-md 0.0.1 → 0.2.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 (722) hide show
  1. package/LICENSE +176 -0
  2. package/NOTICE +5 -0
  3. package/README.md +940 -4
  4. package/SPEC.md +476 -34
  5. package/cli.js +29 -3
  6. package/dist/src/adapters/agentmail.d.ts +426 -0
  7. package/dist/src/adapters/agentmail.js +1200 -0
  8. package/dist/src/adapters/agentmail.js.map +1 -0
  9. package/dist/src/adapters/conformance.d.ts +149 -0
  10. package/dist/src/adapters/conformance.js +461 -0
  11. package/dist/src/adapters/conformance.js.map +1 -0
  12. package/dist/src/adapters/contract.d.ts +628 -0
  13. package/dist/src/adapters/contract.js +1035 -0
  14. package/dist/src/adapters/contract.js.map +1 -0
  15. package/dist/src/adapters/email.d.ts +324 -0
  16. package/dist/src/adapters/email.js +749 -0
  17. package/dist/src/adapters/email.js.map +1 -0
  18. package/dist/src/adapters/env-passphrase.d.ts +93 -0
  19. package/dist/src/adapters/env-passphrase.js +132 -0
  20. package/dist/src/adapters/env-passphrase.js.map +1 -0
  21. package/dist/src/adapters/public.d.ts +11 -0
  22. package/dist/src/adapters/public.js +11 -0
  23. package/dist/src/adapters/public.js.map +1 -0
  24. package/dist/src/adapters/registry.d.ts +59 -0
  25. package/dist/src/adapters/registry.js +77 -0
  26. package/dist/src/adapters/registry.js.map +1 -0
  27. package/dist/src/adapters/smtp.d.ts +213 -0
  28. package/dist/src/adapters/smtp.js +499 -0
  29. package/dist/src/adapters/smtp.js.map +1 -0
  30. package/dist/src/adapters/vault-provider.d.ts +114 -0
  31. package/dist/src/adapters/vault-provider.js +161 -0
  32. package/dist/src/adapters/vault-provider.js.map +1 -0
  33. package/dist/src/adapters/zzz.d.ts +66 -0
  34. package/dist/src/adapters/zzz.js +299 -0
  35. package/dist/src/adapters/zzz.js.map +1 -0
  36. package/dist/src/channels/batch.d.ts +109 -0
  37. package/dist/src/channels/batch.js +121 -0
  38. package/dist/src/channels/batch.js.map +1 -0
  39. package/dist/src/channels/cli.d.ts +193 -0
  40. package/dist/src/channels/cli.js +468 -0
  41. package/dist/src/channels/cli.js.map +1 -0
  42. package/dist/src/channels/conformance.d.ts +92 -0
  43. package/dist/src/channels/conformance.js +445 -0
  44. package/dist/src/channels/conformance.js.map +1 -0
  45. package/dist/src/channels/contract.d.ts +623 -0
  46. package/dist/src/channels/contract.js +494 -0
  47. package/dist/src/channels/contract.js.map +1 -0
  48. package/dist/src/channels/payload-view.d.ts +35 -0
  49. package/dist/src/channels/payload-view.js +43 -0
  50. package/dist/src/channels/payload-view.js.map +1 -0
  51. package/dist/src/channels/render-queue.d.ts +149 -0
  52. package/dist/src/channels/render-queue.js +564 -0
  53. package/dist/src/channels/render-queue.js.map +1 -0
  54. package/dist/src/channels/tagging.d.ts +196 -0
  55. package/dist/src/channels/tagging.js +723 -0
  56. package/dist/src/channels/tagging.js.map +1 -0
  57. package/dist/src/channels/telegram.d.ts +1832 -0
  58. package/dist/src/channels/telegram.js +3190 -0
  59. package/dist/src/channels/telegram.js.map +1 -0
  60. package/dist/src/channels/web.d.ts +341 -0
  61. package/dist/src/channels/web.js +903 -0
  62. package/dist/src/channels/web.js.map +1 -0
  63. package/dist/src/cli/adapter.d.ts +90 -0
  64. package/dist/src/cli/adapter.js +288 -0
  65. package/dist/src/cli/adapter.js.map +1 -0
  66. package/dist/src/cli/amend.d.ts +59 -0
  67. package/dist/src/cli/amend.js +2171 -0
  68. package/dist/src/cli/amend.js.map +1 -0
  69. package/dist/src/cli/args.d.ts +43 -0
  70. package/dist/src/cli/args.js +86 -0
  71. package/dist/src/cli/args.js.map +1 -0
  72. package/dist/src/cli/attest.d.ts +41 -0
  73. package/dist/src/cli/attest.js +307 -0
  74. package/dist/src/cli/attest.js.map +1 -0
  75. package/dist/src/cli/audit-card.d.ts +62 -0
  76. package/dist/src/cli/audit-card.js +201 -0
  77. package/dist/src/cli/audit-card.js.map +1 -0
  78. package/dist/src/cli/audit.d.ts +59 -0
  79. package/dist/src/cli/audit.js +460 -0
  80. package/dist/src/cli/audit.js.map +1 -0
  81. package/dist/src/cli/channel-telegram.d.ts +806 -0
  82. package/dist/src/cli/channel-telegram.js +2063 -0
  83. package/dist/src/cli/channel-telegram.js.map +1 -0
  84. package/dist/src/cli/channel-web.d.ts +131 -0
  85. package/dist/src/cli/channel-web.js +357 -0
  86. package/dist/src/cli/channel-web.js.map +1 -0
  87. package/dist/src/cli/channel.d.ts +71 -0
  88. package/dist/src/cli/channel.js +438 -0
  89. package/dist/src/cli/channel.js.map +1 -0
  90. package/dist/src/cli/checkpoint-tap.d.ts +169 -0
  91. package/dist/src/cli/checkpoint-tap.js +238 -0
  92. package/dist/src/cli/checkpoint-tap.js.map +1 -0
  93. package/dist/src/cli/codex.d.ts +2 -0
  94. package/dist/src/cli/codex.js +172 -0
  95. package/dist/src/cli/codex.js.map +1 -0
  96. package/dist/src/cli/coverage.d.ts +61 -0
  97. package/dist/src/cli/coverage.js +343 -0
  98. package/dist/src/cli/coverage.js.map +1 -0
  99. package/dist/src/cli/daemon.d.ts +120 -0
  100. package/dist/src/cli/daemon.js +631 -0
  101. package/dist/src/cli/daemon.js.map +1 -0
  102. package/dist/src/cli/doctor.d.ts +129 -0
  103. package/dist/src/cli/doctor.js +2762 -0
  104. package/dist/src/cli/doctor.js.map +1 -0
  105. package/dist/src/cli/env.d.ts +65 -0
  106. package/dist/src/cli/env.js +302 -0
  107. package/dist/src/cli/env.js.map +1 -0
  108. package/dist/src/cli/execute.d.ts +202 -0
  109. package/dist/src/cli/execute.js +1682 -0
  110. package/dist/src/cli/execute.js.map +1 -0
  111. package/dist/src/cli/exit-codes.d.ts +73 -0
  112. package/dist/src/cli/exit-codes.js +82 -0
  113. package/dist/src/cli/exit-codes.js.map +1 -0
  114. package/dist/src/cli/feedback.d.ts +60 -0
  115. package/dist/src/cli/feedback.js +205 -0
  116. package/dist/src/cli/feedback.js.map +1 -0
  117. package/dist/src/cli/gate-window.d.ts +40 -0
  118. package/dist/src/cli/gate-window.js +294 -0
  119. package/dist/src/cli/gate-window.js.map +1 -0
  120. package/dist/src/cli/gate.d.ts +68 -0
  121. package/dist/src/cli/gate.js +557 -0
  122. package/dist/src/cli/gate.js.map +1 -0
  123. package/dist/src/cli/git-scope.d.ts +190 -0
  124. package/dist/src/cli/git-scope.js +295 -0
  125. package/dist/src/cli/git-scope.js.map +1 -0
  126. package/dist/src/cli/gloss-attach.d.ts +85 -0
  127. package/dist/src/cli/gloss-attach.js +107 -0
  128. package/dist/src/cli/gloss-attach.js.map +1 -0
  129. package/dist/src/cli/gloss-codex-child.d.ts +9 -0
  130. package/dist/src/cli/gloss-codex-child.js +149 -0
  131. package/dist/src/cli/gloss-codex-child.js.map +1 -0
  132. package/dist/src/cli/gloss-codex.d.ts +24 -0
  133. package/dist/src/cli/gloss-codex.js +255 -0
  134. package/dist/src/cli/gloss-codex.js.map +1 -0
  135. package/dist/src/cli/gloss-options.d.ts +42 -0
  136. package/dist/src/cli/gloss-options.js +79 -0
  137. package/dist/src/cli/gloss-options.js.map +1 -0
  138. package/dist/src/cli/gloss.d.ts +265 -0
  139. package/dist/src/cli/gloss.js +362 -0
  140. package/dist/src/cli/gloss.js.map +1 -0
  141. package/dist/src/cli/help.d.ts +103 -0
  142. package/dist/src/cli/help.js +2339 -0
  143. package/dist/src/cli/help.js.map +1 -0
  144. package/dist/src/cli/hook-codex.d.ts +78 -0
  145. package/dist/src/cli/hook-codex.js +167 -0
  146. package/dist/src/cli/hook-codex.js.map +1 -0
  147. package/dist/src/cli/hook.d.ts +331 -0
  148. package/dist/src/cli/hook.js +2849 -0
  149. package/dist/src/cli/hook.js.map +1 -0
  150. package/dist/src/cli/import.d.ts +35 -0
  151. package/dist/src/cli/import.js +175 -0
  152. package/dist/src/cli/import.js.map +1 -0
  153. package/dist/src/cli/init.d.ts +84 -0
  154. package/dist/src/cli/init.js +336 -0
  155. package/dist/src/cli/init.js.map +1 -0
  156. package/dist/src/cli/instructions.d.ts +23 -0
  157. package/dist/src/cli/instructions.js +262 -0
  158. package/dist/src/cli/instructions.js.map +1 -0
  159. package/dist/src/cli/journal.d.ts +41 -0
  160. package/dist/src/cli/journal.js +238 -0
  161. package/dist/src/cli/journal.js.map +1 -0
  162. package/dist/src/cli/log-advance.d.ts +287 -0
  163. package/dist/src/cli/log-advance.js +840 -0
  164. package/dist/src/cli/log-advance.js.map +1 -0
  165. package/dist/src/cli/log-anchor.d.ts +176 -0
  166. package/dist/src/cli/log-anchor.js +387 -0
  167. package/dist/src/cli/log-anchor.js.map +1 -0
  168. package/dist/src/cli/log-checkpoint.d.ts +22 -0
  169. package/dist/src/cli/log-checkpoint.js +128 -0
  170. package/dist/src/cli/log-checkpoint.js.map +1 -0
  171. package/dist/src/cli/log-sync.d.ts +243 -0
  172. package/dist/src/cli/log-sync.js +849 -0
  173. package/dist/src/cli/log-sync.js.map +1 -0
  174. package/dist/src/cli/log-verbs.d.ts +16 -0
  175. package/dist/src/cli/log-verbs.js +360 -0
  176. package/dist/src/cli/log-verbs.js.map +1 -0
  177. package/dist/src/cli/long-help.d.ts +70 -0
  178. package/dist/src/cli/long-help.js +148 -0
  179. package/dist/src/cli/long-help.js.map +1 -0
  180. package/dist/src/cli/main.d.ts +77 -0
  181. package/dist/src/cli/main.js +1206 -0
  182. package/dist/src/cli/main.js.map +1 -0
  183. package/dist/src/cli/mcp.d.ts +52 -0
  184. package/dist/src/cli/mcp.js +306 -0
  185. package/dist/src/cli/mcp.js.map +1 -0
  186. package/dist/src/cli/paths.d.ts +56 -0
  187. package/dist/src/cli/paths.js +79 -0
  188. package/dist/src/cli/paths.js.map +1 -0
  189. package/dist/src/cli/payload.d.ts +58 -0
  190. package/dist/src/cli/payload.js +253 -0
  191. package/dist/src/cli/payload.js.map +1 -0
  192. package/dist/src/cli/policy.d.ts +43 -0
  193. package/dist/src/cli/policy.js +229 -0
  194. package/dist/src/cli/policy.js.map +1 -0
  195. package/dist/src/cli/preflight.d.ts +363 -0
  196. package/dist/src/cli/preflight.js +1175 -0
  197. package/dist/src/cli/preflight.js.map +1 -0
  198. package/dist/src/cli/progress.d.ts +78 -0
  199. package/dist/src/cli/progress.js +112 -0
  200. package/dist/src/cli/progress.js.map +1 -0
  201. package/dist/src/cli/prompt.d.ts +209 -0
  202. package/dist/src/cli/prompt.js +312 -0
  203. package/dist/src/cli/prompt.js.map +1 -0
  204. package/dist/src/cli/quickstart.d.ts +46 -0
  205. package/dist/src/cli/quickstart.js +297 -0
  206. package/dist/src/cli/quickstart.js.map +1 -0
  207. package/dist/src/cli/records.d.ts +34 -0
  208. package/dist/src/cli/records.js +66 -0
  209. package/dist/src/cli/records.js.map +1 -0
  210. package/dist/src/cli/render.d.ts +22 -0
  211. package/dist/src/cli/render.js +132 -0
  212. package/dist/src/cli/render.js.map +1 -0
  213. package/dist/src/cli/sandbox.d.ts +51 -0
  214. package/dist/src/cli/sandbox.js +150 -0
  215. package/dist/src/cli/sandbox.js.map +1 -0
  216. package/dist/src/cli/scaffold.d.ts +79 -0
  217. package/dist/src/cli/scaffold.js +137 -0
  218. package/dist/src/cli/scaffold.js.map +1 -0
  219. package/dist/src/cli/setup-adapter.d.ts +137 -0
  220. package/dist/src/cli/setup-adapter.js +509 -0
  221. package/dist/src/cli/setup-adapter.js.map +1 -0
  222. package/dist/src/cli/setup-channel.d.ts +117 -0
  223. package/dist/src/cli/setup-channel.js +635 -0
  224. package/dist/src/cli/setup-channel.js.map +1 -0
  225. package/dist/src/cli/setup-checkpoint.d.ts +57 -0
  226. package/dist/src/cli/setup-checkpoint.js +196 -0
  227. package/dist/src/cli/setup-checkpoint.js.map +1 -0
  228. package/dist/src/cli/setup-common.d.ts +275 -0
  229. package/dist/src/cli/setup-common.js +376 -0
  230. package/dist/src/cli/setup-common.js.map +1 -0
  231. package/dist/src/cli/setup-flow.d.ts +287 -0
  232. package/dist/src/cli/setup-flow.js +476 -0
  233. package/dist/src/cli/setup-flow.js.map +1 -0
  234. package/dist/src/cli/setup-service.d.ts +96 -0
  235. package/dist/src/cli/setup-service.js +308 -0
  236. package/dist/src/cli/setup-service.js.map +1 -0
  237. package/dist/src/cli/setup.d.ts +202 -0
  238. package/dist/src/cli/setup.js +473 -0
  239. package/dist/src/cli/setup.js.map +1 -0
  240. package/dist/src/cli/style.d.ts +320 -0
  241. package/dist/src/cli/style.js +469 -0
  242. package/dist/src/cli/style.js.map +1 -0
  243. package/dist/src/cli/token.d.ts +39 -0
  244. package/dist/src/cli/token.js +274 -0
  245. package/dist/src/cli/token.js.map +1 -0
  246. package/dist/src/cli/up.d.ts +155 -0
  247. package/dist/src/cli/up.js +849 -0
  248. package/dist/src/cli/up.js.map +1 -0
  249. package/dist/src/cli/usage.d.ts +37 -0
  250. package/dist/src/cli/usage.js +91 -0
  251. package/dist/src/cli/usage.js.map +1 -0
  252. package/dist/src/cli/values.d.ts +40 -0
  253. package/dist/src/cli/values.js +189 -0
  254. package/dist/src/cli/values.js.map +1 -0
  255. package/dist/src/cli/vault.d.ts +59 -0
  256. package/dist/src/cli/vault.js +362 -0
  257. package/dist/src/cli/vault.js.map +1 -0
  258. package/dist/src/cli/verb-registry.d.ts +76 -0
  259. package/dist/src/cli/verb-registry.js +2341 -0
  260. package/dist/src/cli/verb-registry.js.map +1 -0
  261. package/dist/src/cli/wordmark.d.ts +31 -0
  262. package/dist/src/cli/wordmark.js +52 -0
  263. package/dist/src/cli/wordmark.js.map +1 -0
  264. package/dist/src/codex/doctor.d.ts +13 -0
  265. package/dist/src/codex/doctor.js +41 -0
  266. package/dist/src/codex/doctor.js.map +1 -0
  267. package/dist/src/codex/manifest.d.ts +49 -0
  268. package/dist/src/codex/manifest.js +103 -0
  269. package/dist/src/codex/manifest.js.map +1 -0
  270. package/dist/src/codex/templates.d.ts +41 -0
  271. package/dist/src/codex/templates.js +319 -0
  272. package/dist/src/codex/templates.js.map +1 -0
  273. package/dist/src/codex/trust.d.ts +19 -0
  274. package/dist/src/codex/trust.js +183 -0
  275. package/dist/src/codex/trust.js.map +1 -0
  276. package/dist/src/codex/workspace-plan.d.ts +131 -0
  277. package/dist/src/codex/workspace-plan.js +561 -0
  278. package/dist/src/codex/workspace-plan.js.map +1 -0
  279. package/dist/src/core/actor.d.ts +2 -0
  280. package/dist/src/core/actor.js +5 -0
  281. package/dist/src/core/actor.js.map +1 -0
  282. package/dist/src/core/advance-cycle.d.ts +170 -0
  283. package/dist/src/core/advance-cycle.js +200 -0
  284. package/dist/src/core/advance-cycle.js.map +1 -0
  285. package/dist/src/core/agents-md.d.ts +276 -0
  286. package/dist/src/core/agents-md.js +747 -0
  287. package/dist/src/core/agents-md.js.map +1 -0
  288. package/dist/src/core/apply-patch.d.ts +49 -0
  289. package/dist/src/core/apply-patch.js +266 -0
  290. package/dist/src/core/apply-patch.js.map +1 -0
  291. package/dist/src/core/attest.d.ts +420 -0
  292. package/dist/src/core/attest.js +589 -0
  293. package/dist/src/core/attest.js.map +1 -0
  294. package/dist/src/core/audit.d.ts +492 -0
  295. package/dist/src/core/audit.js +882 -0
  296. package/dist/src/core/audit.js.map +1 -0
  297. package/dist/src/core/budgets.d.ts +238 -0
  298. package/dist/src/core/budgets.js +449 -0
  299. package/dist/src/core/budgets.js.map +1 -0
  300. package/dist/src/core/checkpoint.d.ts +500 -0
  301. package/dist/src/core/checkpoint.js +738 -0
  302. package/dist/src/core/checkpoint.js.map +1 -0
  303. package/dist/src/core/child-env.d.ts +88 -0
  304. package/dist/src/core/child-env.js +86 -0
  305. package/dist/src/core/child-env.js.map +1 -0
  306. package/dist/src/core/clock.d.ts +52 -0
  307. package/dist/src/core/clock.js +43 -0
  308. package/dist/src/core/clock.js.map +1 -0
  309. package/dist/src/core/command-class.d.ts +543 -0
  310. package/dist/src/core/command-class.js +2356 -0
  311. package/dist/src/core/command-class.js.map +1 -0
  312. package/dist/src/core/coverage-sources/adapter.d.ts +40 -0
  313. package/dist/src/core/coverage-sources/adapter.js +71 -0
  314. package/dist/src/core/coverage-sources/adapter.js.map +1 -0
  315. package/dist/src/core/coverage-sources/gh.d.ts +48 -0
  316. package/dist/src/core/coverage-sources/gh.js +136 -0
  317. package/dist/src/core/coverage-sources/gh.js.map +1 -0
  318. package/dist/src/core/coverage-sources/git.d.ts +101 -0
  319. package/dist/src/core/coverage-sources/git.js +269 -0
  320. package/dist/src/core/coverage-sources/git.js.map +1 -0
  321. package/dist/src/core/coverage.d.ts +217 -0
  322. package/dist/src/core/coverage.js +337 -0
  323. package/dist/src/core/coverage.js.map +1 -0
  324. package/dist/src/core/credential-spec.d.ts +72 -0
  325. package/dist/src/core/credential-spec.js +23 -0
  326. package/dist/src/core/credential-spec.js.map +1 -0
  327. package/dist/src/core/dark-session.d.ts +331 -0
  328. package/dist/src/core/dark-session.js +714 -0
  329. package/dist/src/core/dark-session.js.map +1 -0
  330. package/dist/src/core/decision-refusal.d.ts +185 -0
  331. package/dist/src/core/decision-refusal.js +265 -0
  332. package/dist/src/core/decision-refusal.js.map +1 -0
  333. package/dist/src/core/env-file.d.ts +450 -0
  334. package/dist/src/core/env-file.js +837 -0
  335. package/dist/src/core/env-file.js.map +1 -0
  336. package/dist/src/core/execute.d.ts +858 -0
  337. package/dist/src/core/execute.js +1271 -0
  338. package/dist/src/core/execute.js.map +1 -0
  339. package/dist/src/core/frontmatter.d.ts +78 -0
  340. package/dist/src/core/frontmatter.js +100 -0
  341. package/dist/src/core/frontmatter.js.map +1 -0
  342. package/dist/src/core/gate-window.d.ts +312 -0
  343. package/dist/src/core/gate-window.js +506 -0
  344. package/dist/src/core/gate-window.js.map +1 -0
  345. package/dist/src/core/gate.d.ts +1364 -0
  346. package/dist/src/core/gate.js +3002 -0
  347. package/dist/src/core/gate.js.map +1 -0
  348. package/dist/src/core/git-run.d.ts +73 -0
  349. package/dist/src/core/git-run.js +93 -0
  350. package/dist/src/core/git-run.js.map +1 -0
  351. package/dist/src/core/harness-version.d.ts +157 -0
  352. package/dist/src/core/harness-version.js +211 -0
  353. package/dist/src/core/harness-version.js.map +1 -0
  354. package/dist/src/core/harness-wait.d.ts +55 -0
  355. package/dist/src/core/harness-wait.js +58 -0
  356. package/dist/src/core/harness-wait.js.map +1 -0
  357. package/dist/src/core/head-retry.d.ts +107 -0
  358. package/dist/src/core/head-retry.js +121 -0
  359. package/dist/src/core/head-retry.js.map +1 -0
  360. package/dist/src/core/instance.d.ts +253 -0
  361. package/dist/src/core/instance.js +319 -0
  362. package/dist/src/core/instance.js.map +1 -0
  363. package/dist/src/core/intake-limits.d.ts +247 -0
  364. package/dist/src/core/intake-limits.js +350 -0
  365. package/dist/src/core/intake-limits.js.map +1 -0
  366. package/dist/src/core/jcs.d.ts +52 -0
  367. package/dist/src/core/jcs.js +132 -0
  368. package/dist/src/core/jcs.js.map +1 -0
  369. package/dist/src/core/journal.d.ts +144 -0
  370. package/dist/src/core/journal.js +200 -0
  371. package/dist/src/core/journal.js.map +1 -0
  372. package/dist/src/core/live-draw.d.ts +436 -0
  373. package/dist/src/core/live-draw.js +703 -0
  374. package/dist/src/core/live-draw.js.map +1 -0
  375. package/dist/src/core/log-reconcile.d.ts +89 -0
  376. package/dist/src/core/log-reconcile.js +136 -0
  377. package/dist/src/core/log-reconcile.js.map +1 -0
  378. package/dist/src/core/log-subscribe.d.ts +36 -0
  379. package/dist/src/core/log-subscribe.js +162 -0
  380. package/dist/src/core/log-subscribe.js.map +1 -0
  381. package/dist/src/core/log.d.ts +278 -0
  382. package/dist/src/core/log.js +546 -0
  383. package/dist/src/core/log.js.map +1 -0
  384. package/dist/src/core/loop.d.ts +274 -0
  385. package/dist/src/core/loop.js +487 -0
  386. package/dist/src/core/loop.js.map +1 -0
  387. package/dist/src/core/md-fence.d.ts +41 -0
  388. package/dist/src/core/md-fence.js +74 -0
  389. package/dist/src/core/md-fence.js.map +1 -0
  390. package/dist/src/core/money.d.ts +147 -0
  391. package/dist/src/core/money.js +195 -0
  392. package/dist/src/core/money.js.map +1 -0
  393. package/dist/src/core/payload-census.d.ts +74 -0
  394. package/dist/src/core/payload-census.js +146 -0
  395. package/dist/src/core/payload-census.js.map +1 -0
  396. package/dist/src/core/payload-store.d.ts +175 -0
  397. package/dist/src/core/payload-store.js +340 -0
  398. package/dist/src/core/payload-store.js.map +1 -0
  399. package/dist/src/core/payload.d.ts +71 -0
  400. package/dist/src/core/payload.js +80 -0
  401. package/dist/src/core/payload.js.map +1 -0
  402. package/dist/src/core/policy-diff.d.ts +292 -0
  403. package/dist/src/core/policy-diff.js +588 -0
  404. package/dist/src/core/policy-diff.js.map +1 -0
  405. package/dist/src/core/policy-expectations.d.ts +199 -0
  406. package/dist/src/core/policy-expectations.js +394 -0
  407. package/dist/src/core/policy-expectations.js.map +1 -0
  408. package/dist/src/core/policy-explain.d.ts +150 -0
  409. package/dist/src/core/policy-explain.js +258 -0
  410. package/dist/src/core/policy-explain.js.map +1 -0
  411. package/dist/src/core/policy-load.d.ts +527 -0
  412. package/dist/src/core/policy-load.js +536 -0
  413. package/dist/src/core/policy-load.js.map +1 -0
  414. package/dist/src/core/policy-match.d.ts +281 -0
  415. package/dist/src/core/policy-match.js +478 -0
  416. package/dist/src/core/policy-match.js.map +1 -0
  417. package/dist/src/core/policy-proposal.d.ts +265 -0
  418. package/dist/src/core/policy-proposal.js +458 -0
  419. package/dist/src/core/policy-proposal.js.map +1 -0
  420. package/dist/src/core/prompt-layout.d.ts +221 -0
  421. package/dist/src/core/prompt-layout.js +422 -0
  422. package/dist/src/core/prompt-layout.js.map +1 -0
  423. package/dist/src/core/protected-path-guard.d.ts +453 -0
  424. package/dist/src/core/protected-path-guard.js +1566 -0
  425. package/dist/src/core/protected-path-guard.js.map +1 -0
  426. package/dist/src/core/registration.d.ts +25 -0
  427. package/dist/src/core/registration.js +39 -0
  428. package/dist/src/core/registration.js.map +1 -0
  429. package/dist/src/core/reindex.d.ts +99 -0
  430. package/dist/src/core/reindex.js +336 -0
  431. package/dist/src/core/reindex.js.map +1 -0
  432. package/dist/src/core/sampler.d.ts +313 -0
  433. package/dist/src/core/sampler.js +388 -0
  434. package/dist/src/core/sampler.js.map +1 -0
  435. package/dist/src/core/sandbox.d.ts +290 -0
  436. package/dist/src/core/sandbox.js +424 -0
  437. package/dist/src/core/sandbox.js.map +1 -0
  438. package/dist/src/core/seal.d.ts +165 -0
  439. package/dist/src/core/seal.js +290 -0
  440. package/dist/src/core/seal.js.map +1 -0
  441. package/dist/src/core/state.d.ts +505 -0
  442. package/dist/src/core/state.js +1009 -0
  443. package/dist/src/core/state.js.map +1 -0
  444. package/dist/src/core/task-file.d.ts +185 -0
  445. package/dist/src/core/task-file.js +464 -0
  446. package/dist/src/core/task-file.js.map +1 -0
  447. package/dist/src/core/telegram-config.d.ts +93 -0
  448. package/dist/src/core/telegram-config.js +114 -0
  449. package/dist/src/core/telegram-config.js.map +1 -0
  450. package/dist/src/core/token.d.ts +409 -0
  451. package/dist/src/core/token.js +561 -0
  452. package/dist/src/core/token.js.map +1 -0
  453. package/dist/src/core/validate.d.ts +138 -0
  454. package/dist/src/core/validate.js +0 -0
  455. package/dist/src/core/validate.js.map +1 -0
  456. package/dist/src/core/values.d.ts +137 -0
  457. package/dist/src/core/values.js +153 -0
  458. package/dist/src/core/values.js.map +1 -0
  459. package/dist/src/core/vault.d.ts +291 -0
  460. package/dist/src/core/vault.js +612 -0
  461. package/dist/src/core/vault.js.map +1 -0
  462. package/dist/src/core/verified-snapshot.d.ts +204 -0
  463. package/dist/src/core/verified-snapshot.js +506 -0
  464. package/dist/src/core/verified-snapshot.js.map +1 -0
  465. package/dist/src/core/verify.d.ts +336 -0
  466. package/dist/src/core/verify.js +549 -0
  467. package/dist/src/core/verify.js.map +1 -0
  468. package/dist/src/core/version.d.ts +8 -0
  469. package/dist/src/core/version.js +9 -0
  470. package/dist/src/core/version.js.map +1 -0
  471. package/dist/src/core/wysiwys.d.ts +370 -0
  472. package/dist/src/core/wysiwys.js +728 -0
  473. package/dist/src/core/wysiwys.js.map +1 -0
  474. package/dist/src/daemon/advance-child.d.ts +39 -0
  475. package/dist/src/daemon/advance-child.js +78 -0
  476. package/dist/src/daemon/advance-child.js.map +1 -0
  477. package/dist/src/daemon/advance.d.ts +466 -0
  478. package/dist/src/daemon/advance.js +849 -0
  479. package/dist/src/daemon/advance.js.map +1 -0
  480. package/dist/src/daemon/audit.d.ts +87 -0
  481. package/dist/src/daemon/audit.js +90 -0
  482. package/dist/src/daemon/audit.js.map +1 -0
  483. package/dist/src/daemon/daemon.d.ts +1180 -0
  484. package/dist/src/daemon/daemon.js +1988 -0
  485. package/dist/src/daemon/daemon.js.map +1 -0
  486. package/dist/src/daemon/dark-session.d.ts +64 -0
  487. package/dist/src/daemon/dark-session.js +119 -0
  488. package/dist/src/daemon/dark-session.js.map +1 -0
  489. package/dist/src/daemon/draw-child.d.ts +36 -0
  490. package/dist/src/daemon/draw-child.js +132 -0
  491. package/dist/src/daemon/draw-child.js.map +1 -0
  492. package/dist/src/daemon/draw.d.ts +154 -0
  493. package/dist/src/daemon/draw.js +458 -0
  494. package/dist/src/daemon/draw.js.map +1 -0
  495. package/dist/src/daemon/git-evidence.d.ts +173 -0
  496. package/dist/src/daemon/git-evidence.js +345 -0
  497. package/dist/src/daemon/git-evidence.js.map +1 -0
  498. package/dist/src/daemon/projection.d.ts +180 -0
  499. package/dist/src/daemon/projection.js +233 -0
  500. package/dist/src/daemon/projection.js.map +1 -0
  501. package/dist/src/daemon/prune.d.ts +207 -0
  502. package/dist/src/daemon/prune.js +376 -0
  503. package/dist/src/daemon/prune.js.map +1 -0
  504. package/dist/src/mcp/http.d.ts +113 -0
  505. package/dist/src/mcp/http.js +343 -0
  506. package/dist/src/mcp/http.js.map +1 -0
  507. package/dist/src/mcp/server.d.ts +265 -0
  508. package/dist/src/mcp/server.js +602 -0
  509. package/dist/src/mcp/server.js.map +1 -0
  510. package/docs/adapter-api.md +106 -0
  511. package/docs/cli-reference.md +5716 -0
  512. package/docs/codex-enforced-session.md +30 -0
  513. package/package.json +53 -4
  514. package/schema/.gitkeep +0 -0
  515. package/schema/LICENSE +117 -0
  516. package/schema/codex-instance.schema.json +82 -0
  517. package/schema/envelope.schema.json +137 -0
  518. package/schema/event.schema.json +1811 -0
  519. package/schema/fixtures/codex-instance/invalid/unpinned-codex-version.json +40 -0
  520. package/schema/fixtures/codex-instance/valid/canonical.json +40 -0
  521. package/schema/fixtures/envelope/invalid/action-missing-idempotency-key.json +15 -0
  522. package/schema/fixtures/envelope/invalid/action-unknown-class-format.json +14 -0
  523. package/schema/fixtures/envelope/invalid/confidence-out-of-range.json +11 -0
  524. package/schema/fixtures/envelope/invalid/est-cost-bare-number.json +14 -0
  525. package/schema/fixtures/envelope/invalid/est-cost-noncanonical-string.json +14 -0
  526. package/schema/fixtures/envelope/invalid/malformed-assignee.json +10 -0
  527. package/schema/fixtures/envelope/invalid/malformed-created-by.json +7 -0
  528. package/schema/fixtures/envelope/invalid/malformed-max-latency.json +11 -0
  529. package/schema/fixtures/envelope/invalid/malformed-payload-hash.json +14 -0
  530. package/schema/fixtures/envelope/invalid/max-cost-bare-number.json +11 -0
  531. package/schema/fixtures/envelope/invalid/missing-origin.json +3 -0
  532. package/schema/fixtures/envelope/invalid/negative-est-cost.json +14 -0
  533. package/schema/fixtures/envelope/invalid/unknown-state.json +7 -0
  534. package/schema/fixtures/envelope/invalid/unknown-top-level-field.json +8 -0
  535. package/schema/fixtures/envelope/valid/action-payload-hash.json +17 -0
  536. package/schema/fixtures/envelope/valid/actions-without-budget.json +18 -0
  537. package/schema/fixtures/envelope/valid/canonical.json +25 -0
  538. package/schema/fixtures/envelope/valid/minimal.json +7 -0
  539. package/schema/fixtures/envelope/valid/multi-action-executed.json +30 -0
  540. package/schema/fixtures/envelope/valid/record-write-stage.json +22 -0
  541. package/schema/fixtures/event/invalid/approval-granted-agent-actor.json +15 -0
  542. package/schema/fixtures/event/invalid/approval-granted-empty-batch-delivery-id.json +17 -0
  543. package/schema/fixtures/event/invalid/approval-granted-fifth-reaction.json +16 -0
  544. package/schema/fixtures/event/invalid/approval-granted-missing-actor.json +14 -0
  545. package/schema/fixtures/event/invalid/approval-requested-missing-action-key.json +14 -0
  546. package/schema/fixtures/event/invalid/approval-withdrawn-agent-policy-drift.json +15 -0
  547. package/schema/fixtures/event/invalid/approval-withdrawn-missing-reason.json +15 -0
  548. package/schema/fixtures/event/invalid/approval-withdrawn-system-actor.json +15 -0
  549. package/schema/fixtures/event/invalid/audit-decision-refused-human-actor.json +17 -0
  550. package/schema/fixtures/event/invalid/audit-decision-refused-missing-code.json +16 -0
  551. package/schema/fixtures/event/invalid/audit-reviewed-agent-actor.json +15 -0
  552. package/schema/fixtures/event/invalid/audit-reviewed-loved-no-note.json +16 -0
  553. package/schema/fixtures/event/invalid/audit-reviewed-system-actor.json +15 -0
  554. package/schema/fixtures/event/invalid/bad-actor-prefix.json +15 -0
  555. package/schema/fixtures/event/invalid/est-cost-bare-number.json +17 -0
  556. package/schema/fixtures/event/invalid/execution-completed-fabricated-exit-code.json +16 -0
  557. package/schema/fixtures/event/invalid/execution-completed-provider-ref-empty-id.json +18 -0
  558. package/schema/fixtures/event/invalid/execution-completed-provider-ref-extra-field.json +19 -0
  559. package/schema/fixtures/event/invalid/execution-completed-provider-ref-id-not-string.json +18 -0
  560. package/schema/fixtures/event/invalid/execution-completed-provider-ref-missing-adapter.json +17 -0
  561. package/schema/fixtures/event/invalid/execution-failed-open-reported-by.json +16 -0
  562. package/schema/fixtures/event/invalid/execution-indeterminate-open-reason.json +14 -0
  563. package/schema/fixtures/event/invalid/execution-reconciled-agent-actor.json +17 -0
  564. package/schema/fixtures/event/invalid/execution-started-negative-env-stripped.json +16 -0
  565. package/schema/fixtures/event/invalid/gate-bypassed-missing-opened-seq.json +15 -0
  566. package/schema/fixtures/event/invalid/gate-closed-non-integer-opened-seq.json +13 -0
  567. package/schema/fixtures/event/invalid/gate-opened-agent-actor.json +16 -0
  568. package/schema/fixtures/event/invalid/gate-organ-attested-absolute-path.json +14 -0
  569. package/schema/fixtures/event/invalid/gate-organ-attested-agent-actor.json +14 -0
  570. package/schema/fixtures/event/invalid/gate-organ-attested-missing-organ-path.json +13 -0
  571. package/schema/fixtures/event/invalid/harness-unknown-kind.json +18 -0
  572. package/schema/fixtures/event/invalid/harness-version-multiline.json +16 -0
  573. package/schema/fixtures/event/invalid/log-checkpoint-agent-actor.json +17 -0
  574. package/schema/fixtures/event/invalid/log-checkpoint-missing-signature.json +16 -0
  575. package/schema/fixtures/event/invalid/log-checkpoint-short-signed-hash.json +17 -0
  576. package/schema/fixtures/event/invalid/log-checkpoint-unknown-signature-alg.json +17 -0
  577. package/schema/fixtures/event/invalid/malformed-ts.json +15 -0
  578. package/schema/fixtures/event/invalid/missing-alg.json +14 -0
  579. package/schema/fixtures/event/invalid/missing-hash.json +14 -0
  580. package/schema/fixtures/event/invalid/non-integer-seq.json +15 -0
  581. package/schema/fixtures/event/invalid/payload-pruned-human-actor.json +14 -0
  582. package/schema/fixtures/event/invalid/payload-pruned-missing-hash.json +14 -0
  583. package/schema/fixtures/event/invalid/policy-declined-agent-actor.json +15 -0
  584. package/schema/fixtures/event/invalid/policy-proposed-missing-diff.json +19 -0
  585. package/schema/fixtures/event/invalid/policy-proposed-system-actor.json +26 -0
  586. package/schema/fixtures/event/invalid/short-hash.json +15 -0
  587. package/schema/fixtures/event/invalid/unknown-alg.json +15 -0
  588. package/schema/fixtures/event/invalid/unknown-event-type.json +15 -0
  589. package/schema/fixtures/event/invalid/unknown-top-level-field.json +16 -0
  590. package/schema/fixtures/event/valid/approval-expired.json +15 -0
  591. package/schema/fixtures/event/valid/approval-granted-batch.json +19 -0
  592. package/schema/fixtures/event/valid/approval-granted-reaction.json +16 -0
  593. package/schema/fixtures/event/valid/approval-granted.json +15 -0
  594. package/schema/fixtures/event/valid/approval-rejected.json +15 -0
  595. package/schema/fixtures/event/valid/approval-requested.json +19 -0
  596. package/schema/fixtures/event/valid/approval-revoked.json +15 -0
  597. package/schema/fixtures/event/valid/approval-withdrawn-policy-drift.json +17 -0
  598. package/schema/fixtures/event/valid/approval-withdrawn.json +16 -0
  599. package/schema/fixtures/event/valid/audit-decision-refused.json +20 -0
  600. package/schema/fixtures/event/valid/audit-reviewed-reaction.json +17 -0
  601. package/schema/fixtures/event/valid/audit-reviewed.json +15 -0
  602. package/schema/fixtures/event/valid/audit-sampled.json +14 -0
  603. package/schema/fixtures/event/valid/budget-exceeded.json +21 -0
  604. package/schema/fixtures/event/valid/envelope-drift.json +16 -0
  605. package/schema/fixtures/event/valid/execution-completed-harness-report.json +16 -0
  606. package/schema/fixtures/event/valid/execution-completed-provider-ref.json +18 -0
  607. package/schema/fixtures/event/valid/execution-completed.json +15 -0
  608. package/schema/fixtures/event/valid/execution-failed-harness-report.json +16 -0
  609. package/schema/fixtures/event/valid/execution-failed.json +15 -0
  610. package/schema/fixtures/event/valid/execution-indeterminate.json +15 -0
  611. package/schema/fixtures/event/valid/execution-reconciled.json +17 -0
  612. package/schema/fixtures/event/valid/execution-started-env-stripped.json +17 -0
  613. package/schema/fixtures/event/valid/execution-started.json +14 -0
  614. package/schema/fixtures/event/valid/gate-bypassed-harness-version.json +18 -0
  615. package/schema/fixtures/event/valid/gate-bypassed.json +19 -0
  616. package/schema/fixtures/event/valid/gate-closed.json +14 -0
  617. package/schema/fixtures/event/valid/gate-opened.json +16 -0
  618. package/schema/fixtures/event/valid/gate-organ-attested.json +14 -0
  619. package/schema/fixtures/event/valid/genesis-null-prev.json +14 -0
  620. package/schema/fixtures/event/valid/log-checkpoint.json +17 -0
  621. package/schema/fixtures/event/valid/payload-pruned-orphan.json +13 -0
  622. package/schema/fixtures/event/valid/payload-pruned.json +17 -0
  623. package/schema/fixtures/event/valid/policy-declined.json +16 -0
  624. package/schema/fixtures/event/valid/policy-proposed.json +35 -0
  625. package/schema/fixtures/event/valid/policy-updated.json +14 -0
  626. package/schema/fixtures/event/valid/reconciliation-required.json +18 -0
  627. package/schema/fixtures/event/valid/reconciliation-satisfied.json +17 -0
  628. package/schema/fixtures/event/valid/route-accepted.json +15 -0
  629. package/schema/fixtures/event/valid/route-proposed.json +16 -0
  630. package/schema/fixtures/event/valid/spec-example.json +15 -0
  631. package/schema/fixtures/event/valid/task-registered-harness-version.json +23 -0
  632. package/schema/fixtures/event/valid/task-registered.json +14 -0
  633. package/schema/fixtures/hash/known-answer-pre-121.json +74 -0
  634. package/schema/fixtures/hash/known-answer.json +74 -0
  635. package/schema/fixtures/policy/invalid/bad-approval-ttl.json +7 -0
  636. package/schema/fixtures/policy/invalid/bad-web-port.json +4 -0
  637. package/schema/fixtures/policy/invalid/checkpoint-key-not-base64.json +6 -0
  638. package/schema/fixtures/policy/invalid/class-rule-missing-autonomy.json +9 -0
  639. package/schema/fixtures/policy/invalid/empty-class-key.json +6 -0
  640. package/schema/fixtures/policy/invalid/live-rate-on-human-only.json +7 -0
  641. package/schema/fixtures/policy/invalid/malformed-class-key.json +6 -0
  642. package/schema/fixtures/policy/invalid/missing-version.json +8 -0
  643. package/schema/fixtures/policy/invalid/negative-limit.json +9 -0
  644. package/schema/fixtures/policy/invalid/non-numeric-limit.json +9 -0
  645. package/schema/fixtures/policy/invalid/non-positive-max-pending.json +9 -0
  646. package/schema/fixtures/policy/invalid/on-expiry-grant.json +8 -0
  647. package/schema/fixtures/policy/invalid/payload-retention-bare-number.json +4 -0
  648. package/schema/fixtures/policy/invalid/payload-retention-compound.json +4 -0
  649. package/schema/fixtures/policy/invalid/payload-retention-fractional.json +4 -0
  650. package/schema/fixtures/policy/invalid/payload-retention-zero.json +4 -0
  651. package/schema/fixtures/policy/invalid/protected-paths-escape.json +4 -0
  652. package/schema/fixtures/policy/invalid/protected-paths-glob.json +4 -0
  653. package/schema/fixtures/policy/invalid/retro-rate-on-human-only.json +7 -0
  654. package/schema/fixtures/policy/invalid/retro-rate-on-manual.json +7 -0
  655. package/schema/fixtures/policy/invalid/retro-rate-zero.json +7 -0
  656. package/schema/fixtures/policy/invalid/sample-rate-too-high.json +5 -0
  657. package/schema/fixtures/policy/invalid/sampling-secret-env-empty.json +7 -0
  658. package/schema/fixtures/policy/invalid/sampling-secret-env-not-string.json +6 -0
  659. package/schema/fixtures/policy/invalid/skew-tolerance-compound.json +6 -0
  660. package/schema/fixtures/policy/invalid/unknown-autonomy.json +7 -0
  661. package/schema/fixtures/policy/invalid/unknown-class-rule-key.json +6 -0
  662. package/schema/fixtures/policy/invalid/unknown-top-level-key.json +7 -0
  663. package/schema/fixtures/policy/invalid/vault-passphrase-env-empty.json +6 -0
  664. package/schema/fixtures/policy/invalid/vault-passphrase-literal.json +6 -0
  665. package/schema/fixtures/policy/invalid/version-not-string.json +4 -0
  666. package/schema/fixtures/policy/valid/canonical.json +47 -0
  667. package/schema/fixtures/policy/valid/checkpoint-keys.json +18 -0
  668. package/schema/fixtures/policy/valid/class-approvers-limits.json +25 -0
  669. package/schema/fixtures/policy/valid/class-retro-rate.json +17 -0
  670. package/schema/fixtures/policy/valid/global-budgets.json +19 -0
  671. package/schema/fixtures/policy/valid/human-only.json +9 -0
  672. package/schema/fixtures/policy/valid/minimal.json +6 -0
  673. package/schema/fixtures/policy/valid/protected-paths.json +10 -0
  674. package/schema/fixtures/policy/valid/record-namespace.json +13 -0
  675. package/schema/fixtures/policy/valid/request-volume-limits.json +26 -0
  676. package/schema/fixtures/policy/valid/retention-and-sampling-secret.json +16 -0
  677. package/schema/fixtures/policy/valid/skew-tolerance.json +15 -0
  678. package/schema/fixtures/policy/valid/vault-passphrase-env.json +14 -0
  679. package/schema/fixtures/policy/valid/wildcards.json +15 -0
  680. package/schema/fixtures/policy-md/invalid/alias-bomb.md +15 -0
  681. package/schema/fixtures/policy-md/invalid/no-fence.md +7 -0
  682. package/schema/fixtures/policy-md/invalid/protected-route-not-a-subclass.md +16 -0
  683. package/schema/fixtures/policy-md/invalid/schema-invalid-autonomy.md +16 -0
  684. package/schema/fixtures/policy-md/invalid/schema-invalid-read-proof.md +17 -0
  685. package/schema/fixtures/policy-md/invalid/two-fences.md +19 -0
  686. package/schema/fixtures/policy-md/invalid/unclosed-fence.md +11 -0
  687. package/schema/fixtures/policy-md/invalid/wrong-info-string.md +11 -0
  688. package/schema/fixtures/policy-md/invalid/yaml-syntax-error.md +13 -0
  689. package/schema/fixtures/policy-md/precedence/both/APPROVAL.md +7 -0
  690. package/schema/fixtures/policy-md/precedence/both/APPROVALS.md +7 -0
  691. package/schema/fixtures/policy-md/precedence/fallback-only/APPROVALS.md +7 -0
  692. package/schema/fixtures/policy-md/valid/canonical.md +50 -0
  693. package/schema/fixtures/policy-md/valid/daemon-read-proof.md +18 -0
  694. package/schema/fixtures/policy-md/valid/minimal.md +3 -0
  695. package/schema/fixtures/policy-md/valid/prose-lookalikes.md +54 -0
  696. package/schema/fixtures/policy-md/valid/routed-protected-paths.md +49 -0
  697. package/schema/fixtures/policy-md/valid/with-values.md +79 -0
  698. package/schema/fixtures/sample-record/invalid/bad-date-time.json +4 -0
  699. package/schema/fixtures/sample-record/invalid/missing-required-field.json +3 -0
  700. package/schema/fixtures/sample-record/invalid/unknown-top-level-field.json +5 -0
  701. package/schema/fixtures/sample-record/invalid/wrong-type.json +4 -0
  702. package/schema/fixtures/sample-record/valid/minimal.json +4 -0
  703. package/schema/fixtures/sample-record/valid/with-note.json +5 -0
  704. package/schema/fixtures/values/invalid/class-shaped.json +9 -0
  705. package/schema/fixtures/values/invalid/duplicate-entry.json +4 -0
  706. package/schema/fixtures/values/invalid/non-string-item.json +4 -0
  707. package/schema/fixtures/values/invalid/over-cap.json +26 -0
  708. package/schema/fixtures/values/invalid/unknown-key.json +5 -0
  709. package/schema/fixtures/values/invalid/version-string.json +1 -0
  710. package/schema/fixtures/values/valid/empty-lists.json +7 -0
  711. package/schema/fixtures/values/valid/full.json +20 -0
  712. package/schema/fixtures/values/valid/minimal.json +1 -0
  713. package/schema/fixtures/values-md/invalid/schema-invalid.md +62 -0
  714. package/schema/fixtures/values-md/invalid/two-blocks.md +69 -0
  715. package/schema/fixtures/values-md/invalid/unterminated.md +61 -0
  716. package/schema/fixtures/values-md/invalid/yaml-error.md +63 -0
  717. package/schema/fixtures/values-md/valid/absent.md +50 -0
  718. package/schema/fixtures/values-md/valid/with-values.md +79 -0
  719. package/schema/policy.schema.json +501 -0
  720. package/schema/sample-record.schema.json +26 -0
  721. package/schema/values.schema.json +55 -0
  722. package/templates/codex/README.md +9 -0
@@ -0,0 +1,747 @@
1
+ /**
2
+ * AGENTS.md permissions import (SPEC.md §2, §12) — turn permissions PROSE into
3
+ * a DRAFT policy block a human can read, correct, and confirm.
4
+ *
5
+ * SPEC.md §2 names the gap this closes: AGENTS.md files "routinely contain
6
+ * permissions sections splitting actions into 'allowed without prompting' and
7
+ * 'require approval first'", and "nothing checks". SPEC.md §12 gives the verb:
8
+ * `approval import agents-md` "parses ... permissions sections into draft
9
+ * policy classes for human confirmation".
10
+ *
11
+ * ## This module is deterministic, and there is no model in it
12
+ *
13
+ * Per CLAUDE.md's engineering invariants, routing and policy are pure
14
+ * deterministic code; LLMs are confined to language tasks. Reading a bullet
15
+ * list is a language task in appearance only — its OUTPUT is a permission
16
+ * document, so the mapping is a fixed, ordered, documented keyword table
17
+ * ({@link CLASS_TABLE}), not a judgement. The same bytes always produce the
18
+ * same draft, on any machine, with no network and no clock. An LLM-assisted
19
+ * `--suggest` (proposing classes for bullets this table cannot place) is a
20
+ * separate, opt-in, out-of-scope idea: it would be allowed to propose, never
21
+ * to decide.
22
+ *
23
+ * ## The grammar
24
+ *
25
+ * Input is CommonMark-ish markdown. The scanner is line-based:
26
+ *
27
+ * - **Fenced code blocks** (``` or ~~~, 3+ markers, indented at most 3 spaces)
28
+ * are skipped entirely. A bullet inside an example block is an example.
29
+ * - **Headings** are ATX only: `^ {0,3}#{1,6}\s+text`, trailing `#`s stripped.
30
+ * Setext headings are not recognised; the convention in the wild is ATX.
31
+ * - A heading whose text contains `permissions` (case-insensitive, at any
32
+ * level) opens the **permissions region**. The region closes at the next
33
+ * non-canonical heading whose level is less than or equal to the permissions
34
+ * heading's level.
35
+ * - Three **canonical sub-headings** open a section, matched case-insensitively
36
+ * against {@link SECTION_PHRASES} after normalisation (lowercased, markdown
37
+ * emphasis and backticks stripped, whitespace collapsed, trailing `:`
38
+ * dropped). They are recognised at ANY level and, deliberately, whether or
39
+ * not a parent `Permissions` heading exists: the bare three-heading layout is
40
+ * common in AGENTS.md files.
41
+ * - **Bullets** are `-` or `*` list items (`^\s*[-*]\s+`) appearing while a
42
+ * section is open. A following line that is not blank, not a heading, not a
43
+ * list item and not a fence is a **continuation** and is joined to the
44
+ * previous bullet with a single space. Any heading closes the open section.
45
+ * - Every other line is ignored.
46
+ *
47
+ * Non-canonical headings seen inside the permissions region, and non-canonical
48
+ * headings that interrupt an open section, are reported in `ignored` rather
49
+ * than silently dropped: a heading the importer did not understand may be
50
+ * carrying permissions prose, and the human confirming the draft is the one who
51
+ * should decide.
52
+ *
53
+ * ## Fail closed
54
+ *
55
+ * A bullet the table cannot place is NOT guessed at and NOT dropped. It becomes
56
+ * an `unmapped` entry, is preserved verbatim as a comment in the draft, and is
57
+ * covered by `defaults.autonomy: manual` — the strictest outcome available.
58
+ * Likewise a source with no permissions section produces an empty draft (all
59
+ * classes manual by default) plus a warning, never a permissive one.
60
+ *
61
+ * ## The values draft
62
+ *
63
+ * Since APRV-240 the same file is scanned a second time for four optional
64
+ * headings ("what I value", "what good looks like", "how I like to work",
65
+ * "what I want from you") and their bullets are drafted into a
66
+ * ` ```yaml approval-values ` block (SPEC.md §5.3). Every bullet lands in
67
+ * `wants:`, and nothing is ever placed in `love:`, `like:` or `dislike:`.
68
+ * Grading is the human's act. This importer can see that a line was written
69
+ * down; it cannot see how much its author meant it, and a guessed grade would
70
+ * put words in their mouth inside the one block of `APPROVAL.md` that exists to
71
+ * carry their own.
72
+ *
73
+ * ## Namespaces
74
+ *
75
+ * SPEC.md §7 reserves top-level namespaces to the spec and lets implementations
76
+ * add sub-classes freely. The developer-workstation vocabulary this table emits
77
+ * (`vcs.*`, `deps.*`, `release.*`, `exec.*`, `network.*`, `policy.edit`) is not
78
+ * in the §7 table, which was written for life-admin side effects. That is a
79
+ * deliberate, visible property of a DRAFT: the classes are proposals a human
80
+ * renames or upstreams before confirming, and the draft says so in its header.
81
+ */
82
+ /**
83
+ * Canonical section phrases and their tolerant variants, matched against a
84
+ * normalised heading by exact equality first and then by prefix/containment of
85
+ * the variant inside the heading. Order matters only between sections: a
86
+ * heading matching more than one section's variants takes the FIRST section in
87
+ * this list, and the list is ordered strictest-first so an ambiguous heading
88
+ * lands on the stricter reading.
89
+ */
90
+ const SECTION_PHRASES = [
91
+ ["never", ["never", "never do", "forbidden", "prohibited", "not permitted", "off limits"]],
92
+ [
93
+ "approval-first",
94
+ [
95
+ "require approval first",
96
+ "requires approval",
97
+ "require approval",
98
+ "approval required",
99
+ "ask first",
100
+ "ask before",
101
+ "needs approval",
102
+ ],
103
+ ],
104
+ [
105
+ "allowed",
106
+ [
107
+ "allowed without prompting",
108
+ "allowed without asking",
109
+ "allowed",
110
+ "autonomous",
111
+ "no prompt needed",
112
+ "safe to run",
113
+ ],
114
+ ],
115
+ ];
116
+ /** Marker that a heading opens the permissions region. */
117
+ const PERMISSIONS_MARKER = "permissions";
118
+ /**
119
+ * The class heuristic: an ORDERED, STABLE table. First match wins, and the
120
+ * order of this array IS the precedence. Each entry lists alternative keyword
121
+ * conjunctions; an alternative matches when every one of its keywords appears
122
+ * as a substring of the normalised bullet text.
123
+ *
124
+ * Ordering rules, so future edits stay principled:
125
+ *
126
+ * 1. The most consequential and most specific classes come first, because a
127
+ * bullet naming several actions ("git push, merges to main, tag creation")
128
+ * is placed by its first match and the safer placement is the broader,
129
+ * more consequential class.
130
+ * 2. `network.call` precedes `deps.add` on purpose: "any network call beyond
131
+ * package installs" contains "install" and is not a dependency bullet.
132
+ * 3. `vcs.push` precedes `vcs.push.main`: a bullet naming pushes generally
133
+ * should govern all pushes, not only pushes to the default branch.
134
+ * 4. Generic verbs (`edit`, `read`) come last, since almost every bullet
135
+ * contains one.
136
+ *
137
+ * Adding a keyword here changes what a draft proposes for existing files, so
138
+ * the table is pinned byte-for-byte by `tests/agents-md.test.ts` fixtures.
139
+ */
140
+ export const CLASS_TABLE = [
141
+ {
142
+ cls: "account.credential",
143
+ any: [["credential"], ["token"], ["vault"], ["secret"], ["api key"], ["password"]],
144
+ },
145
+ {
146
+ cls: "vcs.history.rewrite",
147
+ any: [["rewrite", "history"], ["force-push"], ["force push"], ["--force"]],
148
+ },
149
+ {
150
+ cls: "policy.edit",
151
+ any: [
152
+ ["approval.md"],
153
+ ["approvals.md"],
154
+ [".approval/"],
155
+ ["agents.md"],
156
+ ["claude.md"],
157
+ ["policy file"],
158
+ ["ci config"],
159
+ ["ci/release"],
160
+ ["release config"],
161
+ ["workflow file"],
162
+ ],
163
+ },
164
+ { cls: "vcs.push", any: [["git push"], ["push"]] },
165
+ { cls: "vcs.push.main", any: [["merge", "main"], ["merge", "master"], ["merge", "trunk"]] },
166
+ {
167
+ cls: "release.publish",
168
+ any: [
169
+ ["npm publish"],
170
+ ["npm version"],
171
+ ["registry"],
172
+ ["tag creation"],
173
+ ["create a tag"],
174
+ ["publish"],
175
+ ["release"],
176
+ ],
177
+ },
178
+ {
179
+ cls: "network.call",
180
+ any: [["network"], ["api call"], ["webhook"], ["send"], ["http"], ["outbound"], ["email"]],
181
+ },
182
+ { cls: "deps.add", any: [["depend"], ["install"], ["upgrade"]] },
183
+ // "delet" rather than "delete": the stem is what matches "deleting" and
184
+ // "deletion" too, and a bullet that says "Deleting files ..." must not fall
185
+ // through to unmapped on an inflection.
186
+ { cls: "data.delete", any: [["delet"], ["rm -rf"], ["destroy"], ["drop table"]] },
187
+ { cls: "vcs.commit.branch", any: [["commit"]] },
188
+ {
189
+ cls: "exec.local",
190
+ any: [
191
+ ["run tests"],
192
+ ["run the tests"],
193
+ ["lint"],
194
+ ["typecheck"],
195
+ ["type-check"],
196
+ ["build"],
197
+ ["script"],
198
+ ],
199
+ },
200
+ {
201
+ cls: "files.write.workspace",
202
+ any: [["edit"], ["write"], ["writing"], ["modif"], ["refactor"]],
203
+ },
204
+ { cls: "read.*", any: [["read"], ["list director"], ["search"], ["inspect"], ["grep"]] },
205
+ ];
206
+ /** Strictness rank; lower is stricter (SPEC.md §5.2 "deny beats allow"). */
207
+ const STRICTNESS = {
208
+ manual: 0,
209
+ supervised: 1,
210
+ autonomous: 2,
211
+ };
212
+ /** Autonomy a section proposes. `never` has no v0.1 level of its own. */
213
+ const SECTION_AUTONOMY = {
214
+ allowed: "autonomous",
215
+ "approval-first": "manual",
216
+ never: "manual",
217
+ };
218
+ /** Lowercase, strip emphasis/backticks, collapse whitespace, drop trailing ':'. */
219
+ function normaliseHeading(text) {
220
+ return text
221
+ .replace(/[`*_]/gu, "")
222
+ .trim()
223
+ .replace(/[:.]+$/u, "")
224
+ .replace(/\s+/gu, " ")
225
+ .toLowerCase();
226
+ }
227
+ /** Match a heading against the section phrases; `null` when it is not one. */
228
+ function sectionOf(heading) {
229
+ const text = normaliseHeading(heading);
230
+ if (text.length === 0)
231
+ return null;
232
+ for (const [section, phrases] of SECTION_PHRASES) {
233
+ for (const phrase of phrases) {
234
+ if (text === phrase || text.startsWith(`${phrase} `) || text.includes(phrase)) {
235
+ return section;
236
+ }
237
+ }
238
+ }
239
+ return null;
240
+ }
241
+ /** Text used for keyword matching: lowercased with whitespace collapsed. */
242
+ export function normaliseBullet(text) {
243
+ return text.replace(/\s+/gu, " ").trim().toLowerCase();
244
+ }
245
+ /**
246
+ * The class this bullet proposes, or `null` when the table cannot place it.
247
+ *
248
+ * Deterministic, total, and side-effect free: the first entry of
249
+ * {@link CLASS_TABLE} with a satisfied keyword conjunction wins.
250
+ */
251
+ export function classifyBullet(text) {
252
+ const haystack = normaliseBullet(text);
253
+ for (const entry of CLASS_TABLE) {
254
+ for (const alternative of entry.any) {
255
+ if (alternative.every((keyword) => haystack.includes(keyword)))
256
+ return entry.cls;
257
+ }
258
+ }
259
+ return null;
260
+ }
261
+ const FENCE_OPEN = /^ {0,3}(`{3,}|~{3,})/u;
262
+ const HEADING = /^ {0,3}(#{1,6})\s+(.*)$/u;
263
+ const LIST_ITEM = /^\s*[-*]\s+(.*)$/u;
264
+ /**
265
+ * Parse the permissions region of an AGENTS.md-style document.
266
+ *
267
+ * Never throws. Pure function of `markdown`; see the module header for the
268
+ * grammar it accepts.
269
+ */
270
+ export function parseAgentsMd(markdown) {
271
+ const sections = { allowed: [], approvalFirst: [], never: [] };
272
+ const ignored = [];
273
+ const warnings = [];
274
+ const lines = markdown.split(/\r\n|\n|\r/u);
275
+ let fence = null;
276
+ let inRegion = false;
277
+ let regionLevel = 0;
278
+ let sawPermissionsHeading = false;
279
+ let current = null;
280
+ let currentLevel = 0;
281
+ let lastBullet = null;
282
+ const bucket = (section) => section === "allowed"
283
+ ? sections.allowed
284
+ : section === "approval-first"
285
+ ? sections.approvalFirst
286
+ : sections.never;
287
+ for (let index = 0; index < lines.length; index += 1) {
288
+ const line = lines[index];
289
+ const lineNumber = index + 1;
290
+ if (fence !== null) {
291
+ const close = FENCE_OPEN.exec(line);
292
+ const marker = close === null ? "" : (close[1] ?? "");
293
+ if (marker.length >= fence.length && marker.startsWith(fence.slice(0, 1)))
294
+ fence = null;
295
+ continue;
296
+ }
297
+ const open = FENCE_OPEN.exec(line);
298
+ if (open !== null) {
299
+ fence = open[1];
300
+ lastBullet = null;
301
+ continue;
302
+ }
303
+ const heading = HEADING.exec(line);
304
+ if (heading !== null) {
305
+ const level = heading[1].length;
306
+ const raw = heading[2].replace(/\s+#+\s*$/u, "").trim();
307
+ lastBullet = null;
308
+ const section = sectionOf(raw);
309
+ if (section !== null) {
310
+ current = section;
311
+ currentLevel = level;
312
+ continue;
313
+ }
314
+ const wasInSection = current !== null;
315
+ const sectionLevel = currentLevel;
316
+ current = null;
317
+ if (normaliseHeading(raw).includes(PERMISSIONS_MARKER)) {
318
+ inRegion = true;
319
+ sawPermissionsHeading = true;
320
+ regionLevel = level;
321
+ continue;
322
+ }
323
+ if (inRegion && level <= regionLevel) {
324
+ inRegion = false;
325
+ continue;
326
+ }
327
+ if (inRegion || (wasInSection && level > sectionLevel))
328
+ ignored.push(raw);
329
+ continue;
330
+ }
331
+ if (current === null) {
332
+ lastBullet = null;
333
+ continue;
334
+ }
335
+ const item = LIST_ITEM.exec(line);
336
+ if (item !== null) {
337
+ const text = item[1].trim();
338
+ if (text.length === 0) {
339
+ lastBullet = null;
340
+ continue;
341
+ }
342
+ const bullet = { text, line: lineNumber };
343
+ bucket(current).push(bullet);
344
+ lastBullet = bullet;
345
+ continue;
346
+ }
347
+ if (line.trim().length === 0) {
348
+ lastBullet = null;
349
+ continue;
350
+ }
351
+ // A continuation of the previous bullet: wrapped prose, joined with one
352
+ // space so the draft's comment carries the whole sentence.
353
+ if (lastBullet !== null)
354
+ lastBullet.text = `${lastBullet.text} ${line.trim()}`;
355
+ }
356
+ const total = sections.allowed.length + sections.approvalFirst.length + sections.never.length;
357
+ if (total === 0) {
358
+ warnings.push(sawPermissionsHeading
359
+ ? "a permissions heading was found but no bullets under any recognised section (allowed / require approval first / never); the draft declares no classes and everything falls to defaults.autonomy: manual"
360
+ : "no permissions section found (looked for a heading containing \"permissions\", or the sub-headings \"allowed without prompting\" / \"require approval first\" / \"never\"); the draft declares no classes and everything falls to defaults.autonomy: manual");
361
+ }
362
+ return { sections, ignored, warnings };
363
+ }
364
+ // ---------------------------------------------------------------------------
365
+ // The values headings (APRV-240)
366
+ /**
367
+ * Headings whose bullets become a DRAFT values block (SPEC.md §5.3).
368
+ *
369
+ * Matched against a heading run through {@link normaliseHeading}, at ANY level,
370
+ * with the tolerance {@link sectionOf} already uses (equality, then prefix,
371
+ * then containment), so "## What I value most" and "**What I want from you:**"
372
+ * are recognised too. Four phrases and no more: this is a fixed vocabulary a
373
+ * human can be told about in one line of documentation, and a wider net would
374
+ * start collecting prose nobody offered as values.
375
+ */
376
+ const VALUES_HEADING_PHRASES = [
377
+ "what i value",
378
+ "what good looks like",
379
+ "how i like to work",
380
+ "what i want from you",
381
+ ];
382
+ /**
383
+ * The caps of `values.schema.json` `$defs/valueList`, restated so the renderer
384
+ * can respect them without importing a validator. `tests/agents-md.test.ts`
385
+ * reads the schema and asserts these two numbers still match it, so the copy
386
+ * cannot drift.
387
+ */
388
+ const VALUES_MAX_ITEMS = 20;
389
+ const VALUES_MAX_LENGTH = 200;
390
+ /** True when this heading opens a values section. */
391
+ function isValuesHeading(heading) {
392
+ const text = normaliseHeading(heading);
393
+ if (text.length === 0)
394
+ return false;
395
+ return VALUES_HEADING_PHRASES.some((phrase) => text === phrase || text.startsWith(`${phrase} `) || text.includes(phrase));
396
+ }
397
+ /**
398
+ * Bring one bullet under the schema's 200-character cap.
399
+ *
400
+ * Truncation with a visible marker, rather than refusing the draft or dropping
401
+ * the entry. The draft exists to be read and corrected by hand, so a line the
402
+ * human can see is over-long is a line they can repair in place; refusing would
403
+ * cost them the other nineteen bullets over one long sentence, and dropping is
404
+ * the one outcome ruled out everywhere in this module. Sliced by CODE POINT, so
405
+ * an astral character is never cut in half (Ajv measures `maxLength` the same
406
+ * way).
407
+ */
408
+ function capLength(text) {
409
+ const points = [...text];
410
+ if (points.length <= VALUES_MAX_LENGTH)
411
+ return { text, truncated: false };
412
+ return { text: `${points.slice(0, VALUES_MAX_LENGTH - 1).join("")}…`, truncated: true };
413
+ }
414
+ /**
415
+ * Collect the bullets under the optional values headings of an AGENTS.md-style
416
+ * document (SPEC.md §5.3).
417
+ *
418
+ * ## Everything goes to `wants`, and nothing is graded
419
+ *
420
+ * The values block has three standing grades (`love`, `like`, `dislike`) and
421
+ * one behavioural list (`wants`). This function fills `wants` and leaves the
422
+ * three grades empty, always. A grade is a statement of taste, and it is the
423
+ * human's to make: the source shows that a line was written under a heading, it
424
+ * does not show how strongly it was meant, and an importer that inferred
425
+ * "love" from an exclamation mark or a heading's wording would be putting words
426
+ * in its reader's mouth in the one block of `APPROVAL.md` that exists to carry
427
+ * theirs. `wants` is the honest destination for a bullet whose grade is
428
+ * unknown: it says the operator asked for something, which is exactly what a
429
+ * bullet under "what I want from you" demonstrates.
430
+ *
431
+ * ## The scan
432
+ *
433
+ * A second line-based pass over the same primitives {@link parseAgentsMd} uses,
434
+ * with the same rules: fenced code blocks are skipped whole (a bullet in an
435
+ * example block is an example), headings are ATX at any level, a values heading
436
+ * opens a section, any other heading closes one, and a non-blank line that is
437
+ * not a bullet, heading or fence is a continuation joined to the previous
438
+ * bullet with a single space.
439
+ *
440
+ * Never throws. No clock, no filesystem, no network.
441
+ */
442
+ export function parseValuesHeadings(markdown) {
443
+ const headings = [];
444
+ const collected = [];
445
+ const warnings = [];
446
+ const lines = markdown.split(/\r\n|\n|\r/u);
447
+ let fence = null;
448
+ let open = false;
449
+ let lastBullet = null;
450
+ for (const line of lines) {
451
+ if (fence !== null) {
452
+ const close = FENCE_OPEN.exec(line);
453
+ const marker = close === null ? "" : (close[1] ?? "");
454
+ if (marker.length >= fence.length && marker.startsWith(fence.slice(0, 1)))
455
+ fence = null;
456
+ continue;
457
+ }
458
+ const opened = FENCE_OPEN.exec(line);
459
+ if (opened !== null) {
460
+ fence = opened[1];
461
+ lastBullet = null;
462
+ continue;
463
+ }
464
+ const heading = HEADING.exec(line);
465
+ if (heading !== null) {
466
+ const raw = heading[2].replace(/\s+#+\s*$/u, "").trim();
467
+ lastBullet = null;
468
+ open = isValuesHeading(raw);
469
+ if (open)
470
+ headings.push(normaliseHeading(raw));
471
+ continue;
472
+ }
473
+ if (!open) {
474
+ lastBullet = null;
475
+ continue;
476
+ }
477
+ const item = LIST_ITEM.exec(line);
478
+ if (item !== null) {
479
+ const text = item[1].trim();
480
+ if (text.length === 0) {
481
+ lastBullet = null;
482
+ continue;
483
+ }
484
+ const bullet = { text };
485
+ collected.push(bullet);
486
+ lastBullet = bullet;
487
+ continue;
488
+ }
489
+ if (line.trim().length === 0) {
490
+ lastBullet = null;
491
+ continue;
492
+ }
493
+ if (lastBullet !== null)
494
+ lastBullet.text = `${lastBullet.text} ${line.trim()}`;
495
+ }
496
+ const seen = new Set();
497
+ const unique = [];
498
+ let duplicates = 0;
499
+ for (const bullet of collected) {
500
+ const capped = capLength(bullet.text);
501
+ if (capped.truncated) {
502
+ warnings.push(`a values bullet is ${String([...bullet.text].length)} characters and values.schema.json caps an entry at ${String(VALUES_MAX_LENGTH)}; the draft carries it truncated rather than dropping it, so shorten it by hand before confirming: ${JSON.stringify(capped.text)}`);
503
+ }
504
+ // Deduped AFTER truncation, because `uniqueItems` is checked on the values
505
+ // the block actually carries: two long bullets that differ only past the
506
+ // cap become one entry, and a draft that emitted both would fail its schema.
507
+ if (seen.has(capped.text)) {
508
+ duplicates += 1;
509
+ continue;
510
+ }
511
+ seen.add(capped.text);
512
+ unique.push(capped.text);
513
+ }
514
+ if (duplicates > 0) {
515
+ warnings.push(`${String(duplicates)} repeated values ${duplicates === 1 ? "bullet was" : "bullets were"} collapsed; values.schema.json requires the entries of a list to be unique`);
516
+ }
517
+ const wants = unique.slice(0, VALUES_MAX_ITEMS);
518
+ const overflow = unique.slice(VALUES_MAX_ITEMS);
519
+ if (overflow.length > 0) {
520
+ warnings.push(`${String(overflow.length)} values ${overflow.length === 1 ? "bullet is" : "bullets are"} past the cap of ${String(VALUES_MAX_ITEMS)}; they are preserved as comments in the draft instead of in wants:, and a human promotes the ones they want`);
521
+ }
522
+ return { headings, wants, overflow, warnings };
523
+ }
524
+ /** Ordered (section, bullet) pairs: allowed, then approval-first, then never. */
525
+ function orderedBullets(parse) {
526
+ return [
527
+ ...parse.sections.allowed.map((bullet) => ({ bullet, section: "allowed" })),
528
+ ...parse.sections.approvalFirst.map((bullet) => ({
529
+ bullet,
530
+ section: "approval-first",
531
+ })),
532
+ ...parse.sections.never.map((bullet) => ({ bullet, section: "never" })),
533
+ ];
534
+ }
535
+ /**
536
+ * Parse and classify: the whole deterministic half of `approval import
537
+ * agents-md`. Emitting bytes is {@link renderDraftPolicy}'s job.
538
+ *
539
+ * Conflicts follow SPEC.md §5.2 "deny beats allow": when bullets from different
540
+ * sections claim the same class, the strictest autonomy wins and a warning
541
+ * names both bullets, because a class that appears in both an allow list and an
542
+ * approval list is a contradiction in the SOURCE that a human must resolve.
543
+ */
544
+ export function importAgentsMd(markdown) {
545
+ const parse = parseAgentsMd(markdown);
546
+ const values = parseValuesHeadings(markdown);
547
+ // The values notes join the one list every surface already prints. They are
548
+ // notes about a block that enforces nothing, so they change no verdict and
549
+ // never make the policy half of this import fail.
550
+ const warnings = [...parse.warnings, ...values.warnings];
551
+ const unmapped = [];
552
+ const byClass = new Map();
553
+ for (const { bullet, section } of orderedBullets(parse)) {
554
+ const cls = classifyBullet(bullet.text);
555
+ if (cls === null) {
556
+ unmapped.push({ text: bullet.text, section });
557
+ warnings.push(`no class matched ${JSON.stringify(bullet.text)} (section: ${section}); it is preserved as a comment and covered by defaults.autonomy: manual`);
558
+ continue;
559
+ }
560
+ const autonomy = SECTION_AUTONOMY[section];
561
+ const existing = byClass.get(cls);
562
+ if (existing === undefined) {
563
+ byClass.set(cls, {
564
+ cls,
565
+ autonomy,
566
+ bullets: [{ text: bullet.text, section }],
567
+ from: { text: bullet.text, section },
568
+ });
569
+ continue;
570
+ }
571
+ existing.bullets.push({ text: bullet.text, section });
572
+ if (existing.from.section !== section) {
573
+ const stricter = STRICTNESS[autonomy] < STRICTNESS[existing.autonomy];
574
+ const winner = stricter ? autonomy : existing.autonomy;
575
+ warnings.push(`class ${cls} is claimed by two sections; the stricter autonomy wins (${winner}): ${JSON.stringify(existing.from.text)} (${existing.from.section}) and ${JSON.stringify(bullet.text)} (${section})`);
576
+ if (stricter) {
577
+ existing.autonomy = autonomy;
578
+ existing.from = { text: bullet.text, section };
579
+ }
580
+ }
581
+ }
582
+ return { classes: [...byClass.values()], unmapped, ignored: parse.ignored, warnings, values };
583
+ }
584
+ /** Info string of the machine-readable policy block (SPEC.md §5). */
585
+ export const POLICY_INFO_STRING = "yaml approval-policy";
586
+ /**
587
+ * Info string of the OPTIONAL values block (SPEC.md §5.3).
588
+ *
589
+ * Spelled here rather than imported from `core/values.ts`, exactly as
590
+ * {@link POLICY_INFO_STRING} is spelled rather than imported from
591
+ * `core/policy-load.ts`. `tests/values-inert.test.ts` (APRV-237) lets three CLI
592
+ * surfaces import the values reader and no module under `src/core/` at all,
593
+ * because a core module holding a reference to that reader is something review
594
+ * has to re-argue on every change. A label is not a reader, and this renderer
595
+ * needs only the label. The two spellings are pinned to each other by
596
+ * `tests/agents-md.test.ts`, so the copy cannot drift.
597
+ */
598
+ const VALUES_INFO_STRING = "yaml approval-values";
599
+ function draftHeader(source) {
600
+ return [
601
+ `# DRAFT policy, generated from ${source} by \`approval import agents-md\`.`,
602
+ "#",
603
+ "# NOTHING HAS BEEN APPLIED. This block was printed, not written: APPROVAL.md",
604
+ "# is untouched, no event was appended, and no attestation was made. A human",
605
+ "# confirms a draft by pasting it into APPROVAL.md and running",
606
+ "# `approval policy amend`, which diffs it, attests it, and commits it.",
607
+ "#",
608
+ "# The v0.1 vocabulary has three levels (manual > supervised > autonomous) and",
609
+ "# NO forbid level, so bullets from a \"Never\" section are rendered `manual`",
610
+ "# and carry a `# never:` comment. Manual is not never — a human can still say",
611
+ "# yes. Read every `# never:` line before confirming this draft.",
612
+ "#",
613
+ "# Class names are PROPOSALS. The importer places bullets with a fixed keyword",
614
+ "# table into the SPEC.md §7 developer-workstation namespaces (vcs.*, deps.*,",
615
+ "# release.*, exec.*, network.*, policy.*). Rename any that do not match the",
616
+ "# classes your adapters actually declare.",
617
+ "#",
618
+ "# No `approvers:` and no `channels:` are invented here: a generated file must",
619
+ "# not name who may approve, or where. Add them by hand (SPEC.md §5.1).",
620
+ ];
621
+ }
622
+ /**
623
+ * True when a values draft should be rendered at all: the source declared at
624
+ * least one of the four headings. One predicate, so "when is there a values
625
+ * draft" is answered in one place rather than at each surface.
626
+ */
627
+ function hasValuesDraft(values) {
628
+ return values !== null && values !== undefined && values.headings.length > 0;
629
+ }
630
+ /**
631
+ * Render the values draft, fenced (APRV-240).
632
+ *
633
+ * The argument is the whole {@link ValuesDraft} rather than its bullets alone,
634
+ * because the entries past the cap have to appear in the output as comments:
635
+ * the renderer needs to see what was left out in order to say so.
636
+ *
637
+ * Deterministic, like everything else here. Entries are emitted as
638
+ * double-quoted scalars via `JSON.stringify`, whose escapes are all valid YAML
639
+ * double-quoted escapes, so a bullet full of backticks, colons and `#` survives
640
+ * the round trip without the renderer having to reason about YAML quoting.
641
+ */
642
+ export function renderFencedValuesDraft(draft, source) {
643
+ const lines = [
644
+ `# DRAFT values block, imported from ${source} by \`approval import agents-md\`.`,
645
+ "#",
646
+ "# NOTHING HAS BEEN APPLIED, exactly as for the policy draft: this block was",
647
+ "# printed, not written. APPROVAL.md is untouched and nothing was attested.",
648
+ "# The values block lives INSIDE APPROVAL.md, so pasting it changes the file's",
649
+ "# bytes and invalidates the standing attestation; renew it immediately after.",
650
+ "#",
651
+ "# EVERY bullet is in `wants:`, and nothing is graded. `love:`, `like:` and",
652
+ "# `dislike:` are yours to fill in. A grade is a statement of taste and it is",
653
+ "# yours to make: this importer can see that you wrote a line down, and cannot",
654
+ "# see how much you meant it. Guessing would put words in your mouth.",
655
+ "#",
656
+ "# This block is guidance and never policy. Nothing here is enforced, counted",
657
+ "# or checked, and no routing, class match, sampling draw, budget or token",
658
+ "# reads it (SPEC.md §11.1 invariant 10).",
659
+ "",
660
+ "version: 1",
661
+ ];
662
+ if (draft.wants.length === 0) {
663
+ lines.push("# The headings were there and carried no bullets. An empty list is a real", "# answer: it says the question was considered and left blank.", "wants: []");
664
+ }
665
+ else {
666
+ lines.push("wants:");
667
+ for (const want of draft.wants)
668
+ lines.push(` - ${JSON.stringify(want)}`);
669
+ }
670
+ if (draft.overflow.length > 0) {
671
+ lines.push("", `# OVER THE CAP: values.schema.json admits ${String(VALUES_MAX_ITEMS)} entries and the source`, "# offered more. These are preserved verbatim and are NOT in `wants:`. Promote", "# the ones you want by hand, in place of ones above:");
672
+ for (const want of draft.overflow)
673
+ lines.push(`# ${want}`);
674
+ }
675
+ return `\`\`\`${VALUES_INFO_STRING}\n${lines.join("\n")}\n\`\`\`\n`;
676
+ }
677
+ /**
678
+ * The fenced values draft for an import, or `null` when the source declared no
679
+ * values headings. The `--json` surface's `values_draft` field, verbatim.
680
+ */
681
+ export function valuesDraftOf(result, source) {
682
+ return hasValuesDraft(result.values) ? renderFencedValuesDraft(result.values, source) : null;
683
+ }
684
+ /**
685
+ * Render the draft policy YAML. Deterministic: no clock, no cwd, no
686
+ * randomness — the only inputs are the import result and the source label, so
687
+ * the same file always produces the same bytes.
688
+ *
689
+ * With `values` omitted (or from a source that declared no values headings) the
690
+ * output is bare YAML with no fence, a valid policy under
691
+ * `schema/policy.schema.json` that loads through `loadPolicy` once wrapped in a
692
+ * ` ```yaml approval-policy ` fence.
693
+ *
694
+ * With a values draft the shape changes, and it has to. A values fence appended
695
+ * to bare YAML could not be pasted into a policy fence, because the values
696
+ * block's own closing fence would close the policy block and leave a file that
697
+ * loads as neither. So a two-block draft is emitted already fenced: the policy
698
+ * inside its ` ```yaml approval-policy ` fence, then the values fence after it,
699
+ * which is the shape `APPROVAL.md` itself has and which the policy loader and
700
+ * the values reader each read straight off disk.
701
+ */
702
+ export function renderDraftPolicy(result, source, values) {
703
+ const lines = [...draftHeader(source), ""];
704
+ lines.push('version: "0.1"', "");
705
+ lines.push("defaults:", " autonomy: manual # anything not named below needs sign-off", ' approval_ttl: "24h"', " on_expiry: reject", "");
706
+ if (result.classes.length === 0) {
707
+ lines.push("# No classes: the source declared no permissions bullets this importer could", "# use. Every class therefore resolves to defaults.autonomy (manual).");
708
+ }
709
+ else {
710
+ lines.push("classes:");
711
+ for (const entry of result.classes) {
712
+ for (const bullet of entry.bullets) {
713
+ // The section is named only when more than one bullet mapped here: with
714
+ // one bullet the heading it came from is not in question, and with two
715
+ // the reader needs to see which section the surviving autonomy came from.
716
+ const label = bullet.section === "never"
717
+ ? "never"
718
+ : entry.bullets.length > 1
719
+ ? `from (${bullet.section})`
720
+ : "from";
721
+ lines.push(` # ${label}: ${bullet.text}`);
722
+ }
723
+ lines.push(` ${entry.cls}: { autonomy: ${entry.autonomy} }`);
724
+ }
725
+ }
726
+ if (result.unmapped.length > 0) {
727
+ lines.push("", "# UNMAPPED — the importer could not place these bullets, and refuses to", "# guess. They are covered by defaults.autonomy (manual) until a human names", "# their class:");
728
+ for (const bullet of result.unmapped) {
729
+ lines.push(`# (${bullet.section}) ${bullet.text}`);
730
+ }
731
+ }
732
+ const yaml = `${lines.join("\n")}\n`;
733
+ if (!hasValuesDraft(values))
734
+ return yaml;
735
+ return `\`\`\`${POLICY_INFO_STRING}\n${yaml}\`\`\`\n\n${renderFencedValuesDraft(values, source)}`;
736
+ }
737
+ /**
738
+ * The draft wrapped in its ` ```yaml approval-policy ` fence, for stdout, with
739
+ * the values fence printed after it when the source declared values headings.
740
+ */
741
+ export function renderFencedDraft(result, source, values) {
742
+ const policy = `\`\`\`${POLICY_INFO_STRING}\n${renderDraftPolicy(result, source)}\`\`\`\n`;
743
+ if (!hasValuesDraft(values))
744
+ return policy;
745
+ return `${policy}\n${renderFencedValuesDraft(values, source)}`;
746
+ }
747
+ //# sourceMappingURL=agents-md.js.map