approval-md 0.1.0 → 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 (266) hide show
  1. package/README.md +584 -553
  2. package/SPEC.md +42 -13
  3. package/dist/src/adapters/agentmail.d.ts +426 -0
  4. package/dist/src/adapters/agentmail.js +2 -2
  5. package/dist/src/adapters/conformance.d.ts +149 -0
  6. package/dist/src/adapters/contract.d.ts +628 -0
  7. package/dist/src/adapters/contract.js +110 -16
  8. package/dist/src/adapters/contract.js.map +1 -1
  9. package/dist/src/adapters/email.d.ts +324 -0
  10. package/dist/src/adapters/env-passphrase.d.ts +93 -0
  11. package/dist/src/adapters/public.d.ts +11 -0
  12. package/dist/src/adapters/public.js +11 -0
  13. package/dist/src/adapters/public.js.map +1 -0
  14. package/dist/src/adapters/registry.d.ts +59 -0
  15. package/dist/src/adapters/registry.js +2 -1
  16. package/dist/src/adapters/registry.js.map +1 -1
  17. package/dist/src/adapters/smtp.d.ts +213 -0
  18. package/dist/src/adapters/vault-provider.d.ts +114 -0
  19. package/dist/src/adapters/vault-provider.js +3 -3
  20. package/dist/src/adapters/zzz.d.ts +66 -0
  21. package/dist/src/adapters/zzz.js +299 -0
  22. package/dist/src/adapters/zzz.js.map +1 -0
  23. package/dist/src/channels/batch.d.ts +109 -0
  24. package/dist/src/channels/cli.d.ts +193 -0
  25. package/dist/src/channels/conformance.d.ts +92 -0
  26. package/dist/src/channels/contract.d.ts +623 -0
  27. package/dist/src/channels/payload-view.d.ts +35 -0
  28. package/dist/src/channels/render-queue.d.ts +149 -0
  29. package/dist/src/channels/tagging.d.ts +196 -0
  30. package/dist/src/channels/telegram.d.ts +1832 -0
  31. package/dist/src/channels/web.d.ts +341 -0
  32. package/dist/src/cli/adapter.d.ts +90 -0
  33. package/dist/src/cli/adapter.js +25 -15
  34. package/dist/src/cli/adapter.js.map +1 -1
  35. package/dist/src/cli/amend.d.ts +59 -0
  36. package/dist/src/cli/args.d.ts +43 -0
  37. package/dist/src/cli/attest.d.ts +41 -0
  38. package/dist/src/cli/audit-card.d.ts +62 -0
  39. package/dist/src/cli/audit.d.ts +59 -0
  40. package/dist/src/cli/channel-telegram.d.ts +806 -0
  41. package/dist/src/cli/channel-web.d.ts +131 -0
  42. package/dist/src/cli/channel.d.ts +71 -0
  43. package/dist/src/cli/checkpoint-tap.d.ts +169 -0
  44. package/dist/src/cli/codex.d.ts +2 -0
  45. package/dist/src/cli/codex.js +172 -0
  46. package/dist/src/cli/codex.js.map +1 -0
  47. package/dist/src/cli/coverage.d.ts +61 -0
  48. package/dist/src/cli/daemon.d.ts +120 -0
  49. package/dist/src/cli/doctor.d.ts +129 -0
  50. package/dist/src/cli/doctor.js +119 -5
  51. package/dist/src/cli/doctor.js.map +1 -1
  52. package/dist/src/cli/env.d.ts +65 -0
  53. package/dist/src/cli/execute.d.ts +202 -0
  54. package/dist/src/cli/exit-codes.d.ts +73 -0
  55. package/dist/src/cli/feedback.d.ts +60 -0
  56. package/dist/src/cli/gate-window.d.ts +40 -0
  57. package/dist/src/cli/gate.d.ts +68 -0
  58. package/dist/src/cli/git-scope.d.ts +190 -0
  59. package/dist/src/cli/gloss-attach.d.ts +85 -0
  60. package/dist/src/cli/gloss-codex-child.d.ts +9 -0
  61. package/dist/src/cli/gloss-codex.d.ts +24 -0
  62. package/dist/src/cli/gloss-options.d.ts +42 -0
  63. package/dist/src/cli/gloss.d.ts +265 -0
  64. package/dist/src/cli/help.d.ts +103 -0
  65. package/dist/src/cli/help.js +173 -51
  66. package/dist/src/cli/help.js.map +1 -1
  67. package/dist/src/cli/hook-codex.d.ts +78 -0
  68. package/dist/src/cli/hook-codex.js +167 -0
  69. package/dist/src/cli/hook-codex.js.map +1 -0
  70. package/dist/src/cli/hook.d.ts +331 -0
  71. package/dist/src/cli/hook.js +186 -80
  72. package/dist/src/cli/hook.js.map +1 -1
  73. package/dist/src/cli/import.d.ts +35 -0
  74. package/dist/src/cli/init.d.ts +84 -0
  75. package/dist/src/cli/init.js +2 -2
  76. package/dist/src/cli/init.js.map +1 -1
  77. package/dist/src/cli/instructions.d.ts +23 -0
  78. package/dist/src/cli/journal.d.ts +41 -0
  79. package/dist/src/cli/log-advance.d.ts +287 -0
  80. package/dist/src/cli/log-advance.js +102 -11
  81. package/dist/src/cli/log-advance.js.map +1 -1
  82. package/dist/src/cli/log-anchor.d.ts +176 -0
  83. package/dist/src/cli/log-checkpoint.d.ts +22 -0
  84. package/dist/src/cli/log-sync.d.ts +243 -0
  85. package/dist/src/cli/log-verbs.d.ts +16 -0
  86. package/dist/src/cli/log-verbs.js +7 -1
  87. package/dist/src/cli/log-verbs.js.map +1 -1
  88. package/dist/src/cli/long-help.d.ts +70 -0
  89. package/dist/src/cli/main.d.ts +77 -0
  90. package/dist/src/cli/main.js +155 -5
  91. package/dist/src/cli/main.js.map +1 -1
  92. package/dist/src/cli/mcp.d.ts +52 -0
  93. package/dist/src/cli/paths.d.ts +56 -0
  94. package/dist/src/cli/payload.d.ts +58 -0
  95. package/dist/src/cli/policy.d.ts +43 -0
  96. package/dist/src/cli/preflight.d.ts +363 -0
  97. package/dist/src/cli/preflight.js +294 -7
  98. package/dist/src/cli/preflight.js.map +1 -1
  99. package/dist/src/cli/progress.d.ts +78 -0
  100. package/dist/src/cli/prompt.d.ts +209 -0
  101. package/dist/src/cli/quickstart.d.ts +46 -0
  102. package/dist/src/cli/quickstart.js +297 -0
  103. package/dist/src/cli/quickstart.js.map +1 -0
  104. package/dist/src/cli/records.d.ts +34 -0
  105. package/dist/src/cli/render.d.ts +22 -0
  106. package/dist/src/cli/sandbox.d.ts +51 -0
  107. package/dist/src/cli/scaffold.d.ts +79 -0
  108. package/dist/src/cli/setup-adapter.d.ts +137 -0
  109. package/dist/src/cli/setup-adapter.js +38 -4
  110. package/dist/src/cli/setup-adapter.js.map +1 -1
  111. package/dist/src/cli/setup-channel.d.ts +117 -0
  112. package/dist/src/cli/setup-checkpoint.d.ts +57 -0
  113. package/dist/src/cli/setup-common.d.ts +275 -0
  114. package/dist/src/cli/setup-flow.d.ts +287 -0
  115. package/dist/src/cli/setup-service.d.ts +96 -0
  116. package/dist/src/cli/setup.d.ts +202 -0
  117. package/dist/src/cli/style.d.ts +320 -0
  118. package/dist/src/cli/token.d.ts +39 -0
  119. package/dist/src/cli/up.d.ts +155 -0
  120. package/dist/src/cli/up.js +4 -2
  121. package/dist/src/cli/up.js.map +1 -1
  122. package/dist/src/cli/usage.d.ts +37 -0
  123. package/dist/src/cli/values.d.ts +40 -0
  124. package/dist/src/cli/vault.d.ts +59 -0
  125. package/dist/src/cli/vault.js +2 -2
  126. package/dist/src/cli/vault.js.map +1 -1
  127. package/dist/src/cli/verb-registry.d.ts +76 -0
  128. package/dist/src/cli/verb-registry.js +176 -8
  129. package/dist/src/cli/verb-registry.js.map +1 -1
  130. package/dist/src/cli/wordmark.d.ts +31 -0
  131. package/dist/src/cli/wordmark.js +2 -2
  132. package/dist/src/codex/doctor.d.ts +13 -0
  133. package/dist/src/codex/doctor.js +41 -0
  134. package/dist/src/codex/doctor.js.map +1 -0
  135. package/dist/src/codex/manifest.d.ts +49 -0
  136. package/dist/src/codex/manifest.js +103 -0
  137. package/dist/src/codex/manifest.js.map +1 -0
  138. package/dist/src/codex/templates.d.ts +41 -0
  139. package/dist/src/codex/templates.js +319 -0
  140. package/dist/src/codex/templates.js.map +1 -0
  141. package/dist/src/codex/trust.d.ts +19 -0
  142. package/dist/src/codex/trust.js +183 -0
  143. package/dist/src/codex/trust.js.map +1 -0
  144. package/dist/src/codex/workspace-plan.d.ts +131 -0
  145. package/dist/src/codex/workspace-plan.js +561 -0
  146. package/dist/src/codex/workspace-plan.js.map +1 -0
  147. package/dist/src/core/actor.d.ts +2 -0
  148. package/dist/src/core/actor.js +5 -0
  149. package/dist/src/core/actor.js.map +1 -0
  150. package/dist/src/core/advance-cycle.d.ts +170 -0
  151. package/dist/src/core/agents-md.d.ts +276 -0
  152. package/dist/src/core/apply-patch.d.ts +49 -0
  153. package/dist/src/core/apply-patch.js +266 -0
  154. package/dist/src/core/apply-patch.js.map +1 -0
  155. package/dist/src/core/attest.d.ts +420 -0
  156. package/dist/src/core/attest.js +13 -1
  157. package/dist/src/core/attest.js.map +1 -1
  158. package/dist/src/core/audit.d.ts +492 -0
  159. package/dist/src/core/budgets.d.ts +238 -0
  160. package/dist/src/core/checkpoint.d.ts +500 -0
  161. package/dist/src/core/child-env.d.ts +88 -0
  162. package/dist/src/core/clock.d.ts +52 -0
  163. package/dist/src/core/command-class.d.ts +543 -0
  164. package/dist/src/core/command-class.js +43 -8
  165. package/dist/src/core/command-class.js.map +1 -1
  166. package/dist/src/core/coverage-sources/adapter.d.ts +40 -0
  167. package/dist/src/core/coverage-sources/gh.d.ts +48 -0
  168. package/dist/src/core/coverage-sources/git.d.ts +101 -0
  169. package/dist/src/core/coverage.d.ts +217 -0
  170. package/dist/src/core/credential-spec.d.ts +72 -0
  171. package/dist/src/core/dark-session.d.ts +331 -0
  172. package/dist/src/core/decision-refusal.d.ts +185 -0
  173. package/dist/src/core/env-file.d.ts +450 -0
  174. package/dist/src/core/execute.d.ts +858 -0
  175. package/dist/src/core/execute.js +44 -6
  176. package/dist/src/core/execute.js.map +1 -1
  177. package/dist/src/core/frontmatter.d.ts +78 -0
  178. package/dist/src/core/gate-window.d.ts +312 -0
  179. package/dist/src/core/gate.d.ts +1364 -0
  180. package/dist/src/core/gate.js +68 -13
  181. package/dist/src/core/gate.js.map +1 -1
  182. package/dist/src/core/git-run.d.ts +73 -0
  183. package/dist/src/core/harness-version.d.ts +157 -0
  184. package/dist/src/core/harness-version.js +2 -1
  185. package/dist/src/core/harness-version.js.map +1 -1
  186. package/dist/src/core/harness-wait.d.ts +55 -0
  187. package/dist/src/core/head-retry.d.ts +107 -0
  188. package/dist/src/core/instance.d.ts +253 -0
  189. package/dist/src/core/intake-limits.d.ts +247 -0
  190. package/dist/src/core/jcs.d.ts +52 -0
  191. package/dist/src/core/journal.d.ts +144 -0
  192. package/dist/src/core/live-draw.d.ts +436 -0
  193. package/dist/src/core/log-reconcile.d.ts +89 -0
  194. package/dist/src/core/log-subscribe.d.ts +36 -0
  195. package/dist/src/core/log-subscribe.js +162 -0
  196. package/dist/src/core/log-subscribe.js.map +1 -0
  197. package/dist/src/core/log.d.ts +278 -0
  198. package/dist/src/core/loop.d.ts +274 -0
  199. package/dist/src/core/loop.js +11 -0
  200. package/dist/src/core/loop.js.map +1 -1
  201. package/dist/src/core/md-fence.d.ts +41 -0
  202. package/dist/src/core/money.d.ts +147 -0
  203. package/dist/src/core/payload-census.d.ts +74 -0
  204. package/dist/src/core/payload-store.d.ts +175 -0
  205. package/dist/src/core/payload.d.ts +71 -0
  206. package/dist/src/core/policy-diff.d.ts +292 -0
  207. package/dist/src/core/policy-diff.js +27 -4
  208. package/dist/src/core/policy-diff.js.map +1 -1
  209. package/dist/src/core/policy-expectations.d.ts +199 -0
  210. package/dist/src/core/policy-explain.d.ts +150 -0
  211. package/dist/src/core/policy-explain.js +31 -3
  212. package/dist/src/core/policy-explain.js.map +1 -1
  213. package/dist/src/core/policy-load.d.ts +527 -0
  214. package/dist/src/core/policy-load.js +15 -3
  215. package/dist/src/core/policy-load.js.map +1 -1
  216. package/dist/src/core/policy-match.d.ts +281 -0
  217. package/dist/src/core/policy-match.js +20 -9
  218. package/dist/src/core/policy-match.js.map +1 -1
  219. package/dist/src/core/policy-proposal.d.ts +265 -0
  220. package/dist/src/core/prompt-layout.d.ts +221 -0
  221. package/dist/src/core/protected-path-guard.d.ts +453 -0
  222. package/dist/src/core/protected-path-guard.js +514 -35
  223. package/dist/src/core/protected-path-guard.js.map +1 -1
  224. package/dist/src/core/registration.d.ts +25 -0
  225. package/dist/src/core/reindex.d.ts +99 -0
  226. package/dist/src/core/sampler.d.ts +313 -0
  227. package/dist/src/core/sandbox.d.ts +290 -0
  228. package/dist/src/core/seal.d.ts +165 -0
  229. package/dist/src/core/state.d.ts +505 -0
  230. package/dist/src/core/task-file.d.ts +185 -0
  231. package/dist/src/core/telegram-config.d.ts +93 -0
  232. package/dist/src/core/token.d.ts +409 -0
  233. package/dist/src/core/token.js +21 -38
  234. package/dist/src/core/token.js.map +1 -1
  235. package/dist/src/core/validate.d.ts +138 -0
  236. package/dist/src/core/values.d.ts +137 -0
  237. package/dist/src/core/vault.d.ts +291 -0
  238. package/dist/src/core/verified-snapshot.d.ts +204 -0
  239. package/dist/src/core/verify.d.ts +336 -0
  240. package/dist/src/core/version.d.ts +8 -0
  241. package/dist/src/core/wysiwys.d.ts +370 -0
  242. package/dist/src/daemon/advance-child.d.ts +39 -0
  243. package/dist/src/daemon/advance.d.ts +466 -0
  244. package/dist/src/daemon/audit.d.ts +87 -0
  245. package/dist/src/daemon/daemon.d.ts +1180 -0
  246. package/dist/src/daemon/dark-session.d.ts +64 -0
  247. package/dist/src/daemon/draw-child.d.ts +36 -0
  248. package/dist/src/daemon/draw.d.ts +154 -0
  249. package/dist/src/daemon/git-evidence.d.ts +173 -0
  250. package/dist/src/daemon/git-evidence.js +1 -1
  251. package/dist/src/daemon/projection.d.ts +180 -0
  252. package/dist/src/daemon/prune.d.ts +207 -0
  253. package/dist/src/mcp/http.d.ts +113 -0
  254. package/dist/src/mcp/server.d.ts +265 -0
  255. package/dist/src/mcp/server.js +9 -1
  256. package/dist/src/mcp/server.js.map +1 -1
  257. package/docs/adapter-api.md +106 -0
  258. package/docs/cli-reference.md +389 -36
  259. package/docs/codex-enforced-session.md +30 -0
  260. package/package.json +12 -2
  261. package/schema/codex-instance.schema.json +82 -0
  262. package/schema/event.schema.json +2 -1
  263. package/schema/fixtures/codex-instance/invalid/unpinned-codex-version.json +40 -0
  264. package/schema/fixtures/codex-instance/valid/canonical.json +40 -0
  265. package/schema/policy.schema.json +21 -1
  266. package/templates/codex/README.md +9 -0
