@flowdot.ai/guardian-agent 0.1.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 (188) hide show
  1. package/LICENSE +40 -0
  2. package/README.md +281 -0
  3. package/ROADMAP.md +109 -0
  4. package/dist/audit/attestor.d.ts +102 -0
  5. package/dist/audit/attestor.d.ts.map +1 -0
  6. package/dist/audit/attestor.js +103 -0
  7. package/dist/audit/attestor.js.map +1 -0
  8. package/dist/audit/chain.d.ts +30 -0
  9. package/dist/audit/chain.d.ts.map +1 -0
  10. package/dist/audit/chain.js +65 -0
  11. package/dist/audit/chain.js.map +1 -0
  12. package/dist/audit/correlation.d.ts +114 -0
  13. package/dist/audit/correlation.d.ts.map +1 -0
  14. package/dist/audit/correlation.js +259 -0
  15. package/dist/audit/correlation.js.map +1 -0
  16. package/dist/audit/index.d.ts +13 -0
  17. package/dist/audit/index.d.ts.map +1 -0
  18. package/dist/audit/index.js +8 -0
  19. package/dist/audit/index.js.map +1 -0
  20. package/dist/audit/reader.d.ts +30 -0
  21. package/dist/audit/reader.d.ts.map +1 -0
  22. package/dist/audit/reader.js +85 -0
  23. package/dist/audit/reader.js.map +1 -0
  24. package/dist/audit/signature.d.ts +39 -0
  25. package/dist/audit/signature.d.ts.map +1 -0
  26. package/dist/audit/signature.js +73 -0
  27. package/dist/audit/signature.js.map +1 -0
  28. package/dist/audit/stats.d.ts +106 -0
  29. package/dist/audit/stats.d.ts.map +1 -0
  30. package/dist/audit/stats.js +196 -0
  31. package/dist/audit/stats.js.map +1 -0
  32. package/dist/audit/writer.d.ts +96 -0
  33. package/dist/audit/writer.d.ts.map +1 -0
  34. package/dist/audit/writer.js +263 -0
  35. package/dist/audit/writer.js.map +1 -0
  36. package/dist/cli/guardian-baseline.d.ts +42 -0
  37. package/dist/cli/guardian-baseline.d.ts.map +1 -0
  38. package/dist/cli/guardian-baseline.js +265 -0
  39. package/dist/cli/guardian-baseline.js.map +1 -0
  40. package/dist/cli/guardian-correlator.d.ts +47 -0
  41. package/dist/cli/guardian-correlator.d.ts.map +1 -0
  42. package/dist/cli/guardian-correlator.js +217 -0
  43. package/dist/cli/guardian-correlator.js.map +1 -0
  44. package/dist/cli/guardian-verify.d.ts +30 -0
  45. package/dist/cli/guardian-verify.d.ts.map +1 -0
  46. package/dist/cli/guardian-verify.js +149 -0
  47. package/dist/cli/guardian-verify.js.map +1 -0
  48. package/dist/errors.d.ts +28 -0
  49. package/dist/errors.d.ts.map +1 -0
  50. package/dist/errors.js +40 -0
  51. package/dist/errors.js.map +1 -0
  52. package/dist/estop/heartbeat.d.ts +94 -0
  53. package/dist/estop/heartbeat.d.ts.map +1 -0
  54. package/dist/estop/heartbeat.js +135 -0
  55. package/dist/estop/heartbeat.js.map +1 -0
  56. package/dist/estop/hub.d.ts +76 -0
  57. package/dist/estop/hub.d.ts.map +1 -0
  58. package/dist/estop/hub.js +167 -0
  59. package/dist/estop/hub.js.map +1 -0
  60. package/dist/estop/index.d.ts +12 -0
  61. package/dist/estop/index.d.ts.map +1 -0
  62. package/dist/estop/index.js +6 -0
  63. package/dist/estop/index.js.map +1 -0
  64. package/dist/estop/local.d.ts +31 -0
  65. package/dist/estop/local.d.ts.map +1 -0
  66. package/dist/estop/local.js +101 -0
  67. package/dist/estop/local.js.map +1 -0
  68. package/dist/estop/middleware.d.ts +36 -0
  69. package/dist/estop/middleware.d.ts.map +1 -0
  70. package/dist/estop/middleware.js +40 -0
  71. package/dist/estop/middleware.js.map +1 -0
  72. package/dist/estop/poller.d.ts +36 -0
  73. package/dist/estop/poller.d.ts.map +1 -0
  74. package/dist/estop/poller.js +85 -0
  75. package/dist/estop/poller.js.map +1 -0
  76. package/dist/estop/types.d.ts +31 -0
  77. package/dist/estop/types.d.ts.map +1 -0
  78. package/dist/estop/types.js +5 -0
  79. package/dist/estop/types.js.map +1 -0
  80. package/dist/gate/async-callback.d.ts +27 -0
  81. package/dist/gate/async-callback.d.ts.map +1 -0
  82. package/dist/gate/async-callback.js +79 -0
  83. package/dist/gate/async-callback.js.map +1 -0
  84. package/dist/gate/cli.d.ts +29 -0
  85. package/dist/gate/cli.d.ts.map +1 -0
  86. package/dist/gate/cli.js +83 -0
  87. package/dist/gate/cli.js.map +1 -0
  88. package/dist/gate/data-channel.d.ts +41 -0
  89. package/dist/gate/data-channel.d.ts.map +1 -0
  90. package/dist/gate/data-channel.js +132 -0
  91. package/dist/gate/data-channel.js.map +1 -0
  92. package/dist/gate/index.d.ts +13 -0
  93. package/dist/gate/index.d.ts.map +1 -0
  94. package/dist/gate/index.js +7 -0
  95. package/dist/gate/index.js.map +1 -0
  96. package/dist/gate/options.d.ts +90 -0
  97. package/dist/gate/options.d.ts.map +1 -0
  98. package/dist/gate/options.js +131 -0
  99. package/dist/gate/options.js.map +1 -0
  100. package/dist/gate/programmatic.d.ts +9 -0
  101. package/dist/gate/programmatic.d.ts.map +1 -0
  102. package/dist/gate/programmatic.js +20 -0
  103. package/dist/gate/programmatic.js.map +1 -0
  104. package/dist/gate/two-key.d.ts +90 -0
  105. package/dist/gate/two-key.d.ts.map +1 -0
  106. package/dist/gate/two-key.js +78 -0
  107. package/dist/gate/two-key.js.map +1 -0
  108. package/dist/gate/types.d.ts +25 -0
  109. package/dist/gate/types.d.ts.map +1 -0
  110. package/dist/gate/types.js +5 -0
  111. package/dist/gate/types.js.map +1 -0
  112. package/dist/index.d.ts +33 -0
  113. package/dist/index.d.ts.map +1 -0
  114. package/dist/index.js +26 -0
  115. package/dist/index.js.map +1 -0
  116. package/dist/notify/console.d.ts +13 -0
  117. package/dist/notify/console.d.ts.map +1 -0
  118. package/dist/notify/console.js +27 -0
  119. package/dist/notify/console.js.map +1 -0
  120. package/dist/notify/index.d.ts +8 -0
  121. package/dist/notify/index.d.ts.map +1 -0
  122. package/dist/notify/index.js +4 -0
  123. package/dist/notify/index.js.map +1 -0
  124. package/dist/notify/multi.d.ts +14 -0
  125. package/dist/notify/multi.d.ts.map +1 -0
  126. package/dist/notify/multi.js +22 -0
  127. package/dist/notify/multi.js.map +1 -0
  128. package/dist/notify/types.d.ts +21 -0
  129. package/dist/notify/types.d.ts.map +1 -0
  130. package/dist/notify/types.js +5 -0
  131. package/dist/notify/types.js.map +1 -0
  132. package/dist/notify/webhook.d.ts +21 -0
  133. package/dist/notify/webhook.d.ts.map +1 -0
  134. package/dist/notify/webhook.js +37 -0
  135. package/dist/notify/webhook.js.map +1 -0
  136. package/dist/policy/attribution.d.ts +61 -0
  137. package/dist/policy/attribution.d.ts.map +1 -0
  138. package/dist/policy/attribution.js +116 -0
  139. package/dist/policy/attribution.js.map +1 -0
  140. package/dist/policy/evaluator.d.ts +36 -0
  141. package/dist/policy/evaluator.d.ts.map +1 -0
  142. package/dist/policy/evaluator.js +211 -0
  143. package/dist/policy/evaluator.js.map +1 -0
  144. package/dist/policy/index.d.ts +11 -0
  145. package/dist/policy/index.d.ts.map +1 -0
  146. package/dist/policy/index.js +7 -0
  147. package/dist/policy/index.js.map +1 -0
  148. package/dist/policy/integrity.d.ts +17 -0
  149. package/dist/policy/integrity.d.ts.map +1 -0
  150. package/dist/policy/integrity.js +31 -0
  151. package/dist/policy/integrity.js.map +1 -0
  152. package/dist/policy/loader.d.ts +9 -0
  153. package/dist/policy/loader.d.ts.map +1 -0
  154. package/dist/policy/loader.js +124 -0
  155. package/dist/policy/loader.js.map +1 -0
  156. package/dist/policy/site-key.d.ts +22 -0
  157. package/dist/policy/site-key.d.ts.map +1 -0
  158. package/dist/policy/site-key.js +48 -0
  159. package/dist/policy/site-key.js.map +1 -0
  160. package/dist/policy/store.d.ts +45 -0
  161. package/dist/policy/store.d.ts.map +1 -0
  162. package/dist/policy/store.js +223 -0
  163. package/dist/policy/store.js.map +1 -0
  164. package/dist/policy/types.d.ts +72 -0
  165. package/dist/policy/types.d.ts.map +1 -0
  166. package/dist/policy/types.js +5 -0
  167. package/dist/policy/types.js.map +1 -0
  168. package/dist/runtime/capability.d.ts +125 -0
  169. package/dist/runtime/capability.d.ts.map +1 -0
  170. package/dist/runtime/capability.js +121 -0
  171. package/dist/runtime/capability.js.map +1 -0
  172. package/dist/runtime/honeytokens.d.ts +104 -0
  173. package/dist/runtime/honeytokens.d.ts.map +1 -0
  174. package/dist/runtime/honeytokens.js +115 -0
  175. package/dist/runtime/honeytokens.js.map +1 -0
  176. package/dist/runtime/multi-rate-limiter.d.ts +90 -0
  177. package/dist/runtime/multi-rate-limiter.d.ts.map +1 -0
  178. package/dist/runtime/multi-rate-limiter.js +133 -0
  179. package/dist/runtime/multi-rate-limiter.js.map +1 -0
  180. package/dist/runtime/runtime.d.ts +94 -0
  181. package/dist/runtime/runtime.d.ts.map +1 -0
  182. package/dist/runtime/runtime.js +276 -0
  183. package/dist/runtime/runtime.js.map +1 -0
  184. package/dist/types.d.ts +97 -0
  185. package/dist/types.d.ts.map +1 -0
  186. package/dist/types.js +5 -0
  187. package/dist/types.js.map +1 -0
  188. package/package.json +83 -0
