@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
@@ -0,0 +1,217 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * guardian-correlator — offline cross-surface correlation CLI. SPEC §14
4
+ * (v0.5.0+).
5
+ *
6
+ * Reads two or more audit JSONL files for the same `agent_id` and reports
7
+ * patterns that span surfaces: overlapping sessions, identical-args
8
+ * collisions, similar tool-frequency sequences. Writes findings as
9
+ * `x_cross_surface_match` JSONL to its own log (NEVER mutates source
10
+ * files).
11
+ *
12
+ * Usage:
13
+ * guardian-correlator <file1.jsonl>:<surface1> <file2.jsonl>:<surface2> [...]
14
+ * guardian-correlator <file1>:<surface1> <file2>:<surface2> --out <correlations.jsonl>
15
+ * guardian-correlator <files...> --threshold <0..1> # cosine threshold (default 0.9)
16
+ * guardian-correlator <files...> --window-ms <N> # args-hash window (default 60000)
17
+ *
18
+ * Exit codes:
19
+ * 0 — success (matches written or none found; either way, exit 0)
20
+ * 1 — IO error / bad JSONL
21
+ * 2 — usage error
22
+ *
23
+ * Not a runtime tripwire. Output is for operator review.
24
+ */
25
+ import { appendFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
26
+ import { homedir } from 'node:os';
27
+ import { dirname, join } from 'node:path';
28
+ import { AuditLogReader } from '../audit/reader.js';
29
+ import { correlate, } from '../audit/correlation.js';
30
+ export function parseArgs(argv) {
31
+ const args = argv.slice();
32
+ const sources = [];
33
+ let out;
34
+ let threshold = 0.9;
35
+ let argsHashWindowMs = 60_000;
36
+ let similarityWindowMs = 600_000;
37
+ let similarityMinCalls = 5;
38
+ while (args.length > 0) {
39
+ const a = args.shift();
40
+ /* c8 ignore next */
41
+ if (a === undefined)
42
+ break;
43
+ if (a === '--out') {
44
+ out = args.shift();
45
+ if (out === undefined)
46
+ return null;
47
+ }
48
+ else if (a === '--threshold') {
49
+ const v = args.shift();
50
+ if (v === undefined)
51
+ return null;
52
+ const n = Number(v);
53
+ if (!Number.isFinite(n) || n < 0 || n > 1)
54
+ return null;
55
+ threshold = n;
56
+ }
57
+ else if (a === '--window-ms') {
58
+ const v = args.shift();
59
+ if (v === undefined)
60
+ return null;
61
+ const n = Number(v);
62
+ if (!Number.isFinite(n) || n <= 0)
63
+ return null;
64
+ argsHashWindowMs = n;
65
+ }
66
+ else if (a === '--similarity-window-ms') {
67
+ const v = args.shift();
68
+ if (v === undefined)
69
+ return null;
70
+ const n = Number(v);
71
+ if (!Number.isFinite(n) || n <= 0)
72
+ return null;
73
+ similarityWindowMs = n;
74
+ }
75
+ else if (a === '--similarity-min-calls') {
76
+ const v = args.shift();
77
+ if (v === undefined)
78
+ return null;
79
+ const n = Number(v);
80
+ if (!Number.isFinite(n) || n < 1)
81
+ return null;
82
+ similarityMinCalls = n;
83
+ }
84
+ else if (a.startsWith('--')) {
85
+ return null;
86
+ }
87
+ else {
88
+ // Positional: path:surface
89
+ const idx = a.lastIndexOf(':');
90
+ if (idx <= 0 || idx === a.length - 1)
91
+ return null;
92
+ const path = a.slice(0, idx);
93
+ const surface = a.slice(idx + 1);
94
+ sources.push({ path, surface });
95
+ }
96
+ }
97
+ if (sources.length < 2)
98
+ return null;
99
+ return {
100
+ sources,
101
+ out,
102
+ threshold,
103
+ argsHashWindowMs,
104
+ similarityWindowMs,
105
+ similarityMinCalls,
106
+ };
107
+ }
108
+ export function defaultCorrelationsPath() {
109
+ return process.env.FLOWDOT_CORRELATIONS_PATH ?? join(homedir(), '.flowdot', 'audit', 'correlations.jsonl');
110
+ }
111
+ async function loadSource(path, surface) {
112
+ const reader = await AuditLogReader.open(path);
113
+ try {
114
+ const records = [];
115
+ for await (const r of reader.records())
116
+ records.push(r);
117
+ return { surface, records };
118
+ }
119
+ finally {
120
+ await reader.close();
121
+ }
122
+ }
123
+ export async function runCorrelator(args) {
124
+ for (const s of args.sources) {
125
+ if (!existsSync(s.path)) {
126
+ return {
127
+ exitCode: 1,
128
+ message: `audit file not found: ${s.path}`,
129
+ matches: [],
130
+ outPath: undefined,
131
+ };
132
+ }
133
+ }
134
+ // Load all sources.
135
+ let sources;
136
+ try {
137
+ sources = await Promise.all(args.sources.map((s) => loadSource(s.path, s.surface)));
138
+ }
139
+ catch (err) {
140
+ return {
141
+ exitCode: 1,
142
+ /* c8 ignore next */
143
+ message: `failed to read audit file: ${err instanceof Error ? err.message : String(err)}`,
144
+ matches: [],
145
+ outPath: undefined,
146
+ };
147
+ }
148
+ const opts = {
149
+ argsHashWindowMs: args.argsHashWindowMs,
150
+ similarityThreshold: args.threshold,
151
+ similarityWindowMs: args.similarityWindowMs,
152
+ similarityMinCalls: args.similarityMinCalls,
153
+ };
154
+ const matches = correlate(sources, opts);
155
+ const outPath = args.out ?? defaultCorrelationsPath();
156
+ const outDir = dirname(outPath);
157
+ if (!existsSync(outDir)) {
158
+ mkdirSync(outDir, { recursive: true, mode: 0o700 });
159
+ }
160
+ // Append each match as one JSONL row with `ts` stamped at write time.
161
+ if (matches.length > 0) {
162
+ const lines = matches.map((m) => JSON.stringify({ ts: new Date().toISOString(), ...m }) + '\n').join('');
163
+ // Create the file with 0o600 if it doesn't exist; otherwise append.
164
+ if (!existsSync(outPath)) {
165
+ writeFileSync(outPath, lines, { mode: 0o600 });
166
+ }
167
+ else {
168
+ appendFileSync(outPath, lines);
169
+ }
170
+ }
171
+ return {
172
+ exitCode: 0,
173
+ message: matches.length === 0
174
+ ? `no cross-surface matches across ${sources.length} sources`
175
+ : `wrote ${matches.length} match(es) to ${outPath}`,
176
+ matches,
177
+ outPath: matches.length === 0 ? undefined : outPath,
178
+ };
179
+ }
180
+ const USAGE = `Usage:
181
+ guardian-correlator <file1>:<surface1> <file2>:<surface2> [...]
182
+ guardian-correlator <files...> [--out <correlations.jsonl>]
183
+ guardian-correlator <files...> [--threshold <0..1>] # cosine threshold (default 0.9)
184
+ guardian-correlator <files...> [--window-ms <N>] # args-hash window (default 60000)
185
+ guardian-correlator <files...> [--similarity-window-ms <N>] # session-start window (default 600000)
186
+ guardian-correlator <files...> [--similarity-min-calls <N>] # min calls per session (default 5)
187
+
188
+ Exit codes:
189
+ 0 — success (matches written or none found)
190
+ 1 — IO error / bad JSONL
191
+ 2 — usage error
192
+ `;
193
+ /* c8 ignore start */
194
+ async function main() {
195
+ const parsed = parseArgs(process.argv.slice(2));
196
+ if (!parsed) {
197
+ process.stderr.write(USAGE);
198
+ process.exit(2);
199
+ }
200
+ const result = await runCorrelator(parsed);
201
+ process.stdout.write(result.message + '\n');
202
+ if (result.exitCode !== 0) {
203
+ process.stderr.write(result.message + '\n');
204
+ }
205
+ process.exit(result.exitCode);
206
+ }
207
+ /* c8 ignore stop */
208
+ const isMain = typeof process !== 'undefined' &&
209
+ typeof process.argv !== 'undefined' &&
210
+ process.argv[1] !== undefined &&
211
+ /guardian-correlator(\.js|\.ts)?$/.test(process.argv[1]);
212
+ /* c8 ignore start */
213
+ if (isMain) {
214
+ void main();
215
+ }
216
+ /* c8 ignore stop */
217
+ //# sourceMappingURL=guardian-correlator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardian-correlator.js","sourceRoot":"","sources":["../../src/cli/guardian-correlator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * guardian-verify — log integrity verification CLI. SPEC §2.5, §2.6.
4
+ *
5
+ * Usage:
6
+ * guardian-verify <audit.jsonl> # verify hash chain
7
+ * guardian-verify <audit.jsonl> --pubkey <pem> # verify hash chain + signatures
8
+ *
9
+ * Exit codes:
10
+ * 0 — all verifications passed
11
+ * 1 — hash chain broken / signature invalid / IO error
12
+ * 2 — usage error (bad args)
13
+ */
14
+ export interface VerifyResult {
15
+ recordCount: number;
16
+ chainVerified: boolean;
17
+ signaturesVerified: boolean;
18
+ exitCode: 0 | 1 | 2;
19
+ message: string;
20
+ }
21
+ export interface VerifyArgs {
22
+ path: string | undefined;
23
+ pubkeyPath: string | undefined;
24
+ }
25
+ /** Parse argv. Returns the parsed args or null on usage error. */
26
+ export declare function parseArgs(argv: readonly string[]): VerifyArgs | null;
27
+ /** Run a verification given parsed args. */
28
+ export declare function runVerify(args: VerifyArgs): Promise<VerifyResult>;
29
+ export declare function usageString(): string;
30
+ //# sourceMappingURL=guardian-verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardian-verify.d.ts","sourceRoot":"","sources":["../../src/cli/guardian-verify.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG;AAQH,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,kEAAkE;AAClE,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,GAAG,IAAI,CAwBpE;AAED,4CAA4C;AAC5C,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CA4DvE;AAED,wBAAgB,WAAW,IAAI,MAAM,CAWpC"}
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * guardian-verify — log integrity verification CLI. SPEC §2.5, §2.6.
4
+ *
5
+ * Usage:
6
+ * guardian-verify <audit.jsonl> # verify hash chain
7
+ * guardian-verify <audit.jsonl> --pubkey <pem> # verify hash chain + signatures
8
+ *
9
+ * Exit codes:
10
+ * 0 — all verifications passed
11
+ * 1 — hash chain broken / signature invalid / IO error
12
+ * 2 — usage error (bad args)
13
+ */
14
+ import { readFileSync } from 'node:fs';
15
+ import { AuditLogReader } from '../audit/reader.js';
16
+ import { loadPublicKey } from '../audit/signature.js';
17
+ import { GuardianIntegrityError } from '../errors.js';
18
+ /** Parse argv. Returns the parsed args or null on usage error. */
19
+ export function parseArgs(argv) {
20
+ const args = argv.slice();
21
+ let path;
22
+ let pubkeyPath;
23
+ while (args.length > 0) {
24
+ const a = args.shift();
25
+ /* c8 ignore next */
26
+ if (a === undefined)
27
+ break;
28
+ if (a === '--pubkey') {
29
+ const next = args.shift();
30
+ if (next === undefined)
31
+ return null;
32
+ pubkeyPath = next;
33
+ }
34
+ else if (a === '--help' || a === '-h') {
35
+ return { path: undefined, pubkeyPath: undefined };
36
+ }
37
+ else if (a.startsWith('--')) {
38
+ return null;
39
+ }
40
+ else {
41
+ if (path !== undefined)
42
+ return null; // only one positional accepted
43
+ path = a;
44
+ }
45
+ }
46
+ return { path, pubkeyPath };
47
+ }
48
+ /** Run a verification given parsed args. */
49
+ export async function runVerify(args) {
50
+ if (!args.path) {
51
+ return {
52
+ recordCount: 0,
53
+ chainVerified: false,
54
+ signaturesVerified: false,
55
+ exitCode: 2,
56
+ message: usageString(),
57
+ };
58
+ }
59
+ const reader = await AuditLogReader.open(args.path);
60
+ try {
61
+ let chainCount = 0;
62
+ try {
63
+ chainCount = await reader.verifyChain();
64
+ }
65
+ catch (err) {
66
+ /* c8 ignore next */
67
+ const msg = err instanceof GuardianIntegrityError ? err.message : String(err);
68
+ return {
69
+ recordCount: 0,
70
+ chainVerified: false,
71
+ signaturesVerified: false,
72
+ exitCode: 1,
73
+ message: `chain verification failed: ${msg}`,
74
+ };
75
+ }
76
+ let signaturesVerified = false;
77
+ if (args.pubkeyPath) {
78
+ const pem = readFileSync(args.pubkeyPath, 'utf-8');
79
+ const pubkey = loadPublicKey(pem);
80
+ try {
81
+ await reader.verifySignatures(pubkey);
82
+ signaturesVerified = true;
83
+ }
84
+ catch (err) {
85
+ /* c8 ignore next */
86
+ const msg = err instanceof GuardianIntegrityError ? err.message : String(err);
87
+ return {
88
+ recordCount: chainCount,
89
+ chainVerified: true,
90
+ signaturesVerified: false,
91
+ exitCode: 1,
92
+ message: `signature verification failed: ${msg}`,
93
+ };
94
+ }
95
+ }
96
+ const parts = [`chain ok (${chainCount} records)`];
97
+ if (signaturesVerified)
98
+ parts.push('signatures ok');
99
+ return {
100
+ recordCount: chainCount,
101
+ chainVerified: true,
102
+ signaturesVerified,
103
+ exitCode: 0,
104
+ message: parts.join('; '),
105
+ };
106
+ }
107
+ finally {
108
+ await reader.close();
109
+ }
110
+ }
111
+ export function usageString() {
112
+ return [
113
+ 'guardian-verify — verify guardian-agent audit log integrity',
114
+ '',
115
+ 'Usage:',
116
+ ' guardian-verify <audit.jsonl> [--pubkey <pem>]',
117
+ '',
118
+ 'Options:',
119
+ ' --pubkey <pem> Path to an ed25519 public key (PEM). When supplied, signatures are verified.',
120
+ ' --help, -h Show this message.',
121
+ ].join('\n');
122
+ }
123
+ /* c8 ignore start */
124
+ async function main() {
125
+ const parsed = parseArgs(process.argv.slice(2));
126
+ if (parsed === null) {
127
+ process.stderr.write(usageString() + '\n');
128
+ process.exit(2);
129
+ }
130
+ const result = await runVerify(parsed);
131
+ if (result.exitCode === 0) {
132
+ process.stdout.write(result.message + '\n');
133
+ }
134
+ else {
135
+ process.stderr.write(result.message + '\n');
136
+ }
137
+ process.exit(result.exitCode);
138
+ }
139
+ /* c8 ignore stop */
140
+ const isMain = typeof process !== 'undefined' &&
141
+ typeof process.argv !== 'undefined' &&
142
+ process.argv[1] !== undefined &&
143
+ /guardian-verify(\.js|\.ts)?$/.test(process.argv[1]);
144
+ /* c8 ignore start */
145
+ if (isMain) {
146
+ void main();
147
+ }
148
+ /* c8 ignore stop */
149
+ //# sourceMappingURL=guardian-verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardian-verify.js","sourceRoot":"","sources":["../../src/cli/guardian-verify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Public error types.
3
+ */
4
+ /**
5
+ * Thrown inside a tool wrapper when the runtime is halted.
6
+ * SPEC §5.2.
7
+ */
8
+ export declare class GuardianHaltedError extends Error {
9
+ readonly reason: string | undefined;
10
+ readonly operatorId: string | undefined;
11
+ constructor(message: string, reason?: string, operatorId?: string);
12
+ }
13
+ /**
14
+ * Thrown for invalid configuration: malformed policy YAML, missing required
15
+ * options, contradictory rules, etc.
16
+ */
17
+ export declare class GuardianConfigError extends Error {
18
+ constructor(message: string);
19
+ }
20
+ /**
21
+ * Thrown when integrity verification fails: a broken audit-log hash chain,
22
+ * a failed HMAC on a policy file, or a bad ed25519 signature.
23
+ */
24
+ export declare class GuardianIntegrityError extends Error {
25
+ readonly detail: string | undefined;
26
+ constructor(message: string, detail?: string);
27
+ }
28
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;gBAE5B,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;CAMlE;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAED;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;gBAExB,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;CAK7C"}
package/dist/errors.js ADDED
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Public error types.
3
+ */
4
+ /**
5
+ * Thrown inside a tool wrapper when the runtime is halted.
6
+ * SPEC §5.2.
7
+ */
8
+ export class GuardianHaltedError extends Error {
9
+ reason;
10
+ operatorId;
11
+ constructor(message, reason, operatorId) {
12
+ super(message);
13
+ this.name = 'GuardianHaltedError';
14
+ this.reason = reason;
15
+ this.operatorId = operatorId;
16
+ }
17
+ }
18
+ /**
19
+ * Thrown for invalid configuration: malformed policy YAML, missing required
20
+ * options, contradictory rules, etc.
21
+ */
22
+ export class GuardianConfigError extends Error {
23
+ constructor(message) {
24
+ super(message);
25
+ this.name = 'GuardianConfigError';
26
+ }
27
+ }
28
+ /**
29
+ * Thrown when integrity verification fails: a broken audit-log hash chain,
30
+ * a failed HMAC on a policy file, or a bad ed25519 signature.
31
+ */
32
+ export class GuardianIntegrityError extends Error {
33
+ detail;
34
+ constructor(message, detail) {
35
+ super(message);
36
+ this.name = 'GuardianIntegrityError';
37
+ this.detail = detail;
38
+ }
39
+ }
40
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACnC,MAAM,CAAqB;IAC3B,UAAU,CAAqB;IAExC,YAAY,OAAe,EAAE,MAAe,EAAE,UAAmB;QAC/D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IACtC,MAAM,CAAqB;IAEpC,YAAY,OAAe,EAAE,MAAe;QAC1C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Dead-man's-switch heartbeat. SPEC §6 (v0.4.0+).
3
+ *
4
+ * For long-running surfaces (CLI daemon, MCP server's persistent session,
5
+ * Native main loop) the agent (or its harness) must call
6
+ * `monitor.heartbeat()` every N seconds. If no heartbeat arrives within
7
+ * `softMs`, an `x_heartbeat_warning` audit row is written (no behavior
8
+ * change). If still no heartbeat by `hardMs`, the configured `EStopLocal`
9
+ * is pressed with `reason: 'heartbeat_missed'`.
10
+ *
11
+ * Pure mechanism: setInterval + timestamp arithmetic. The supervisor does
12
+ * not decide whether the agent should be alive — only whether it is
13
+ * claiming to be.
14
+ *
15
+ * OPT-IN PER SURFACE. Default OFF. A surface that hasn't wired
16
+ * `heartbeat()` calls into its main loop must not enable this — that's a
17
+ * day-1 false E-stop.
18
+ */
19
+ import type { AuditLogWriter } from '../audit/writer.js';
20
+ import type { EStopLocal } from './local.js';
21
+ export interface HeartbeatMonitorOptions {
22
+ /** Audit log writer for `x_heartbeat_warning` rows. Optional. */
23
+ audit?: AuditLogWriter;
24
+ /**
25
+ * EStopLocal to press on hard miss. When omitted, hard-miss behavior is
26
+ * audit-only (mostly useful for testing the monitor itself).
27
+ */
28
+ estop?: EStopLocal;
29
+ /**
30
+ * Soft window in ms. After this many ms with no heartbeat, write
31
+ * `x_heartbeat_warning`. Must be < hardMs.
32
+ */
33
+ softMs: number;
34
+ /**
35
+ * Hard window in ms. After this many ms with no heartbeat, press the
36
+ * EStop with `reason: 'heartbeat_missed'`.
37
+ */
38
+ hardMs: number;
39
+ /**
40
+ * How often to check (ms). Default = min(softMs, hardMs) / 4, clamped
41
+ * to [50, 5000]. Smaller = tighter response; larger = lower CPU cost.
42
+ */
43
+ checkIntervalMs?: number;
44
+ /** Time source override (testing). */
45
+ now?: () => number;
46
+ /**
47
+ * setInterval override (testing). Must return a token that
48
+ * `clearIntervalFn` accepts.
49
+ */
50
+ setIntervalFn?: (cb: () => void, ms: number) => unknown;
51
+ /** clearInterval override (testing). */
52
+ clearIntervalFn?: (handle: unknown) => void;
53
+ }
54
+ /**
55
+ * State machine: idle → softMissed → hardMissed. Each transition writes
56
+ * an audit row (warning for softMissed, estop_press for hardMissed). The
57
+ * monitor stops checking once hardMissed fires; restart by constructing a
58
+ * new monitor (a new session).
59
+ */
60
+ export declare class HeartbeatMonitor {
61
+ private readonly audit;
62
+ private readonly estop;
63
+ private readonly softMs;
64
+ private readonly hardMs;
65
+ private readonly checkIntervalMs;
66
+ private readonly now;
67
+ private readonly setIntervalFn;
68
+ private readonly clearIntervalFn;
69
+ private lastBeat;
70
+ private state;
71
+ private interval;
72
+ private stopped;
73
+ constructor(options: HeartbeatMonitorOptions);
74
+ /** Start the watchdog. Idempotent. */
75
+ start(): void;
76
+ /** Stop the watchdog. Idempotent. Call from supervisor close(). */
77
+ stop(): void;
78
+ /**
79
+ * Record a heartbeat. Resets the state machine to `idle` if a soft
80
+ * warning had fired but no hard miss yet.
81
+ */
82
+ heartbeat(): void;
83
+ /** Current state (for tests + introspection). */
84
+ getState(): {
85
+ state: 'idle' | 'softMissed' | 'hardMissed';
86
+ lastBeatMs: number;
87
+ };
88
+ /**
89
+ * Public tick. Called automatically by the interval; exposed so tests can
90
+ * drive deterministically without real timers.
91
+ */
92
+ tick(): Promise<void>;
93
+ }
94
+ //# sourceMappingURL=heartbeat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../src/estop/heartbeat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,uBAAuB;IACtC,iEAAiE;IACjE,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IACxD,wCAAwC;IACxC,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CAC7C;AAED;;;;;GAKG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IACnD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA0C;IACxE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA4B;IAE5D,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAAgD;IAC7D,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,uBAAuB;IAmB5C,sCAAsC;IACtC,KAAK,IAAI,IAAI;IAQb,mEAAmE;IACnE,IAAI,IAAI,IAAI;IAQZ;;;OAGG;IACH,SAAS,IAAI,IAAI;IASjB,iDAAiD;IACjD,QAAQ,IAAI;QAAE,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,YAAY,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;IAI/E;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAuC5B"}