@@ -0,0 +1,274 @@
1
+ /**
2
+ * Loop safety (SPEC.md §10.2): "three consecutive `execution.failed` events for
3
+ * one task escalate to `manual` regardless of policy".
4
+ *
5
+ * This is a **pure projection over the log** and nothing else. It reads records,
6
+ * counts, and returns; it never appends, never reads the clock, and never
7
+ * consults the policy. Two very different consumers need the same answer and
8
+ * must not be allowed to disagree about it:
9
+ *
10
+ * - `core/gate.ts` refuses to admit a *new* non-manual request for an escalated
11
+ * task (the `loop-escalated` refusal);
12
+ * - `core/execute.ts` refuses to *start* a supervised/autonomous execution for
13
+ * one, directing the caller to the manual path.
14
+ *
15
+ * It lives in its own module rather than inside `core/execute.ts` for a boring
16
+ * structural reason: `execute.ts` imports the gate, so the gate cannot import
17
+ * `execute.ts` back without a cycle. `core/execute.ts` re-exports these names, so
18
+ * the documented home of the projection is still the execution module.
19
+ *
20
+ * ## What "consecutive" means here, stated exactly
21
+ *
22
+ * The streak is **per task**, not per action key — SPEC.md §10.2 says "for one
23
+ * task", and an agent that fails three different actions of the same task in a
24
+ * row is exactly the runaway loop the rule exists to stop.
25
+ *
26
+ * Only two event types move the counter:
27
+ *
28
+ * - `execution.failed` increments it;
29
+ * - `execution.completed` resets it to zero.
30
+ *
31
+ * Everything else — `execution.started`, approvals, budget events, another
32
+ * task's failures — is transparent. In particular a *retry* is not a reset: a
33
+ * failed action that is started again and fails again is two consecutive
34
+ * failures, which is the entire point. Only a successful completion is evidence
35
+ * that the loop broke, so only a completion clears the count.
36
+ *
37
+ * ## Escalation is a floor, never a ban
38
+ *
39
+ * An escalated task is escalated **to manual**, not to refused. Its manual
40
+ * actions still request, still grant, and still execute with a token — a human
41
+ * is now in the loop for every one of them, which is what "escalate to manual"
42
+ * means. Escalation is also **not** cleared by a human decision, only by an
43
+ * `execution.completed`: the log records the recovery, or the escalation stands.
44
+ *
45
+ * ## The harness scopes (APRV-145)
46
+ *
47
+ * Everything above is the per-task streak of SPEC.md §10.2 and is unchanged. A
48
+ * harness adapter (§10.1) mints a fresh task id for every tool call, so that
49
+ * streak cannot leave zero on that surface however wedged the session is. The
50
+ * amended §10.2 answers it with two more streaks, both derived here and both
51
+ * counted in TOOL CALLS rather than in events:
52
+ *
53
+ * - the **session**, `hook:<session id>`, which is a real prefix of every task
54
+ * id the adapter mints, so the scope is recovered from a string the runtime
55
+ * itself wrote rather than from a field an agent hands the gate;
56
+ * - the **actor**, the identity the adapter runs as, because a session id is
57
+ * authored by the party under oversight and a scope key the subject can
58
+ * rotate is a streak the subject can clear (§11.1 invariant 4).
59
+ *
60
+ * A command is escalated when EITHER reaches {@link LOOP_ESCALATION_THRESHOLD}.
61
+ *
62
+ * ## Only side effects accrue (APRV-280, amended SPEC.md §10.2)
63
+ *
64
+ * The streak counts failed executions of classes that DO something. A
65
+ * `read.*` command that exits non-zero has not failed a side effect: a `grep`
66
+ * that matches nothing and an `ls` of a path that is not there both exit 1, and
67
+ * that exit IS the command's answer. Counting those escalated whole sessions to
68
+ * manual over nothing, which is the incident APRV-280 was filed on: forty-eight
69
+ * requests queued in an hour behind three failed greps.
70
+ *
71
+ * The predicate is {@link isSideEffectingClass} and it is stated once. What it
72
+ * does NOT do is let a read clear anything: a tool call whose classes are all
73
+ * reads is transparent to the streak in both directions, so a failing write
74
+ * streak is not cleared by a successful `ls` in between. The strict direction is
75
+ * kept everywhere else too — a class this projection cannot resolve from the log
76
+ * counts as side-effecting, because "we could not establish what this was" is
77
+ * not "this was harmless".
78
+ *
79
+ * The class is read from the `execution.started` record the RUNTIME wrote for
80
+ * the action key (its `payload.class`), never from anything the reporter said
81
+ * (§11.1 invariants 1 and 4). The report chooses the outcome; it does not get to
82
+ * choose the bucket.
83
+ *
84
+ * ## Escalation raises scrutiny on side effects only (APRV-297, amended §10.2)
85
+ *
86
+ * APRV-280 above says what a read does not ACCRUE. This says what a tripped
87
+ * floor does not ROUTE, and it is the same sentence read forward: a tool call
88
+ * whose classes are all `read.*` is answered by the policy under a tripped floor
89
+ * exactly as it is under a clear one.
90
+ *
91
+ * The floor bounds a harm a read cannot cause. It exists to stop an agent
92
+ * retrying a side effect that keeps failing, so routing a `grep` to a phone buys
93
+ * no safety at all, and it costs the thing the floor is spending: a human's
94
+ * attention, once per read, plus the wait the agent spends before it is refused.
95
+ * On 2026-09-06/07 a floor tripped and a session that could not get an answer
96
+ * could not read a file either, which is the state this removes.
97
+ *
98
+ * Two edges, both narrow. A MIXED tool call is routed whole, as one question,
99
+ * because the side-effecting half of it is exactly what the floor is for; its
100
+ * read classes are neither counted nor separately raised, so the approver sees
101
+ * one prompt for the command's effects and none for its looking. And the
102
+ * exemption is about ROUTING alone: a read still clears nothing, so a session
103
+ * cannot read its way out from under a floor.
104
+ *
105
+ * This module states the fact; the two surfaces that apply it are the harness
106
+ * adapter's verdict (`cli/hook.ts`) and the write boundary that re-checks it
107
+ * (`core/gate.ts`'s `startHarnessExecution`), and both use
108
+ * {@link isSideEffectingClass} so neither can drift from the other.
109
+ */
110
+ import type { EventRecord } from "./log.js";
111
+ /**
112
+ * Consecutive failures that force a task to manual (SPEC.md §10.2). Three, and
113
+ * the number is spelled here once so the gate, the executor, and the CLI cannot
114
+ * hold three opinions about it.
115
+ */
116
+ export declare const LOOP_ESCALATION_THRESHOLD = 3;
117
+ /**
118
+ * Does an action in this class have a side effect the loop rule is about?
119
+ * (APRV-280, amended SPEC.md §10.2.)
120
+ *
121
+ * THE PREDICATE, exactly: a class is side-effecting unless it is `read` itself
122
+ * or sits under the `read.` namespace. Everything else — `files.write.*`,
123
+ * `files.delete.*`, `vcs.*`, `deps.*`, `network.*`, `communicate.*`,
124
+ * `policy.*`, `log.*`, a routed `policy.edit.*`, and any class this build has
125
+ * never heard of — is side-effecting. The unknown falls on the strict side by
126
+ * construction, which is the whole reason the predicate is written as a
127
+ * carve-OUT of `read.*` rather than as a list of the namespaces that act.
128
+ *
129
+ * `core/command-class.ts` already reads `read.*` this way when it decides which
130
+ * command substitutions may run unattended, and this is deliberately the same
131
+ * sentence: one reading of "this command only looks at things", used by the
132
+ * classifier and by loop safety alike.
133
+ */
134
+ export declare function isSideEffectingClass(cls: string): boolean;
135
+ /** One task's loop state, derived from the log. */
136
+ export interface TaskLoopState {
137
+ task: string;
138
+ /** Failures since the last `execution.completed` for this task. */
139
+ consecutiveFailures: number;
140
+ /** `consecutiveFailures >= LOOP_ESCALATION_THRESHOLD`. */
141
+ escalated: boolean;
142
+ /** The seq of the failure that opened the current streak, or `null`. */
143
+ streakStartSeq: number | null;
144
+ /** The seq of the most recent failure in the streak, or `null`. */
145
+ lastFailureSeq: number | null;
146
+ }
147
+ /**
148
+ * Loop state for every task that has recorded an execution outcome.
149
+ *
150
+ * Returned sorted by task id so the projection is byte-stable: two runs over
151
+ * the same log produce the same list in the same order, which is what lets
152
+ * `approval status --json` be pinned by a `deepEqual` test.
153
+ *
154
+ * Tasks with side-effecting executions but no failures are included with
155
+ * `consecutiveFailures: 0` — a caller rendering health wants to know the task
156
+ * was seen and is clean, and filtering is the caller's business, not this
157
+ * function's.
158
+ *
159
+ * APRV-280: outcomes of `read.*` actions are skipped entirely, so a task whose
160
+ * every execution was a read appears here not at all. That is the transparency
161
+ * the amended §10.2 asks for, read in both directions: a failed read accrues
162
+ * nothing, and a completed read clears nothing either.
163
+ */
164
+ export declare function loopEscalation(records: EventRecord[]): TaskLoopState[];
165
+ /** Is `task` escalated to manual by loop safety right now? */
166
+ export declare function isLoopEscalated(records: EventRecord[], task: string): boolean;
167
+ /** The prefix every harness adapter task id carries (`src/cli/hook.ts`). */
168
+ export declare const HARNESS_TASK_PREFIX = "hook:";
169
+ /**
170
+ * The bucket every unreadable session identifier lands in.
171
+ *
172
+ * ONE shared bucket, not a fresh one per unreadable id, and the difference is
173
+ * the whole rule: absence must accrue FASTER and never slower. `parseHookInput`
174
+ * already substitutes this literal for an absent `session_id`, so the two halves
175
+ * of the runtime spell it the same way.
176
+ */
177
+ export declare const UNKNOWN_SESSION = "unknown-session";
178
+ /**
179
+ * The session scope key of a harness task id, or `null` for a task no harness
180
+ * adapter minted.
181
+ *
182
+ * DERIVED, never declared. The id is `hook:<session>:<tool-use id>` and this
183
+ * reads its middle segment back out; nothing here reads a scope an agent named.
184
+ * A `hook:` task that does not split into exactly three colon-separated parts is
185
+ * an id this runtime cannot read, so it lands in {@link UNKNOWN_SESSION} with
186
+ * every other unreadable one.
187
+ */
188
+ export declare function harnessSessionOf(task: string): string | null;
189
+ /** Which derivation produced a {@link HarnessLoopState}'s key. */
190
+ export type HarnessScope = "session" | "actor";
191
+ /** One harness scope's loop state, derived from the log. */
192
+ export interface HarnessLoopState {
193
+ scope: HarnessScope;
194
+ /** `hook:<session id>` for a session, the actor identity for an actor. */
195
+ key: string;
196
+ /** Consecutive failed TOOL CALLS since the last completed one. */
197
+ consecutiveFailures: number;
198
+ /** `consecutiveFailures >= LOOP_ESCALATION_THRESHOLD`. */
199
+ escalated: boolean;
200
+ /** The seq that opened the current streak, or `null`. */
201
+ streakStartSeq: number | null;
202
+ /** The seq of the most recent failure in the streak, or `null`. */
203
+ lastFailureSeq: number | null;
204
+ }
205
+ /**
206
+ * Loop state for every harness session and every harness actor the log has seen
207
+ * an outcome for.
208
+ *
209
+ * Sorted by scope then key so the projection is byte-stable, exactly as
210
+ * {@link loopEscalation} is, which is what lets `approval status --json` be
211
+ * pinned by a `deepEqual` test.
212
+ *
213
+ * What resets a streak is unchanged and deliberately not widened: only an
214
+ * `execution.completed` in the same scope, of a SIDE-EFFECTING class since
215
+ * APRV-280. A hook timeout, a deny, a withdrawn request, a granted approval, a
216
+ * fresh tool call, a successful `grep`, a restarted process and elapsed time all
217
+ * leave the streak where they found it. Silence is not evidence of recovery, and
218
+ * neither is a command that did nothing.
219
+ */
220
+ export declare function harnessLoopEscalation(records: EventRecord[]): HarnessLoopState[];
221
+ /**
222
+ * The harness scope that escalated this tool call, or `null` for a command no
223
+ * streak has floored.
224
+ *
225
+ * EITHER scope escalates (amended SPEC.md §10.2). The session is the smallest
226
+ * scope a runaway actually runs away in; the actor is the backstop, because the
227
+ * session id is authored by the party under oversight and a scope it can rotate
228
+ * is a streak it can shed. The session is reported in preference to the actor
229
+ * where both are tripped, because it is the narrower fact and names the run an
230
+ * operator has to go and look at.
231
+ */
232
+ export declare function harnessLoopFloor(records: EventRecord[], task: string, actor: string): HarnessLoopState | null;
233
+ /**
234
+ * What clears this streak, in one sentence, for the surface that has to say so
235
+ * (APRV-280).
236
+ *
237
+ * Written here rather than at each call site because three surfaces print it —
238
+ * the gate's `loop-escalated` refusals, the hook's denies, and `approval
239
+ * status` — and three copies of a sentence about how to get out of a floor are
240
+ * three chances to tell an operator something that is not true. Everything in
241
+ * it is a fact of this module: a completion of a SIDE-EFFECTING class in the
242
+ * same scope, and nothing else, resets the counter.
243
+ *
244
+ * The gate window is named for the harness scopes only, because that is the
245
+ * surface it reaches: an open window routes every gated tool call through the
246
+ * bypass path before the floor is ever consulted (SPEC.md §5.2, APRV-214). It is
247
+ * named as the human's ceremony, which is what it is — it needs a terminal and a
248
+ * typed `understood`, and an agent may not run it.
249
+ *
250
+ * The harness sentence also states the routing exemption of APRV-297, and states
251
+ * it here for the same reason the clearance is here: the operator reading it in
252
+ * `approval status` and the agent reading it in a deny need the same account of
253
+ * what a floor does and does not reach, and two copies would eventually give two.
254
+ */
255
+ export declare function loopClearance(scope: "task" | HarnessScope, key: string): string;
256
+ /** Is this harness tool call floored to manual by either scope right now? */
257
+ export declare function isHarnessLoopEscalated(records: EventRecord[], task: string, actor: string): boolean;
258
+ /** How many harness starts carry an outcome, and how many do not (§10.2). */
259
+ export interface HarnessOutcomeCoverage {
260
+ started: number;
261
+ reported: number;
262
+ unreported: number;
263
+ }
264
+ /**
265
+ * Coverage of the completion counterpart, for `approval status`.
266
+ *
267
+ * INFORMATIONAL. It moves no health verdict and no exit code, for the reason
268
+ * §8's timestamp anomalies move neither: it is a coverage measurement rather
269
+ * than an integrity verdict, and a control an operator learns to silence is
270
+ * worse than one that reports beside the verdict. A persistently high
271
+ * `unreported` is how an operator learns the post-execution hook is not
272
+ * installed or not firing.
273
+ */
274
+ export declare function harnessOutcomeCoverage(records: EventRecord[]): HarnessOutcomeCoverage;
@@ -269,6 +269,17 @@ export function harnessSessionOf(task) {
269
269
  if (!task.startsWith(HARNESS_TASK_PREFIX))
270
270
  return null;
271
271
  const parts = task.split(":");
272
+ // APRV-311: Codex native ids may themselves contain colons, so the adapter
273
+ // writes fixed-width digests as `hook:codex:<session-digest>:<call-digest>`.
274
+ // Preserve the session digest as the loop bucket. This arm is deliberately
275
+ // exact; malformed Codex-shaped tasks fall through to the legacy unknown
276
+ // bucket rather than selecting a scope from attacker-authored fragments.
277
+ if (parts.length === 4 &&
278
+ parts[1] === "codex" &&
279
+ /^[a-f0-9]{64}$/u.test(parts[2] ?? "") &&
280
+ /^[a-f0-9]{64}$/u.test(parts[3] ?? "")) {
281
+ return `${HARNESS_TASK_PREFIX}codex:${parts[2]}`;
282
+ }
272
283
  if (parts.length !== 3)
273
284
  return `${HARNESS_TASK_PREFIX}${UNKNOWN_SESSION}`;
274
285
  const session = parts[1];
@@ -1 +1 @@
1
- {"version":3,"file":"loop.js","sourceRoot":"","sources":["../../../src/core/loop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loop.js","sourceRoot":"","sources":["../../../src/core/loop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * CommonMark fenced-block scanning, as a leaf module.
3
+ *
4
+ * `APPROVAL.md` is prose for humans plus fenced blocks for machines: exactly
5
+ * one ` ```yaml approval-policy ` block (SPEC.md §5) and at most one optional
6
+ * ` ```yaml approval-values ` block (SPEC.md §5.3). Two readers, two info
7
+ * strings, one question: which fenced blocks in this markdown carry that label,
8
+ * and was one of them left open at end of file.
9
+ *
10
+ * This module answers that question and nothing else. It was lifted out of
11
+ * `policy-load.ts` unchanged (APRV-238) so the values reader could ask it too
12
+ * without importing the policy loader, which is the module a values reader must
13
+ * stay clear of (SPEC.md §11.1 invariant 10, `tests/values-inert.test.ts`). The
14
+ * splitter is the one place allowed to know both info strings, because knowing
15
+ * a label is not reading a block: what it returns is text, and what a caller
16
+ * does with the text is the caller's whole subject.
17
+ *
18
+ * Pure function of the markdown and the info string. No filesystem, no clock,
19
+ * no schema, no YAML.
20
+ */
21
+ /** The blocks a scan found, and whether one was left open at end of file. */
22
+ export interface FenceScan {
23
+ /** Bodies of every block whose info string matched, in document order. */
24
+ blocks: string[];
25
+ /** True when a MATCHING fence was opened and never closed before EOF. */
26
+ unterminated: boolean;
27
+ }
28
+ /**
29
+ * Scan CommonMark fenced code blocks and collect the bodies of those whose info
30
+ * string is `infoString` (compared after {@link normaliseInfoString}).
31
+ *
32
+ * CommonMark rules honoured, because they decide what is and is not a fence:
33
+ * an opening fence is 3+ backticks indented at most 3 spaces; its info string
34
+ * may not contain a backtick; the closing fence is at least as long as the
35
+ * opener and carries nothing but whitespace. Every non-matching fenced block
36
+ * (```js, ```yaml, …) is still scanned as a block, so text *inside* it can
37
+ * never be mistaken for a matching fence. Everything outside a fence — including
38
+ * yaml-looking prose and 4-space-indented code blocks, which are not fences —
39
+ * is ignored entirely.
40
+ */
41
+ export declare function scanFences(markdown: string, infoString: string): FenceScan;
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Monetary amounts in hashed material (APRV-121).
3
+ *
4
+ * ## The representation, and why
5
+ *
6
+ * Every USD amount that enters hashed material — an envelope's
7
+ * `actions[].est_cost_usd` and `budget.max_cost_usd`, the `est_cost_usd` the
8
+ * gate records on `approval.requested`, `approval.granted`, `execution.started`
9
+ * and `budget.exceeded`, and the `est_cost_usd` an execution token binds to —
10
+ * is a **decimal string**: `"0"`, `"0.02"`, `"1200.5"`. Not a JSON number.
11
+ *
12
+ * RFC 8785 pins ES6 number serialization, so a single TypeScript runtime is
13
+ * internally consistent with itself. Cross-language it is not: the fast-path of
14
+ * SPEC.md §13 and any second implementation must reproduce the same bytes from
15
+ * the same value, and float formatting is precisely where that breaks. A
16
+ * decimal string has one spelling, and every language agrees on it because
17
+ * nobody has to reserialize anything.
18
+ *
19
+ * **String decimal, not integer minor units.** Both remove the float; the
20
+ * choice is about what a human writes and reads. The field is named
21
+ * `est_cost_usd` and a task author writes it in YAML frontmatter next to a
22
+ * one-line summary; `est_cost_usd: "0.02"` still says two cents, while
23
+ * `est_cost_usd: 20000` says nothing without knowing the exponent this project
24
+ * picked, and picking one commits the format to a currency decision (USD has
25
+ * two decimal places, other currencies do not) that the field name does not
26
+ * make. The string also round-trips into and out of a channel message, a CLI
27
+ * table, and a policy discussion without a conversion anyone can get wrong.
28
+ *
29
+ * ## The canonical form
30
+ *
31
+ * {@link USD_STRING_PATTERN}: an optional integer part with no leading zeros,
32
+ * an optional fraction of one to six digits, no sign, no exponent, no trailing
33
+ * dot, no trailing zeros beyond the last significant digit. One value, one
34
+ * spelling — `"0.10"` and `"0.1"` cannot both be written, so two records
35
+ * carrying the same amount always hash the same way.
36
+ *
37
+ * Six fractional digits is the resolution, matching the micro-USD unit the
38
+ * arithmetic below runs in. It is far finer than any real amount and far
39
+ * coarser than IEEE-754 drift.
40
+ *
41
+ * ## The arithmetic
42
+ *
43
+ * All budget arithmetic runs in **integer micro-USD**. A decimal string parses
44
+ * to micros by integer string manipulation, never through a double, so no
45
+ * rounding happens on the way in and none is possible on the way back out.
46
+ * Sums, comparisons, and remainders are exact integers: `"0.1" + "0.2"` is
47
+ * `"0.3"`, and a window of ten thousand two-cent actions is exactly `"200"`
48
+ * rather than a value that depends on the order they were added in.
49
+ *
50
+ * ## Historical compatibility (SPEC.md §8, additive-change precedent)
51
+ *
52
+ * The log is append-only, so records written before this change carry JSON
53
+ * numbers and must keep validating, verifying, and feeding budget math exactly
54
+ * as before. Every reader here therefore accepts both forms: a decimal string
55
+ * (the only form the write boundary now admits) and a finite non-negative JSON
56
+ * number (the historical form). A historical number converts to micros by
57
+ * `Math.round(value * 1e6)`, which is deterministic for every amount the old
58
+ * write boundary could have admitted. The write boundary is the only place the
59
+ * two forms are told apart: `schema/*.schema.json` types the fields as decimal
60
+ * strings, and `validate(..., { mode: "historical" })` is the one documented
61
+ * relaxation, used by the verifier and nothing else.
62
+ */
63
+ /** Micro-USD per USD: the resolution of every amount in this module. */
64
+ export declare const USD_MICROS_SCALE = 1000000;
65
+ /** Fractional digits the canonical form admits (the micro-USD resolution). */
66
+ export declare const USD_FRACTION_DIGITS = 6;
67
+ /**
68
+ * The canonical decimal-string form, as a JSON Schema `pattern` source.
69
+ *
70
+ * Exported so the schemas and the runtime cannot drift: `tests/money.test.ts`
71
+ * asserts the schema files carry exactly this string.
72
+ */
73
+ export declare const USD_STRING_PATTERN = "^(0|[1-9][0-9]*)(\\.[0-9]{0,5}[1-9])?$";
74
+ /** Is `value` a canonical decimal USD string? */
75
+ export declare function isUsdString(value: unknown): value is string;
76
+ /**
77
+ * A canonical decimal string as integer micro-USD, or `null` when the string is
78
+ * not canonical.
79
+ *
80
+ * Parsed by integer arithmetic on the digits: the fraction is padded to six
81
+ * places and the two halves are combined, so the double never sees the value.
82
+ */
83
+ export declare function usdStringToMicros(value: string): number | null;
84
+ /**
85
+ * A historical JSON number as integer micro-USD, or `null` when it is not a
86
+ * usable amount (non-finite, negative, or beyond the safe-integer range once
87
+ * scaled).
88
+ *
89
+ * `Math.round` is the documented conversion. It is deterministic, and for every
90
+ * value the pre-APRV-121 write boundary admitted (`minimum: 0`, ES6-serialized)
91
+ * it lands on the micro the author wrote.
92
+ */
93
+ export declare function usdNumberToMicros(value: number): number | null;
94
+ /**
95
+ * Either accepted form as integer micro-USD, or `null` when the value is not a
96
+ * usable amount.
97
+ *
98
+ * This is the reader every enforcement path uses. It accepts the historical
99
+ * number deliberately: a record already in the log must feed budget math
100
+ * identically to before this change.
101
+ */
102
+ export declare function usdToMicros(value: unknown): number | null;
103
+ /** Integer micro-USD as the canonical decimal string. */
104
+ export declare function microsToUsdString(micros: number): string;
105
+ /**
106
+ * Integer micro-USD as a JSON number, for **display and CLI output only**.
107
+ *
108
+ * Never write the result of this function into hashed material: that is the
109
+ * float this module exists to remove. Budget verdicts report through it because
110
+ * a verdict is a rendered explanation of a decision the integers already made.
111
+ */
112
+ export declare function microsToUsdNumber(micros: number): number;
113
+ /**
114
+ * Either accepted form as a canonical decimal string, or `null` when the value
115
+ * is not a usable amount.
116
+ *
117
+ * The normalizer at every boundary where an amount arrives from outside: a task
118
+ * envelope, a CLI flag, a historical log record.
119
+ */
120
+ export declare function normalizeUsd(value: unknown): string | null;
121
+ /**
122
+ * Either accepted form as a canonical decimal string, defaulting to `"0"`.
123
+ *
124
+ * The budgets contract of `core/budgets.ts` requires `est_cost_usd` on every
125
+ * consuming event, and an action that declared no cost is recorded as `"0"` —
126
+ * an authorization with no declared cost is still an authorization.
127
+ */
128
+ export declare function usdOrZero(value: unknown): string;
129
+ /**
130
+ * Either accepted form as a JSON number, for **display surfaces only**: a
131
+ * channel card, a CLI table, a `--json` field a human reads.
132
+ *
133
+ * `0` for anything unusable, so a renderer never has to decide what to print
134
+ * for a malformed amount. Same warning as {@link microsToUsdNumber}: the result
135
+ * of this function must never be written into hashed material.
136
+ */
137
+ export declare function usdNumber(value: unknown): number;
138
+ /**
139
+ * Either accepted form as a JSON number, or `null` when there is no amount.
140
+ *
141
+ * The display counterpart of {@link normalizeUsd}: it keeps "declared nothing"
142
+ * distinct from "declared zero", which is a distinction the queue's own columns
143
+ * make.
144
+ */
145
+ export declare function usdNumberOrNull(value: unknown): number | null;
146
+ /** An amount as accepted from a caller: canonical string, or historical number. */
147
+ export type UsdInput = string | number;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * What the payload store holds, read against what the log says about it
3
+ * (APRV-41's counts, APRV-59's home for them).
4
+ *
5
+ * The census is a *reporting* question, asked by `approval doctor` and by
6
+ * `approval status`, and answered from two sources that can disagree: the files
7
+ * under `.approval/payloads/` and the records of `events.jsonl`. It decides
8
+ * nothing and deletes nothing. The daemon's pruner (`daemon/prune.ts`) is the
9
+ * only caller allowed to act on the same facts, and it derives its plan through
10
+ * the two helpers exported here so that the counts a reader is shown and the
11
+ * files the daemon would remove are computed by one piece of code.
12
+ *
13
+ * ## Why this lives in `core/` and not beside the pruner
14
+ *
15
+ * The CLI reports these numbers, and a CLI verb reaching into `daemon/` to do it
16
+ * is the wrong direction: `daemon/` is a caller of the core, never a dependency
17
+ * of the surfaces. This module is that shared core. Nothing here reads a clock,
18
+ * loads a policy, appends an event, or unlinks a file.
19
+ *
20
+ * ## Why not in `core/payload-store.ts`
21
+ *
22
+ * The store module is deliberately ignorant of the log ("Nothing here opens
23
+ * `events.jsonl`"): it addresses bytes by hash and verifies them, and that
24
+ * narrowness is what makes it safe to call from every channel. The census is the
25
+ * opposite kind of thing, a comparison between the log and the store, so it gets
26
+ * its own module rather than teaching the store to read events.
27
+ */
28
+ import type { EventRecord } from "./log.js";
29
+ /** Hashes a `payload.pruned` record already names. */
30
+ export declare function prunedHashes(records: EventRecord[]): Set<string>;
31
+ export interface Binding {
32
+ /** Action keys that declared this hash. */
33
+ actionKeys: Set<string>;
34
+ /** A record named the hash without an action key: bound, but unattributable. */
35
+ unattributed: boolean;
36
+ }
37
+ /**
38
+ * Every hash any record binds to, mapped to the actions that declared it.
39
+ *
40
+ * Two attributions are understood, because they are the two the runtime writes:
41
+ * a `payload_hash` beside a record's own `action_key` (`approval.requested` and
42
+ * `approval.granted` carry it there), and the `payload_hash` of each action
43
+ * inside a `task.registered` envelope, attributed to that action's
44
+ * `idempotency_key` — which is where a *registered but not yet requested* action
45
+ * declares its bytes. Without the second, a payload stored at registration time
46
+ * would look like residue nothing bound and be pruned out from under the request
47
+ * about to be made for it.
48
+ *
49
+ * Everything else is caught by a deep scan and deliberately treated as a
50
+ * binding this module cannot attribute: an unattributable binding is never
51
+ * prunable, so an event shape nobody here anticipated makes a payload immortal
52
+ * rather than making it disposable. The only event exempt from the scan is
53
+ * `payload.pruned`, whose whole job is to name bytes that are going.
54
+ */
55
+ export declare function bindingsOf(records: EventRecord[]): Map<string, Binding>;
56
+ export interface PayloadStoreCensus {
57
+ /** Files the store currently holds, by hash. */
58
+ files: number;
59
+ /** Distinct hashes a `payload.pruned` event names — evidence that outlived bytes. */
60
+ pruned: number;
61
+ /** Files present that no record binds: head-moved residue, prunable when enabled. */
62
+ orphans: number;
63
+ /** Files present whose prune event is already logged (a crash mid-prune). */
64
+ awaitingRemoval: number;
65
+ }
66
+ /**
67
+ * Count what the store holds against what the log says about it.
68
+ *
69
+ * Honest in both directions and about both failure modes: `pruned` is a fact of
70
+ * the log (it stays true forever, whatever the store does), `orphans` and
71
+ * `awaitingRemoval` are facts about the disagreement between the two. None of
72
+ * them is a health verdict; a reader is being told what is there.
73
+ */
74
+ export declare function payloadStoreCensus(records: EventRecord[], storeDir: string): PayloadStoreCensus;