package/LICENSE ADDED
@@ -0,0 +1,40 @@
1
+ @flowdot.ai/guardian-agent — TypeScript reference implementation of the
2
+ guardian-agent runtime supervisor spec.
3
+ Copyright (C) 2026 FlowDot LLC
4
+
5
+ This program is free software: you can redistribute it and/or modify it under
6
+ the terms of the GNU Affero General Public License as published by the Free
7
+ Software Foundation, either version 3 of the License, or (at your option) any
8
+ later version.
9
+
10
+ This program is distributed in the hope that it will be useful, but WITHOUT
11
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12
+ FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13
+ details.
14
+
15
+ You should have received a copy of the GNU Affero General Public License along
16
+ with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ Full license text: https://www.gnu.org/licenses/agpl-3.0.txt
19
+
20
+ ---
21
+
22
+ COMMERCIAL LICENSING
23
+
24
+ For use cases where the terms of the AGPL-3.0 are not suitable — including
25
+ proprietary deployment, embedding in closed-source products, or distribution
26
+ without source-availability obligations — a commercial license is available.
27
+
28
+ Contact: licensing@flowdot.ai
29
+
30
+ ---
31
+
32
+ SPEC DOCUMENT
33
+
34
+ The canonical specification document lives at
35
+ https://github.com/flowdot-llc/guardian-agent/blob/main/SPEC.md
36
+ and is dual-licensed under AGPL-3.0-or-later and CC BY-SA 4.0. The CC BY-SA 4.0
37
+ licensing is intended to encourage citation and adaptation in research, policy,
38
+ and standards work.
39
+
40
+ See https://creativecommons.org/licenses/by-sa/4.0/ for the CC BY-SA 4.0 terms.
package/README.md ADDED
@@ -0,0 +1,281 @@
1
+ # @flowdot.ai/guardian-agent
2
+
3
+ > TypeScript reference implementation of the [guardian-agent spec](https://github.com/flowdot-llc/guardian-agent/blob/main/SPEC.md). A runtime supervisor for tool-using LLM agents: tamper-evident audit log, tool-permission policy, HITL approval gates, emergency-stop, plus a runtime-safety layer (honeytokens, capability tripwires, per-class rate limits, two-key operator gates, heartbeat) and offline analysis tools.
4
+
5
+ **Status**: v0.1.0 on npm · tracks SPEC v0.5 · v0.10 feature milestone hit · interface stabilizing toward v1.0
6
+
7
+ ```bash
8
+ npm install @flowdot.ai/guardian-agent
9
+ ```
10
+
11
+ > Note on versioning: milestone labels in this README (v0.1, v0.2, …, v0.10) refer to **feature milestones** in the [ROADMAP](./ROADMAP.md), not semver. The package's npm semver lives in `package.json`. Until the public API freezes for v1.0, expect minor-version churn — pin a specific minor in production.
12
+
13
+ The Python reference implementation lives at [`flowdot-llc/guardian-agent`](https://github.com/flowdot-llc/guardian-agent). This repository is the parallel TypeScript implementation. Both conform to the same versioned [spec](https://github.com/flowdot-llc/guardian-agent/blob/main/SPEC.md); the spec is the canonical contract, not either implementation.
14
+
15
+ ---
16
+
17
+ ## Why a second language
18
+
19
+ Python serves the research and evaluation ecosystem (LangChain, AutoGen, MCP Python clients, eval labs). TypeScript serves the production-runtime ecosystem — Node servers, Electron apps, TypeScript MCP clients, LangChain.js, and the broader JS agent tooling. The same spec, in both places, is how a single supervisory contract reaches both worlds.
20
+
21
+ Cross-language interop is real and intended:
22
+
23
+ - An audit log written by the Python implementation can be read and verified by the TypeScript implementation, and vice versa.
24
+ - A `permissions.yaml` is honored identically by both.
25
+ - A gate callback URL hosted by one can be invoked by the other.
26
+ - An `estop` triggered in one produces an audit event identical in structure to one triggered in the other.
27
+
28
+ ## What's included
29
+
30
+ The library bundles three concentric layers. Each is independently usable; together they form the canonical supervisor.
31
+
32
+ **Trust foundation** (v0.1 – v0.7):
33
+
34
+ 1. **Audit log** — hash-chained JSONL, optionally ed25519-signed. Every tool call gets a structured record. `guardian-verify` CLI confirms chain + signature integrity.
35
+ 2. **Tool-permission policy** — HMAC-signed YAML policy with `once`/`session`/`forever`/`banned` scopes and glob-matched tool names. Model-aware `when` clauses (`model.provider`, `model.id`, `attribution_path`).
36
+ 3. **HITL approval gate** — four reference adapters: CLI prompt, async webhook, programmatic callback, LiveKit data channel. Custom `GateOptionSet` lets consumers define their own button sets.
37
+ 4. **Emergency stop** — `EStopLocal` for single-process deployments, `EStopHub` middleware + poller for hub-coordinated deployments (HTTP 423 Locked).
38
+
39
+ **Runtime safety layer** (v0.8 – v0.9):
40
+
41
+ 5. **External chain attestation** ([SPEC §11](https://github.com/flowdot-llc/guardian-agent/blob/main/SPEC.md#11-external-chain-attestation-v030)) — periodically publish chain heads to an external append-only store. Closes the "compromised runtime forges its own log" gap. Reference adapters: `httpAttestor`, `nullAttestor`. Fail-soft on attestor outage.
42
+ 6. **Honeytokens** ([SPEC §12](https://github.com/flowdot-llc/guardian-agent/blob/main/SPEC.md#12-honeytokens-v030)) — consumer-supplied value patterns + phantom tool names. Zero false positives by construction. Library ships **no default tokens**.
43
+ 7. **Capability tags + Yellow-line tripwires** ([SPEC §13](https://github.com/flowdot-llc/guardian-agent/blob/main/SPEC.md#13-capability-tagging--tripwires-v030)) — tag tools with classes (`credential`, `network-egress`, `write`, ...) and define combination rules. v0.x ships Yellow-only (audit-row, no behavior change); Red-line auto-stop ships after real-surface telemetry calibrates thresholds.
44
+ 8. **Per-capability rate limits** ([SPEC §14](https://github.com/flowdot-llc/guardian-agent/blob/main/SPEC.md#14-per-capability-rate-limits-v030)) — `MultiRateLimiter` with conservative defaults (credential=2/s, delete=1/s, network-egress=5/s).
45
+ 9. **Two-key operator authorization** ([SPEC §15](https://github.com/flowdot-llc/guardian-agent/blob/main/SPEC.md#15-two-key-operator-authorization-v040)) — suspend dispatch pending fresh operator confirmation. Library defines the suspend/resume contract; consumers wire the transport.
46
+ 10. **Dead-man's heartbeat** ([SPEC §16](https://github.com/flowdot-llc/guardian-agent/blob/main/SPEC.md#16-dead-mans-heartbeat-v040)) — soft warn + hard E-stop on missed liveness signals. Opt-in (default OFF).
47
+
48
+ **Offline analysis tools** (v0.10):
49
+
50
+ 11. **`guardian-baseline`** ([SPEC §17](https://github.com/flowdot-llc/guardian-agent/blob/main/SPEC.md#17-behavioral-baselines-offline-v050)) — descriptive statistics on audit streams. `--check` flags σ-deviations. **Reports only; not a runtime tripwire.**
51
+ 12. **`guardian-correlator`** ([SPEC §18](https://github.com/flowdot-llc/guardian-agent/blob/main/SPEC.md#18-cross-surface-correlation-offline-v050)) — overlapping sessions + args-hash collisions + sequence-similarity matches across multiple audit logs for the same agent_id.
52
+
53
+ ---
54
+
55
+ ## Demos
56
+
57
+ Three minimal demos show the supervisor enforcing a single primitive end-to-end. Each one is a deterministic `tsx` script — anyone with this repo can reproduce these on their machine by cloning and running `npm install && npm run demo:N`.
58
+
59
+ ### Demo 1 — Tamper-evident audit log
60
+
61
+ Hash-chained + ed25519-signed audit records detect any post-hoc edit, down to a single byte. ([`examples/demo/demo-1-tamper.ts`](./examples/demo/demo-1-tamper.ts))
62
+
63
+ ![Tamper-evident audit log](./examples/demo/demo-1-tamper.gif)
64
+
65
+ ### Demo 2 — HITL approval gate
66
+
67
+ A tool tagged `requiresOperatorConfirmation: true` suspends dispatch and asks a configured `operatorGate` for a decision. Denial means the tool body never executes. ([`examples/demo/demo-2-gate.ts`](./examples/demo/demo-2-gate.ts))
68
+
69
+ ![HITL approval gate](./examples/demo/demo-2-gate.gif)
70
+
71
+ ### Demo 3 — Honeytoken catches exfiltration
72
+
73
+ Planted tokens that never appear in real workflows. Any tool call whose args contain one is, by construction, an attack. Hit triggers `x_honeytoken_triggered` + emergency-stop, and the E-stop is sticky — subsequent calls also throw. ([`examples/demo/demo-3-honeytoken.ts`](./examples/demo/demo-3-honeytoken.ts))
74
+
75
+ ![Honeytoken catches exfiltration](./examples/demo/demo-3-honeytoken.gif)
76
+
77
+ Run them yourself:
78
+
79
+ ```bash
80
+ npm install
81
+ npm run demo:1 # tamper-evident audit log
82
+ npm run demo:2 # HITL approval gate
83
+ npm run demo:3 # honeytoken catches exfiltration
84
+ ```
85
+
86
+ ---
87
+
88
+ ## Quickstart
89
+
90
+ ```typescript
91
+ import {
92
+ AuditLogWriter,
93
+ EStopLocal,
94
+ GuardianRuntime,
95
+ } from '@flowdot.ai/guardian-agent';
96
+
97
+ const audit = new AuditLogWriter({
98
+ path: './audit.jsonl',
99
+ agentId: 'agent_demo',
100
+ sessionId: 'sess_quickstart',
101
+ });
102
+ const estop = new EStopLocal({ audit });
103
+ const runtime = new GuardianRuntime({
104
+ agentId: 'agent_demo',
105
+ sessionId: 'sess_quickstart',
106
+ audit,
107
+ estop,
108
+ });
109
+
110
+ // Wrap any tool function — MCP, LangChain.js, native async fn:
111
+ const listAccounts = runtime.tool(
112
+ async (broker: string) => [
113
+ { id: 'acct_001', broker, balanceUsd: 12_345.67 },
114
+ ],
115
+ { name: 'list_accounts', capabilities: ['read'] },
116
+ );
117
+
118
+ // Your agent code calls these as normal. The runtime intercepts every call,
119
+ // records tool_call → policy_check → tool_result in the audit log.
120
+ const accounts = await listAccounts('schwab');
121
+
122
+ // Hit the kill switch from anywhere — another async context, a signal, an
123
+ // HTTP endpoint:
124
+ await estop.press({ reason: 'operator manual halt', initiator: 'operator' });
125
+
126
+ // Clean shutdown — flushes audit, attestation if configured:
127
+ await runtime.close();
128
+ ```
129
+
130
+ ### Adding the v0.8 safety layer
131
+
132
+ ```typescript
133
+ import {
134
+ AuditLogWriter,
135
+ EStopLocal,
136
+ GuardianRuntime,
137
+ httpAttestor,
138
+ defineHoneytokenSet,
139
+ } from '@flowdot.ai/guardian-agent';
140
+
141
+ const audit = new AuditLogWriter({
142
+ path: './audit.jsonl',
143
+ agentId: 'agent_demo',
144
+ sessionId: 'sess_quickstart',
145
+ // v0.8: external attestation
146
+ attestor: httpAttestor({ url: 'https://attestor.example/v1/heads' }),
147
+ attestEvery: 100,
148
+ });
149
+ const estop = new EStopLocal({ audit });
150
+ const runtime = new GuardianRuntime({
151
+ agentId: 'agent_demo',
152
+ sessionId: 'sess_quickstart',
153
+ audit,
154
+ estop,
155
+ // v0.8: honeytokens
156
+ honeytokens: defineHoneytokenSet('production', [
157
+ { id: 'fake-aws', pattern: /AKIA[0-9A-Z]{16}/ },
158
+ { id: 'recovery-key', value: 'fd_recovery_canary_REPLACE_ME' },
159
+ ], ['delete_account_unsafe']),
160
+ // v0.8: capability rules (Yellow-only)
161
+ capabilityRules: [
162
+ {
163
+ id: 'exfil-shape',
164
+ combination: ['credential', 'network-egress', 'write'],
165
+ window_ms: 60_000,
166
+ level: 'yellow',
167
+ },
168
+ ],
169
+ });
170
+ ```
171
+
172
+ ### v0.9: operator confirmation + heartbeat
173
+
174
+ ```typescript
175
+ import {
176
+ GuardianRuntime,
177
+ callbackOperatorGate,
178
+ HeartbeatMonitor,
179
+ } from '@flowdot.ai/guardian-agent';
180
+
181
+ const runtime = new GuardianRuntime({
182
+ agentId: 'agent_demo',
183
+ sessionId: 'sess_quickstart',
184
+ audit,
185
+ estop,
186
+ operatorGate: callbackOperatorGate(async (req) => {
187
+ // Show req to a real human (UI modal, IPC, webhook) and return their decision.
188
+ const approved = await operatorUI.prompt(req);
189
+ return { decision: approved ? 'approved' : 'denied', operator_id: 'alice' };
190
+ }),
191
+ operatorTimeoutMs: 5 * 60_000,
192
+ });
193
+
194
+ const sensitiveTool = runtime.tool(
195
+ async () => doDangerousThing(),
196
+ {
197
+ name: 'wire_transfer',
198
+ capabilities: ['network-egress', 'credential'],
199
+ requiresOperatorConfirmation: true,
200
+ operatorConfirmationReason: 'sensitive_action',
201
+ },
202
+ );
203
+
204
+ // Heartbeat — opt-in. Surface MUST call heartbeat() from its main loop.
205
+ const heartbeat = new HeartbeatMonitor({
206
+ softMs: 30_000,
207
+ hardMs: 90_000,
208
+ audit,
209
+ estop,
210
+ });
211
+ heartbeat.start();
212
+ setInterval(() => heartbeat.heartbeat(), 10_000);
213
+ ```
214
+
215
+ ### Offline analysis
216
+
217
+ ```bash
218
+ # Produce a per-agent_id statistical baseline
219
+ node dist/cli/guardian-baseline.js ~/.flowdot/audit/cli.jsonl
220
+
221
+ # Check a new session against the saved baseline
222
+ node dist/cli/guardian-baseline.js ~/.flowdot/audit/cli.jsonl --check --sigma 3
223
+
224
+ # Cross-surface correlation
225
+ node dist/cli/guardian-correlator.js \
226
+ ~/.flowdot/audit/cli.jsonl:cli \
227
+ ~/.flowdot/audit/mcp.jsonl:mcp \
228
+ --out ~/.flowdot/audit/correlations.jsonl
229
+ ```
230
+
231
+ See [`examples/quickstart.ts`](./examples/quickstart.ts) for a runnable version.
232
+
233
+ ## What it is NOT
234
+
235
+ It is deliberately small. Not an agent harness. Not a platform. Not a workflow builder. Not an observability dashboard. Not a model evaluation suite. It is the supervisor primitive only.
236
+
237
+ Some things the library deliberately does NOT do:
238
+
239
+ - **Ship default honeytokens.** Library shipping plausible-looking fake credentials gets picked up by secret scanners + creates support load. Consumers register their own.
240
+ - **Promote Red-line capability rules without telemetry.** Yellow-only until real-surface data shows zero organic fires.
241
+ - **Use baselines as runtime tripwires.** Statistical anomaly detection is descriptive output, not a gate. Operator decides what to do.
242
+ - **Reason about agent intent.** Every primitive is a deterministic predicate over inputs.
243
+
244
+ ## Relationship to FlowDot
245
+
246
+ FlowDot's commercial platform — hub, CLI, native Electron app, mobile, MCP server — uses this library directly. FlowDot's `flowdot-cli` and `mcp-server` supervisors are thin per-surface glue around the library's `GuardianRuntime` + `AuditLogWriter` + `EStopLocal`. The runtime-safety layer (attestation / honeytokens / capability tripwires / two-key / heartbeat) is wired through both surfaces.
247
+
248
+ The library itself is independent. Other Node-shaped agent projects can adopt the same supervisor primitives without depending on FlowDot's commercial stack.
249
+
250
+ ## Project status & roadmap
251
+
252
+ Pre-alpha. Releases track the Python implementation milestone-for-milestone:
253
+
254
+ - **v0.1 – v0.7** ✅ Audit log + signatures + policy + gates + estop + model-aware policy.
255
+ - **v0.8** ✅ External attestation, honeytokens, capability tags + Yellow-line, per-capability rate limits.
256
+ - **v0.9** ✅ Two-key operator auth, dead-man's heartbeat.
257
+ - **v0.10** ✅ Offline `guardian-baseline` + `guardian-correlator` tools.
258
+ - **v0.11+** — Red-line capability auto-stop (after Yellow telemetry calibration). Python port. Cross-language conformance corpus.
259
+ - **v1.0** — Stable API, conformance suite in both languages, at least one production deployment outside FlowDot, published red-team study.
260
+
261
+ Full plan: [ROADMAP.md](./ROADMAP.md). Canonical spec: [SPEC.md](https://github.com/flowdot-llc/guardian-agent/blob/main/SPEC.md).
262
+
263
+ ## Verification + testing posture
264
+
265
+ - **539 tests passing, 100% line + branch + function coverage** on the library.
266
+ - **Negative-corpus harness** replays real production audit logs (`~/.flowdot/audit/{cli,mcp}.jsonl`) through every safety detector at default thresholds; required outcome is zero false positives, and the bar is met.
267
+ - **No false E-stops, ever** is a hard rule. Any mechanism that could E-stop a session ships with thresholds calibrated against real-workload data.
268
+
269
+ ## License
270
+
271
+ AGPL-3.0-or-later. See [LICENSE](./LICENSE).
272
+
273
+ **Dual licensing.** FlowDot LLC, as sole copyright holder of this code, also licenses it under proprietary terms for use inside its own commercial products (`@flowdot.ai/cli`, `@flowdot.ai/mcp-server`, etc.). This is the standard open-core arrangement and does not affect downstream users — your obligations under AGPL-3.0 are exactly as written in [LICENSE](./LICENSE). If you want a commercial license for your own (non-FlowDot) use, contact `licensing@flowdot.ai`.
274
+
275
+ ## Citation
276
+
277
+ ```
278
+ Mousseau, E. (2026). @flowdot.ai/guardian-agent: TypeScript reference
279
+ implementation of the guardian-agent spec. v0.10.
280
+ https://github.com/flowdot-llc/guardian-agent-ts
281
+ ```
package/ROADMAP.md ADDED
@@ -0,0 +1,109 @@
1
+ # @flowdot.ai/guardian-agent — roadmap
2
+
3
+ **Last updated**: 2026-05-14
4
+
5
+ This package tracks the Python reference implementation milestone-for-milestone. The spec at [`flowdot-llc/guardian-agent/SPEC.md`](https://github.com/flowdot-llc/guardian-agent/blob/main/SPEC.md) is the canonical contract for both.
6
+
7
+ ## v0.1.0 — Package skeleton and audit log ✅
8
+
9
+ - [x] Package scaffolding: `package.json`, `tsconfig.json`, AGPL-3.0 license, README.
10
+ - [x] Public type surface matching the spec (`GuardianRuntime`, `Policy`, `GateRequest`, `GateResponse`, `ModelAttribution`).
11
+ - [x] JSONL audit log writer with hash chain.
12
+ - [x] `runtime.tool(fn, opts)` wrapper that records `tool_call` + `tool_result` events.
13
+ - [x] Quickstart example.
14
+ - [x] `vitest` suite exercising every record kind defined in spec §2.4.
15
+
16
+ ## v0.2.0 — Tool-permission scoping ✅
17
+
18
+ - [x] YAML policy loader matching spec §3.
19
+ - [x] Wildcard tool-name matching with specificity rules.
20
+ - [x] `policy_check` event emission.
21
+ - [x] Resolution order (banned > forever > session > once > default).
22
+
23
+ ## v0.3.0 — HITL approval gate ✅
24
+
25
+ - [x] `cliApprovalGate` — synchronous-feeling stdin prompt.
26
+ - [x] `asyncCallbackGate(url)` — POSTs `GateRequest`, awaits JSON response.
27
+ - [x] `programmaticGate(handler)` — async handler.
28
+ - [x] `dataChannelGate` — LiveKit-shaped wire frames.
29
+ - [x] `allow_session` / `always_allow` semantics with policy file persistence.
30
+
31
+ ## v0.4.0 — Emergency-stop ✅
32
+
33
+ - [x] `EStopLocal` API + audit emission.
34
+ - [x] `EStopHub` adapter + middleware (HTTP 423 Locked).
35
+ - [x] `EStopPoller` pull-based safety net.
36
+ - [x] `AbortController`-style cross-async halt via `EStopLocal.abortSignal`.
37
+ - [x] `GuardianHaltedError` class; audit log flush on halt.
38
+
39
+ ## v0.5.0 — Signed audit logs ✅
40
+
41
+ - [x] ed25519 via Node's `crypto`.
42
+ - [x] `guardian-verify` CLI for chain + signature integrity.
43
+ - [x] Recovery hook on abnormal-shutdown re-open (`onTipRecovered` + `x_session_recovered`).
44
+
45
+ ## v0.6.0 — Model-aware policy ✅
46
+
47
+ - [x] `PolicyWhen.model.provider` + `model.id` glob clauses (SPEC §3 open question resolved).
48
+ - [x] `ModelAttribution` carried through the audit pipeline.
49
+
50
+ ## v0.7.0 — Attribution-path policy + custom gate options ✅
51
+
52
+ - [x] `ModelAttribution` extended with `surface` + `aggregator` for the canonical chain `surface/aggregator/provider/id`.
53
+ - [x] `PolicyWhen.attribution_path` — flat-glob matcher (`*` matches `/`).
54
+ - [x] Custom `GateOptionSet` system (FLOWDOT_FIVE + CLASSIC_FOUR defaults + `defineGateOptionSet()`).
55
+
56
+ ## v0.8.0 — Runtime safety foundation ✅
57
+
58
+ - [x] **External chain attestation** (SPEC §11) — `Attestor` interface, `httpAttestor` + `nullAttestor` reference adapters, fail-soft `x_chain_attested` / `x_chain_attestation_failed`.
59
+ - [x] **Honeytokens** (SPEC §12) — value + phantom-tool matchers; zero-default-tokens by design.
60
+ - [x] **Capability tags + Yellow-line tripwires** (SPEC §13) — canonical capability classes, `CapabilityWindow` sliding-window evaluator, audit-only Yellow events.
61
+ - [x] **Per-capability rate limits** (SPEC §14) — `MultiRateLimiter` with `DEFAULT_BUCKETS` (credential=2/s, delete=1/s, etc.).
62
+
63
+ ## v0.9.0 — Operator gates ✅
64
+
65
+ - [x] **Two-key operator authorization** (SPEC §15) — `OperatorConfirmationGate` interface, `callbackOperatorGate` + `denyAllOperatorGate` reference adapters, `gate_id` correlation across pending/approved/denied rows, timeout-as-denied.
66
+ - [x] **Dead-man's heartbeat** (SPEC §16) — `HeartbeatMonitor` with soft + hard windows, opt-in (default OFF), `x_heartbeat_warning` + `estop_press { reason: 'heartbeat_missed' }`.
67
+
68
+ ## v0.10.0 — Offline analysis tools ✅
69
+
70
+ - [x] **`guardian-baseline` CLI** (SPEC §17) — per-agent_id statistical profile + `--check` σ-deviation reports. Not a runtime tripwire.
71
+ - [x] **`guardian-correlator` CLI** (SPEC §18) — overlapping sessions + args-hash collisions + sequence similarity, writes `x_cross_surface_match` JSONL to its own log.
72
+
73
+ ## v0.11+ — Red-line + Python port (next)
74
+
75
+ - [ ] **Red-line capability rules** (SPEC §13.3) — promotion path from Yellow → Red after demonstrated zero organic fires in real-surface telemetry. Auto-presses EStop on fire.
76
+ - [ ] **Python port** — faithful translation of every primitive to `guardian-agent` (Python). Same SPEC, same JSON corpus.
77
+ - [ ] **Cross-language conformance corpus** — shared test fixtures both implementations must round-trip.
78
+ - [ ] **Soak harness** — long-running real-workload replay producing the Yellow telemetry the Red-line promotion needs.
79
+
80
+ ## v1.0.0 — Stable
81
+
82
+ Same exit criteria as Python v1.0.0:
83
+ - [ ] No breaking spec changes for 90 days.
84
+ - [ ] Conformance test suite passes in both languages.
85
+ - [ ] At least one production deployment outside FlowDot.
86
+ - [ ] Published red-team study citing this implementation.
87
+
88
+ ## Non-goals through v1.0
89
+
90
+ - A web UI.
91
+ - An HTTP server. The library exposes types and adapter callables; you bring your HTTP layer.
92
+ - Bun/Deno-specific optimizations. Targeting Node 20+ LTS first.
93
+ - Becoming an agent framework. Composes with LangChain.js, MCP clients, AutoGen-TS, native async fns.
94
+ - Default honeytokens. Library never ships plausible-looking decoys; consumers register their own.
95
+ - A baseline-as-runtime-tripwire. Statistical profiles are descriptive reports, not gates.
96
+
97
+ ## Sync with Python implementation
98
+
99
+ The two repos release in lockstep when possible. If one ships a feature ahead of the other:
100
+
101
+ - **Spec changes ship in the [Python repo](https://github.com/flowdot-llc/guardian-agent) first**, because that's where SPEC.md lives. The TS repo follows.
102
+ - **Bug fixes can ship independently.**
103
+ - **Conformance test fixtures are shared.** Both implementations run the same JSON test corpus from the spec repo.
104
+
105
+ ## Test counts (current)
106
+
107
+ - guardian-agent-ts: **535/535** at **100% line + branch + function coverage**.
108
+ - FlowDot surface integrations: mcp-server **153/153**, flowdot-cli **666/666**.
109
+ - Negative-corpus harness (real `~/.flowdot/audit/{cli,mcp}.jsonl` replay) — zero false positives on every v0.8-v0.10 detector at default thresholds.
@@ -0,0 +1,102 @@
1
+ /**
2
+ * External chain attestation. SPEC §2.7 (v0.3.0+).
3
+ *
4
+ * Why this exists: the local audit log is hash-chained + ed25519-signed, but
5
+ * the writer's signing key lives on the same machine as the writer. If the
6
+ * runtime is fully compromised, an attacker can sign a fabricated chain just
7
+ * as easily as the legitimate writer. Attestation closes that gap by
8
+ * periodically publishing the current chain head + its signature to an
9
+ * external append-only store the local process cannot rewrite. A later
10
+ * verifier can cross-check the local chain against the external receipts;
11
+ * any divergence indicates tamper.
12
+ *
13
+ * The library defines the `Attestor` interface + a reference HTTP adapter.
14
+ * Production deployments may use S3 with object-lock + versioning, a
15
+ * Sigstore Rekor transparency log, or a second-party receiver. Library
16
+ * never assumes a specific backend.
17
+ *
18
+ * Failure mode: attestor errors are NEVER fatal. A failed attestation is
19
+ * itself an audit row (`x_chain_attestation_failed`). The supervisor
20
+ * continues. An adversary who can DoS the attestation endpoint cannot use
21
+ * that to halt the agent's session.
22
+ */
23
+ import type { AuditRecord } from '../types.js';
24
+ /**
25
+ * Payload sent to the attestor for one attestation event. The `head` is the
26
+ * hash of the most-recently-appended record (NOT a synthesized commitment).
27
+ * `signature` is the signature of that record. `recordCount` is the total
28
+ * number of records appended to the chain in this session up to and
29
+ * including the head record.
30
+ */
31
+ export interface AttestationPayload {
32
+ /** Agent id, mirrors the audit record's `agent_id`. */
33
+ agentId: string;
34
+ /** Session id, mirrors the audit record's `session_id`. */
35
+ sessionId: string;
36
+ /** `sha256:<hex>` of the canonical-JSON of the head record. */
37
+ head: string;
38
+ /** Head record's `ed25519:<base64url>` signature (when signing is enabled). */
39
+ signature: string | null;
40
+ /** Total records appended in this session through the head. */
41
+ recordCount: number;
42
+ /** ISO-8601 timestamp at which the attestation was emitted. */
43
+ ts: string;
44
+ /** Schema version of the payload itself; bumped on incompatible changes. */
45
+ v: '1';
46
+ }
47
+ /**
48
+ * Receipt the attestor MAY return. When provided, the receipt id is recorded
49
+ * on the local `x_chain_attested` audit row, letting verifiers correlate
50
+ * external receipts with local chain heads.
51
+ */
52
+ export interface AttestationReceipt {
53
+ /** Attestor-assigned id (URL fragment, Rekor log index, S3 version id...). */
54
+ receiptId: string;
55
+ /** Optional URL where the receipt can be inspected. */
56
+ url?: string;
57
+ }
58
+ /**
59
+ * The contract a consumer implements (or wires from a reference adapter).
60
+ * One method, takes a payload, returns a receipt or throws.
61
+ */
62
+ export interface Attestor {
63
+ /**
64
+ * Publish an attestation. Implementations MUST NOT mutate `payload`.
65
+ * Implementations MAY return synchronously or asynchronously.
66
+ *
67
+ * Throwing here is an expected failure mode; callers (AuditLogWriter)
68
+ * catch and convert to `x_chain_attestation_failed` audit rows.
69
+ */
70
+ publish(payload: AttestationPayload): Promise<AttestationReceipt> | AttestationReceipt;
71
+ }
72
+ export interface HttpAttestorOptions {
73
+ /** Endpoint URL. The attestor POSTs the JSON payload here. */
74
+ url: string;
75
+ /** Optional headers (auth bearer, content-type override, etc.). */
76
+ headers?: Record<string, string>;
77
+ /** Request timeout in ms. Default 5000. */
78
+ timeoutMs?: number;
79
+ /** Optional fetch implementation override (testing). */
80
+ fetchImpl?: typeof fetch;
81
+ }
82
+ /**
83
+ * Reference HTTP attestor: POSTs the payload as JSON, expects a JSON
84
+ * `{ receiptId, url? }` response. 2xx → success; anything else → throws.
85
+ *
86
+ * This adapter is INTENTIONALLY MINIMAL. Production deployments will want
87
+ * retries, auth refresh, content-addressed bodies, etc. — those belong in
88
+ * the consumer's adapter, not the library.
89
+ */
90
+ export declare function httpAttestor(options: HttpAttestorOptions): Attestor;
91
+ /**
92
+ * No-op attestor that returns synthetic receipts. Use in tests, or when a
93
+ * consumer wants the supervisor to log `x_chain_attested` rows for audit
94
+ * shape parity without actually publishing externally.
95
+ */
96
+ export declare function nullAttestor(): Attestor;
97
+ /**
98
+ * Build the canonical payload from a head record + the running record count.
99
+ * Pure: same inputs → same payload. Exposed for tests.
100
+ */
101
+ export declare function payloadFromRecord(record: AuditRecord, recordCount: number, headHash: string): AttestationPayload;
102
+ //# sourceMappingURL=attestor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attestor.d.ts","sourceRoot":"","sources":["../../src/audit/attestor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,EAAE,EAAE,MAAM,CAAC;IACX,4EAA4E;IAC5E,CAAC,EAAE,GAAG,CAAC;CACR;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,CAAC;CACxF;AAMD,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,GAAG,EAAE,MAAM,CAAC;IACZ,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,QAAQ,CAkCnE;AAMD;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,QAAQ,CAQvC;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,kBAAkB,CAUpB"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * External chain attestation. SPEC §2.7 (v0.3.0+).
3
+ *
4
+ * Why this exists: the local audit log is hash-chained + ed25519-signed, but
5
+ * the writer's signing key lives on the same machine as the writer. If the
6
+ * runtime is fully compromised, an attacker can sign a fabricated chain just
7
+ * as easily as the legitimate writer. Attestation closes that gap by
8
+ * periodically publishing the current chain head + its signature to an
9
+ * external append-only store the local process cannot rewrite. A later
10
+ * verifier can cross-check the local chain against the external receipts;
11
+ * any divergence indicates tamper.
12
+ *
13
+ * The library defines the `Attestor` interface + a reference HTTP adapter.
14
+ * Production deployments may use S3 with object-lock + versioning, a
15
+ * Sigstore Rekor transparency log, or a second-party receiver. Library
16
+ * never assumes a specific backend.
17
+ *
18
+ * Failure mode: attestor errors are NEVER fatal. A failed attestation is
19
+ * itself an audit row (`x_chain_attestation_failed`). The supervisor
20
+ * continues. An adversary who can DoS the attestation endpoint cannot use
21
+ * that to halt the agent's session.
22
+ */
23
+ /**
24
+ * Reference HTTP attestor: POSTs the payload as JSON, expects a JSON
25
+ * `{ receiptId, url? }` response. 2xx → success; anything else → throws.
26
+ *
27
+ * This adapter is INTENTIONALLY MINIMAL. Production deployments will want
28
+ * retries, auth refresh, content-addressed bodies, etc. — those belong in
29
+ * the consumer's adapter, not the library.
30
+ */
31
+ export function httpAttestor(options) {
32
+ const url = options.url;
33
+ const headers = options.headers ?? {};
34
+ const timeoutMs = options.timeoutMs ?? 5000;
35
+ const fetchImpl = options.fetchImpl ?? globalThis.fetch;
36
+ if (!fetchImpl) {
37
+ throw new Error('httpAttestor: global fetch is not available; supply fetchImpl');
38
+ }
39
+ return {
40
+ async publish(payload) {
41
+ const controller = new AbortController();
42
+ const t = setTimeout(() => controller.abort(), timeoutMs);
43
+ try {
44
+ const res = await fetchImpl(url, {
45
+ method: 'POST',
46
+ headers: { 'content-type': 'application/json', ...headers },
47
+ body: JSON.stringify(payload),
48
+ signal: controller.signal,
49
+ });
50
+ if (!res.ok) {
51
+ throw new Error(`httpAttestor: ${res.status} ${res.statusText}`);
52
+ }
53
+ const body = (await res.json());
54
+ if (!body.receiptId || typeof body.receiptId !== 'string') {
55
+ throw new Error('httpAttestor: response missing receiptId');
56
+ }
57
+ const r = { receiptId: body.receiptId };
58
+ if (typeof body.url === 'string')
59
+ r.url = body.url;
60
+ return r;
61
+ }
62
+ finally {
63
+ clearTimeout(t);
64
+ }
65
+ },
66
+ };
67
+ }
68
+ // ============================================================================
69
+ // nullAttestor — for tests and explicit-disable scenarios
70
+ // ============================================================================
71
+ /**
72
+ * No-op attestor that returns synthetic receipts. Use in tests, or when a
73
+ * consumer wants the supervisor to log `x_chain_attested` rows for audit
74
+ * shape parity without actually publishing externally.
75
+ */
76
+ export function nullAttestor() {
77
+ let n = 0;
78
+ return {
79
+ publish() {
80
+ n += 1;
81
+ return { receiptId: `null-${n}` };
82
+ },
83
+ };
84
+ }
85
+ // ============================================================================
86
+ // Helper: build a payload from a record + count.
87
+ // ============================================================================
88
+ /**
89
+ * Build the canonical payload from a head record + the running record count.
90
+ * Pure: same inputs → same payload. Exposed for tests.
91
+ */
92
+ export function payloadFromRecord(record, recordCount, headHash) {
93
+ return {
94
+ agentId: record.agent_id,
95
+ sessionId: record.session_id,
96
+ head: headHash,
97
+ signature: record.signature ?? null,
98
+ recordCount,
99
+ ts: new Date().toISOString(),
100
+ v: '1',
101
+ };
102
+ }
103
+ //# sourceMappingURL=attestor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attestor.js","sourceRoot":"","sources":["../../src/audit/attestor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAsEH;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,OAA4B;IACvD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IACxB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;IAC5C,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC;IACxD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IACD,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,OAA2B;YACvC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YACzC,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;YAC1D,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;oBAC/B,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,OAAO,EAAE;oBAC3D,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;oBAC7B,MAAM,EAAE,UAAU,CAAC,MAAM;iBAC1B,CAAC,CAAC;gBACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;oBACZ,MAAM,IAAI,KAAK,CAAC,iBAAiB,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;gBACnE,CAAC;gBACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAgC,CAAC;gBAC/D,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;oBAC1D,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;gBAC9D,CAAC;gBACD,MAAM,CAAC,GAAuB,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;gBAC5D,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ;oBAAE,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;gBACnD,OAAO,CAAC,CAAC;YACX,CAAC;oBAAS,CAAC;gBACT,YAAY,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,0DAA0D;AAC1D,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO;QACL,OAAO;YACL,CAAC,IAAI,CAAC,CAAC;YACP,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,iDAAiD;AACjD,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAmB,EACnB,WAAmB,EACnB,QAAgB;IAEhB,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,QAAQ;QACxB,SAAS,EAAE,MAAM,CAAC,UAAU;QAC5B,IAAI,EAAE,QAAQ;QACd,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,IAAI;QACnC,WAAW;QACX,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,CAAC,EAAE,GAAG;KACP,CAAC;AACJ,CAAC"}