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,238 @@
1
+ /**
2
+ * Budget evaluation from the log (SPEC.md §5.2, §8).
3
+ *
4
+ * "An action must pass its class limits AND global budgets. Budget consumption
5
+ * is computed from the log, never from a mutable counter." This module is that
6
+ * computation: given the records of the append-only log, the limits the policy
7
+ * matcher already resolved, the action about to be admitted, and the moment of
8
+ * evaluation, it returns a per-limit verdict and one conjunctive answer.
9
+ *
10
+ * Pure and deterministic: no I/O, no clock, no randomness, no caching. The
11
+ * evaluation timestamp is a **required parameter** — a budget decision that
12
+ * depended on ambient time could not be replayed from the log, and replay is
13
+ * the whole point of computing consumption from the log in the first place.
14
+ * This module also does not re-run class matching: the gate hands in the
15
+ * already-matched limits and the pattern that produced them.
16
+ *
17
+ * ## THE CONSUMPTION CONTRACT — what APRV-16 (the gate) MUST honor
18
+ *
19
+ * Budgets meter **authorization**, not completion. An authorized action
20
+ * consumes budget whether or not it ultimately executes, because the human's
21
+ * decision is the commitment; a runtime that only charged completed actions
22
+ * would let a crashed or hung executor mint unlimited authorizations.
23
+ *
24
+ * The evaluator therefore reads consumption from exactly two event types, and
25
+ * the gate MUST write them accordingly:
26
+ *
27
+ * 1. `approval.granted` — the manual path. A human said yes; budget is spent.
28
+ * 2. `execution.started` — the supervised/autonomous paths. Under the amended
29
+ * §6.3 those paths emit no approval events, so the record that authorizes
30
+ * execution *is* the start event.
31
+ *
32
+ * To avoid charging a manual action twice (granted, then started), an
33
+ * `execution.started` is counted only when the window contains no
34
+ * `approval.granted` bearing the same `action_key`.
35
+ *
36
+ * **The gate MUST record `payload.est_cost_usd` (a decimal USD string since
37
+ * APRV-121, a JSON number in records written before it) and
38
+ * `payload.class` (the action's dotted class string) on every
39
+ * `approval.granted` and `execution.started` event it appends.** Those two
40
+ * payload fields are the entire input to USD accounting and class scoping.
41
+ * A consuming event with no usable `est_cost_usd` contributes **0** to USD
42
+ * sums but still counts as **1** action for `daily_actions` — an authorization
43
+ * with no declared cost is still an authorization. A consuming event with no
44
+ * usable `payload.class` is invisible to class-scoped limits (it cannot be
45
+ * shown to belong to the class) but is still counted by global budgets, which
46
+ * charge every authorization regardless of class.
47
+ *
48
+ * Nothing else consumes. `approval.rejected`, `approval.expired`,
49
+ * `approval.revoked`, and `approval.withdrawn` (APRV-106) consume nothing: an
50
+ * authorization that was refused, lapsed, or never asked for in the end was
51
+ * never a commitment. `execution.completed` and `execution.failed`
52
+ * consume nothing either — they report on a commitment already charged at
53
+ * authorization time, and charging them again would double-count.
54
+ *
55
+ * ## The rolling window (SPEC.md §5.2, rolling-window amendment)
56
+ *
57
+ * A `daily` limit is evaluated over the 24 hours preceding the evaluation
58
+ * moment, not over a calendar day. An event consumes iff
59
+ *
60
+ * evaluationTs - 24h < event.ts <= evaluationTs
61
+ *
62
+ * — half-open at the bottom, closed at the top. An event exactly 24h old has
63
+ * aged out; an event stamped at the evaluation instant is in. The bound is
64
+ * half-open on exactly one side so that consecutive 24h windows tile the
65
+ * timeline without double-counting a boundary event. Timestamps are compared
66
+ * via `Date.parse` on the RFC 3339 strings the schema already guarantees.
67
+ *
68
+ * Rolling, not calendar: a burst that straddles midnight must not have its own
69
+ * tripwire reset underneath it.
70
+ *
71
+ * ## Fail-closed
72
+ *
73
+ * A limit the evaluator does not understand cannot be proven satisfied, so it
74
+ * fails: an unknown limit name yields `pass: false` with an explanatory `note`.
75
+ * The same applies to an unparseable evaluation timestamp (no window can be
76
+ * computed) and to class-scoped rolling limits offered without the class
77
+ * pattern that scopes their consumption. Silence is never a grant.
78
+ *
79
+ * ## What this module does NOT evaluate (APRV-173)
80
+ *
81
+ * `max_pending` and `requests_per_hour` (SPEC.md §5.2) are request-volume
82
+ * limits: they cap the approver's queue rather than the world's exposure, they
83
+ * are counted from `approval.requested` rather than from authorizations, and
84
+ * `core/intake-limits.ts` evaluates them at intake. They are skipped by name
85
+ * here rather than refused as unknown limits, and the skip is exactly the two
86
+ * names that module owns, read from its own exported list. Neither module's
87
+ * silence widens a ceiling: every limit name is evaluated by one of them, or
88
+ * fails closed as unknown in this one.
89
+ */
90
+ import type { Policy } from "./policy-load.js";
91
+ import type { EventRecord } from "./log.js";
92
+ import { type UsdInput } from "./money.js";
93
+ /** Length of the rolling `daily` window: 24 hours, in milliseconds. */
94
+ export declare const WINDOW_MS: number;
95
+ /** Event types that authorize execution and therefore consume budget. */
96
+ export declare const CONSUMING_EVENTS: readonly ["approval.granted", "execution.started"];
97
+ /**
98
+ * Which limits apply, as resolved by the policy matcher — this module does not
99
+ * re-run matching.
100
+ *
101
+ * - `classLimits` is `Resolution.limits`: the matched rule's `limits` map.
102
+ * - `classPattern` is the pattern of the rule those limits came from
103
+ * (`Resolution.matched.pattern`). Class-scoped rolling limits count only
104
+ * authorizations whose `payload.class` matches this **same rule pattern** —
105
+ * not string equality with the action's class. A `financial.*` rule is one
106
+ * budget shared by every class it governs, which is what a policy author
107
+ * writing a single `daily_usd` under `financial.*` means; charging
108
+ * `financial.spend` and `financial.transfer` to separate invisible buckets
109
+ * would silently double the ceiling they wrote.
110
+ * - `globalBudgets` is `policy.budgets`: named scopes, each conjunctive.
111
+ */
112
+ export interface BudgetScope {
113
+ classLimits: Record<string, number> | null;
114
+ classPattern: string | null;
115
+ globalBudgets: Policy["budgets"] | null;
116
+ }
117
+ /**
118
+ * The action being admitted. `est_cost_usd` absent means "no declared cost".
119
+ *
120
+ * The amount is a canonical decimal string (APRV-121, `core/money.ts`). A JSON
121
+ * number is accepted here as the historical form — records written before that
122
+ * change carry one, and this evaluator must read them identically to before.
123
+ */
124
+ export interface BudgetAction {
125
+ class: string;
126
+ est_cost_usd?: UsdInput;
127
+ }
128
+ /**
129
+ * Which window a limit is measured over.
130
+ *
131
+ * `task-total` is the envelope cap of SPEC.md §6.2 (`budget.max_cost_usd`): not
132
+ * a window at all but the whole life of one task, which is what "maximum total
133
+ * spend across this task's actions" means.
134
+ */
135
+ export type BudgetWindow = "per-action" | "rolling-24h" | "task-total";
136
+ /**
137
+ * Where a limit came from: the matched class rule, `policy.budgets`, or the
138
+ * task's own registered envelope (SPEC.md §6.2 `budget`). All three are
139
+ * conjunctive with each other — "the stricter of the two binds".
140
+ */
141
+ export type BudgetVerdictScope = "class" | "global" | "task";
142
+ /**
143
+ * One limit's outcome.
144
+ *
145
+ * `consumed` is what the window already holds, `requested` is what this action
146
+ * would add (USD for money limits, `1` for action counts), and `remaining` is
147
+ * `limit - consumed - requested` — the headroom left *after* admitting the
148
+ * action, so a `pass: false` verdict shows how far over the line it is.
149
+ * `note` is present only when the verdict needs explaining, which at v0.1 means
150
+ * only fail-closed refusals.
151
+ *
152
+ * The three figures are **decimal strings** (APRV-121). A failing verdict is
153
+ * copied verbatim into the `budget.exceeded` payload, which is hashed material,
154
+ * and a float there would be exactly the cross-language serialization hazard
155
+ * this project removed from `est_cost_usd`. Money is reported in canonical USD
156
+ * (`"0.3"`), counts as integers (`"3"`); a negative `remaining` — headroom
157
+ * already spent — is spelled with a leading `-`, so it is a decimal string but
158
+ * not a canonical amount, which only ever describes money being declared.
159
+ */
160
+ export interface BudgetVerdict {
161
+ limit: string;
162
+ scope: BudgetVerdictScope;
163
+ window: BudgetWindow;
164
+ consumed: string;
165
+ requested: string;
166
+ remaining: string;
167
+ pass: boolean;
168
+ note?: string;
169
+ }
170
+ /** Outcome of {@link evaluateBudgets}. Conjunctive: all must pass. */
171
+ export interface BudgetVerdicts {
172
+ pass: boolean;
173
+ verdicts: BudgetVerdict[];
174
+ }
175
+ /** The verdict label for the envelope's own cap (SPEC.md §6.2 `budget`). */
176
+ export declare const TASK_MAX_COST_USD = "budget.max_cost_usd";
177
+ /**
178
+ * Evaluate every applicable budget limit against the log.
179
+ *
180
+ * Conjunctive (SPEC.md §5.2): `pass` is true only when every verdict passes.
181
+ * Verdicts are emitted class limits first (limit names ascending), then global
182
+ * budgets (scope name ascending, limit name ascending within a scope), so the
183
+ * list is byte-stable regardless of policy key order.
184
+ *
185
+ * `records` may be the whole log; only the rolling window is consulted, and the
186
+ * caller is never asked to pre-filter (a caller that filtered wrongly would
187
+ * silently widen the budget).
188
+ */
189
+ export declare function evaluateBudgets(records: EventRecord[], scope: BudgetScope, action: BudgetAction, evaluationTs: string): BudgetVerdicts;
190
+ /**
191
+ * The registered envelope's `budget.max_cost_usd` for `task`, or `null`.
192
+ *
193
+ * Read from the **log**, not from the task file: the file may have been edited
194
+ * since registration, and an agent that could raise its own cap by editing
195
+ * frontmatter after the fact would be authoring the ceiling it is judged by.
196
+ * `register` copies the envelope's `budget` block into the `task.registered`
197
+ * payload for exactly this read. The last registration wins, matching
198
+ * `findDeclaration` in `core/execute.ts`.
199
+ *
200
+ * A cap that is not a finite non-negative number is `null` — absent rather than
201
+ * zero. The schema already refuses those shapes at the write boundary, and
202
+ * inventing a $0 ceiling for a malformed one would refuse every action of the
203
+ * task with a message about money nobody wrote down.
204
+ */
205
+ export declare function taskMaxCostUsd(records: EventRecord[], task: string): string | null;
206
+ /**
207
+ * Evaluate the task's own cap: does admitting `action` keep the SUM of this
208
+ * task's authorized `est_cost_usd` at or under `maxCostUsd`?
209
+ *
210
+ * Commitment-based and consumption-identical to {@link evaluateBudgets}: the
211
+ * same two event types authorize (`approval.granted`, and `execution.started`
212
+ * only where no grant carries the same `action_key`), so a manual action that is
213
+ * granted and then started is charged once. The only differences are scope —
214
+ * events of *this task* — and window: there is none. A task cap is a lifetime
215
+ * total, so an envelope that says `max_cost_usd: 0.5` cannot be spent twice by
216
+ * waiting a day.
217
+ *
218
+ * `evaluationTs` is accepted for symmetry with the windowed evaluator and to
219
+ * keep every budget call site shaped alike; it selects no window here and the
220
+ * verdict does not depend on it.
221
+ */
222
+ export declare function evaluateTaskBudget(records: EventRecord[], task: string, maxCostUsd: UsdInput, action: BudgetAction, _evaluationTs: string): BudgetVerdict;
223
+ /**
224
+ * Every applicable budget, conjunctively: class limits, global budgets, and the
225
+ * task envelope's own cap.
226
+ *
227
+ * This is the function the three enforcement points call (`gate.request`,
228
+ * `gate.decide`'s grant path, `execute.startExecution`), so the envelope cap is
229
+ * checked at intake, at grant, and at execution start — the same three moments
230
+ * policy budgets are checked, because a cap enforced at only one of them is a
231
+ * cap a caller can route around by choosing a different door.
232
+ *
233
+ * Verdict order is class limits, then global budgets, then the task cap: the
234
+ * existing byte-stable order with one deterministic addition at the end.
235
+ * `task` may be `null` for a call site that has no task in hand, in which case
236
+ * the cap simply does not apply.
237
+ */
238
+ export declare function evaluateBudgetsWithTask(records: EventRecord[], scope: BudgetScope, action: BudgetAction, evaluationTs: string, task: string | null): BudgetVerdicts;