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.
- package/README.md +584 -553
- package/SPEC.md +42 -13
- package/dist/src/adapters/agentmail.d.ts +426 -0
- package/dist/src/adapters/agentmail.js +2 -2
- package/dist/src/adapters/conformance.d.ts +149 -0
- package/dist/src/adapters/contract.d.ts +628 -0
- package/dist/src/adapters/contract.js +110 -16
- package/dist/src/adapters/contract.js.map +1 -1
- package/dist/src/adapters/email.d.ts +324 -0
- package/dist/src/adapters/env-passphrase.d.ts +93 -0
- package/dist/src/adapters/public.d.ts +11 -0
- package/dist/src/adapters/public.js +11 -0
- package/dist/src/adapters/public.js.map +1 -0
- package/dist/src/adapters/registry.d.ts +59 -0
- package/dist/src/adapters/registry.js +2 -1
- package/dist/src/adapters/registry.js.map +1 -1
- package/dist/src/adapters/smtp.d.ts +213 -0
- package/dist/src/adapters/vault-provider.d.ts +114 -0
- package/dist/src/adapters/vault-provider.js +3 -3
- package/dist/src/adapters/zzz.d.ts +66 -0
- package/dist/src/adapters/zzz.js +299 -0
- package/dist/src/adapters/zzz.js.map +1 -0
- package/dist/src/channels/batch.d.ts +109 -0
- package/dist/src/channels/cli.d.ts +193 -0
- package/dist/src/channels/conformance.d.ts +92 -0
- package/dist/src/channels/contract.d.ts +623 -0
- package/dist/src/channels/payload-view.d.ts +35 -0
- package/dist/src/channels/render-queue.d.ts +149 -0
- package/dist/src/channels/tagging.d.ts +196 -0
- package/dist/src/channels/telegram.d.ts +1832 -0
- package/dist/src/channels/web.d.ts +341 -0
- package/dist/src/cli/adapter.d.ts +90 -0
- package/dist/src/cli/adapter.js +25 -15
- package/dist/src/cli/adapter.js.map +1 -1
- package/dist/src/cli/amend.d.ts +59 -0
- package/dist/src/cli/args.d.ts +43 -0
- package/dist/src/cli/attest.d.ts +41 -0
- package/dist/src/cli/audit-card.d.ts +62 -0
- package/dist/src/cli/audit.d.ts +59 -0
- package/dist/src/cli/channel-telegram.d.ts +806 -0
- package/dist/src/cli/channel-web.d.ts +131 -0
- package/dist/src/cli/channel.d.ts +71 -0
- package/dist/src/cli/checkpoint-tap.d.ts +169 -0
- package/dist/src/cli/codex.d.ts +2 -0
- package/dist/src/cli/codex.js +172 -0
- package/dist/src/cli/codex.js.map +1 -0
- package/dist/src/cli/coverage.d.ts +61 -0
- package/dist/src/cli/daemon.d.ts +120 -0
- package/dist/src/cli/doctor.d.ts +129 -0
- package/dist/src/cli/doctor.js +119 -5
- package/dist/src/cli/doctor.js.map +1 -1
- package/dist/src/cli/env.d.ts +65 -0
- package/dist/src/cli/execute.d.ts +202 -0
- package/dist/src/cli/exit-codes.d.ts +73 -0
- package/dist/src/cli/feedback.d.ts +60 -0
- package/dist/src/cli/gate-window.d.ts +40 -0
- package/dist/src/cli/gate.d.ts +68 -0
- package/dist/src/cli/git-scope.d.ts +190 -0
- package/dist/src/cli/gloss-attach.d.ts +85 -0
- package/dist/src/cli/gloss-codex-child.d.ts +9 -0
- package/dist/src/cli/gloss-codex.d.ts +24 -0
- package/dist/src/cli/gloss-options.d.ts +42 -0
- package/dist/src/cli/gloss.d.ts +265 -0
- package/dist/src/cli/help.d.ts +103 -0
- package/dist/src/cli/help.js +173 -51
- package/dist/src/cli/help.js.map +1 -1
- package/dist/src/cli/hook-codex.d.ts +78 -0
- package/dist/src/cli/hook-codex.js +167 -0
- package/dist/src/cli/hook-codex.js.map +1 -0
- package/dist/src/cli/hook.d.ts +331 -0
- package/dist/src/cli/hook.js +186 -80
- package/dist/src/cli/hook.js.map +1 -1
- package/dist/src/cli/import.d.ts +35 -0
- package/dist/src/cli/init.d.ts +84 -0
- package/dist/src/cli/init.js +2 -2
- package/dist/src/cli/init.js.map +1 -1
- package/dist/src/cli/instructions.d.ts +23 -0
- package/dist/src/cli/journal.d.ts +41 -0
- package/dist/src/cli/log-advance.d.ts +287 -0
- package/dist/src/cli/log-advance.js +102 -11
- package/dist/src/cli/log-advance.js.map +1 -1
- package/dist/src/cli/log-anchor.d.ts +176 -0
- package/dist/src/cli/log-checkpoint.d.ts +22 -0
- package/dist/src/cli/log-sync.d.ts +243 -0
- package/dist/src/cli/log-verbs.d.ts +16 -0
- package/dist/src/cli/log-verbs.js +7 -1
- package/dist/src/cli/log-verbs.js.map +1 -1
- package/dist/src/cli/long-help.d.ts +70 -0
- package/dist/src/cli/main.d.ts +77 -0
- package/dist/src/cli/main.js +155 -5
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/cli/mcp.d.ts +52 -0
- package/dist/src/cli/paths.d.ts +56 -0
- package/dist/src/cli/payload.d.ts +58 -0
- package/dist/src/cli/policy.d.ts +43 -0
- package/dist/src/cli/preflight.d.ts +363 -0
- package/dist/src/cli/preflight.js +294 -7
- package/dist/src/cli/preflight.js.map +1 -1
- package/dist/src/cli/progress.d.ts +78 -0
- package/dist/src/cli/prompt.d.ts +209 -0
- package/dist/src/cli/quickstart.d.ts +46 -0
- package/dist/src/cli/quickstart.js +297 -0
- package/dist/src/cli/quickstart.js.map +1 -0
- package/dist/src/cli/records.d.ts +34 -0
- package/dist/src/cli/render.d.ts +22 -0
- package/dist/src/cli/sandbox.d.ts +51 -0
- package/dist/src/cli/scaffold.d.ts +79 -0
- package/dist/src/cli/setup-adapter.d.ts +137 -0
- package/dist/src/cli/setup-adapter.js +38 -4
- package/dist/src/cli/setup-adapter.js.map +1 -1
- package/dist/src/cli/setup-channel.d.ts +117 -0
- package/dist/src/cli/setup-checkpoint.d.ts +57 -0
- package/dist/src/cli/setup-common.d.ts +275 -0
- package/dist/src/cli/setup-flow.d.ts +287 -0
- package/dist/src/cli/setup-service.d.ts +96 -0
- package/dist/src/cli/setup.d.ts +202 -0
- package/dist/src/cli/style.d.ts +320 -0
- package/dist/src/cli/token.d.ts +39 -0
- package/dist/src/cli/up.d.ts +155 -0
- package/dist/src/cli/up.js +4 -2
- package/dist/src/cli/up.js.map +1 -1
- package/dist/src/cli/usage.d.ts +37 -0
- package/dist/src/cli/values.d.ts +40 -0
- package/dist/src/cli/vault.d.ts +59 -0
- package/dist/src/cli/vault.js +2 -2
- package/dist/src/cli/vault.js.map +1 -1
- package/dist/src/cli/verb-registry.d.ts +76 -0
- package/dist/src/cli/verb-registry.js +176 -8
- package/dist/src/cli/verb-registry.js.map +1 -1
- package/dist/src/cli/wordmark.d.ts +31 -0
- package/dist/src/cli/wordmark.js +2 -2
- package/dist/src/codex/doctor.d.ts +13 -0
- package/dist/src/codex/doctor.js +41 -0
- package/dist/src/codex/doctor.js.map +1 -0
- package/dist/src/codex/manifest.d.ts +49 -0
- package/dist/src/codex/manifest.js +103 -0
- package/dist/src/codex/manifest.js.map +1 -0
- package/dist/src/codex/templates.d.ts +41 -0
- package/dist/src/codex/templates.js +319 -0
- package/dist/src/codex/templates.js.map +1 -0
- package/dist/src/codex/trust.d.ts +19 -0
- package/dist/src/codex/trust.js +183 -0
- package/dist/src/codex/trust.js.map +1 -0
- package/dist/src/codex/workspace-plan.d.ts +131 -0
- package/dist/src/codex/workspace-plan.js +561 -0
- package/dist/src/codex/workspace-plan.js.map +1 -0
- package/dist/src/core/actor.d.ts +2 -0
- package/dist/src/core/actor.js +5 -0
- package/dist/src/core/actor.js.map +1 -0
- package/dist/src/core/advance-cycle.d.ts +170 -0
- package/dist/src/core/agents-md.d.ts +276 -0
- package/dist/src/core/apply-patch.d.ts +49 -0
- package/dist/src/core/apply-patch.js +266 -0
- package/dist/src/core/apply-patch.js.map +1 -0
- package/dist/src/core/attest.d.ts +420 -0
- package/dist/src/core/attest.js +13 -1
- package/dist/src/core/attest.js.map +1 -1
- package/dist/src/core/audit.d.ts +492 -0
- package/dist/src/core/budgets.d.ts +238 -0
- package/dist/src/core/checkpoint.d.ts +500 -0
- package/dist/src/core/child-env.d.ts +88 -0
- package/dist/src/core/clock.d.ts +52 -0
- package/dist/src/core/command-class.d.ts +543 -0
- package/dist/src/core/command-class.js +43 -8
- package/dist/src/core/command-class.js.map +1 -1
- package/dist/src/core/coverage-sources/adapter.d.ts +40 -0
- package/dist/src/core/coverage-sources/gh.d.ts +48 -0
- package/dist/src/core/coverage-sources/git.d.ts +101 -0
- package/dist/src/core/coverage.d.ts +217 -0
- package/dist/src/core/credential-spec.d.ts +72 -0
- package/dist/src/core/dark-session.d.ts +331 -0
- package/dist/src/core/decision-refusal.d.ts +185 -0
- package/dist/src/core/env-file.d.ts +450 -0
- package/dist/src/core/execute.d.ts +858 -0
- package/dist/src/core/execute.js +44 -6
- package/dist/src/core/execute.js.map +1 -1
- package/dist/src/core/frontmatter.d.ts +78 -0
- package/dist/src/core/gate-window.d.ts +312 -0
- package/dist/src/core/gate.d.ts +1364 -0
- package/dist/src/core/gate.js +68 -13
- package/dist/src/core/gate.js.map +1 -1
- package/dist/src/core/git-run.d.ts +73 -0
- package/dist/src/core/harness-version.d.ts +157 -0
- package/dist/src/core/harness-version.js +2 -1
- package/dist/src/core/harness-version.js.map +1 -1
- package/dist/src/core/harness-wait.d.ts +55 -0
- package/dist/src/core/head-retry.d.ts +107 -0
- package/dist/src/core/instance.d.ts +253 -0
- package/dist/src/core/intake-limits.d.ts +247 -0
- package/dist/src/core/jcs.d.ts +52 -0
- package/dist/src/core/journal.d.ts +144 -0
- package/dist/src/core/live-draw.d.ts +436 -0
- package/dist/src/core/log-reconcile.d.ts +89 -0
- package/dist/src/core/log-subscribe.d.ts +36 -0
- package/dist/src/core/log-subscribe.js +162 -0
- package/dist/src/core/log-subscribe.js.map +1 -0
- package/dist/src/core/log.d.ts +278 -0
- package/dist/src/core/loop.d.ts +274 -0
- package/dist/src/core/loop.js +11 -0
- package/dist/src/core/loop.js.map +1 -1
- package/dist/src/core/md-fence.d.ts +41 -0
- package/dist/src/core/money.d.ts +147 -0
- package/dist/src/core/payload-census.d.ts +74 -0
- package/dist/src/core/payload-store.d.ts +175 -0
- package/dist/src/core/payload.d.ts +71 -0
- package/dist/src/core/policy-diff.d.ts +292 -0
- package/dist/src/core/policy-diff.js +27 -4
- package/dist/src/core/policy-diff.js.map +1 -1
- package/dist/src/core/policy-expectations.d.ts +199 -0
- package/dist/src/core/policy-explain.d.ts +150 -0
- package/dist/src/core/policy-explain.js +31 -3
- package/dist/src/core/policy-explain.js.map +1 -1
- package/dist/src/core/policy-load.d.ts +527 -0
- package/dist/src/core/policy-load.js +15 -3
- package/dist/src/core/policy-load.js.map +1 -1
- package/dist/src/core/policy-match.d.ts +281 -0
- package/dist/src/core/policy-match.js +20 -9
- package/dist/src/core/policy-match.js.map +1 -1
- package/dist/src/core/policy-proposal.d.ts +265 -0
- package/dist/src/core/prompt-layout.d.ts +221 -0
- package/dist/src/core/protected-path-guard.d.ts +453 -0
- package/dist/src/core/protected-path-guard.js +514 -35
- package/dist/src/core/protected-path-guard.js.map +1 -1
- package/dist/src/core/registration.d.ts +25 -0
- package/dist/src/core/reindex.d.ts +99 -0
- package/dist/src/core/sampler.d.ts +313 -0
- package/dist/src/core/sandbox.d.ts +290 -0
- package/dist/src/core/seal.d.ts +165 -0
- package/dist/src/core/state.d.ts +505 -0
- package/dist/src/core/task-file.d.ts +185 -0
- package/dist/src/core/telegram-config.d.ts +93 -0
- package/dist/src/core/token.d.ts +409 -0
- package/dist/src/core/token.js +21 -38
- package/dist/src/core/token.js.map +1 -1
- package/dist/src/core/validate.d.ts +138 -0
- package/dist/src/core/values.d.ts +137 -0
- package/dist/src/core/vault.d.ts +291 -0
- package/dist/src/core/verified-snapshot.d.ts +204 -0
- package/dist/src/core/verify.d.ts +336 -0
- package/dist/src/core/version.d.ts +8 -0
- package/dist/src/core/wysiwys.d.ts +370 -0
- package/dist/src/daemon/advance-child.d.ts +39 -0
- package/dist/src/daemon/advance.d.ts +466 -0
- package/dist/src/daemon/audit.d.ts +87 -0
- package/dist/src/daemon/daemon.d.ts +1180 -0
- package/dist/src/daemon/dark-session.d.ts +64 -0
- package/dist/src/daemon/draw-child.d.ts +36 -0
- package/dist/src/daemon/draw.d.ts +154 -0
- package/dist/src/daemon/git-evidence.d.ts +173 -0
- package/dist/src/daemon/git-evidence.js +1 -1
- package/dist/src/daemon/projection.d.ts +180 -0
- package/dist/src/daemon/prune.d.ts +207 -0
- package/dist/src/mcp/http.d.ts +113 -0
- package/dist/src/mcp/server.d.ts +265 -0
- package/dist/src/mcp/server.js +9 -1
- package/dist/src/mcp/server.js.map +1 -1
- package/docs/adapter-api.md +106 -0
- package/docs/cli-reference.md +389 -36
- package/docs/codex-enforced-session.md +30 -0
- package/package.json +12 -2
- package/schema/codex-instance.schema.json +82 -0
- package/schema/event.schema.json +2 -1
- package/schema/fixtures/codex-instance/invalid/unpinned-codex-version.json +40 -0
- package/schema/fixtures/codex-instance/valid/canonical.json +40 -0
- package/schema/policy.schema.json +21 -1
- 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;
|
package/dist/src/core/loop.js
CHANGED
|
@@ -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;
|