@catp-protocol/cli 0.7.2 → 0.7.4

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 (53) hide show
  1. package/dist/audit/durable.d.ts +68 -0
  2. package/dist/audit/durable.d.ts.map +1 -0
  3. package/dist/audit/durable.js +214 -0
  4. package/dist/audit/durable.js.map +1 -0
  5. package/dist/audit/logger.d.ts +51 -5
  6. package/dist/audit/logger.d.ts.map +1 -1
  7. package/dist/audit/logger.js +99 -20
  8. package/dist/audit/logger.js.map +1 -1
  9. package/dist/audit/paths.d.ts +11 -0
  10. package/dist/audit/paths.d.ts.map +1 -1
  11. package/dist/audit/paths.js +19 -0
  12. package/dist/audit/paths.js.map +1 -1
  13. package/dist/audit/verifier.d.ts +9 -0
  14. package/dist/audit/verifier.d.ts.map +1 -1
  15. package/dist/audit/verifier.js +70 -18
  16. package/dist/audit/verifier.js.map +1 -1
  17. package/dist/cli.js +11 -11
  18. package/dist/cli.js.map +1 -1
  19. package/dist/commands/authorization.js +6 -0
  20. package/dist/commands/authorization.js.map +1 -1
  21. package/dist/commands/log.d.ts +41 -1
  22. package/dist/commands/log.d.ts.map +1 -1
  23. package/dist/commands/log.js +82 -22
  24. package/dist/commands/log.js.map +1 -1
  25. package/dist/commands/receipt.d.ts +71 -1
  26. package/dist/commands/receipt.d.ts.map +1 -1
  27. package/dist/commands/receipt.js +344 -72
  28. package/dist/commands/receipt.js.map +1 -1
  29. package/dist/enforcement/core.d.ts +10 -4
  30. package/dist/enforcement/core.d.ts.map +1 -1
  31. package/dist/enforcement/core.js +40 -4
  32. package/dist/enforcement/core.js.map +1 -1
  33. package/dist/evidence/canonical.d.ts +22 -0
  34. package/dist/evidence/canonical.d.ts.map +1 -0
  35. package/dist/evidence/canonical.js +45 -0
  36. package/dist/evidence/canonical.js.map +1 -0
  37. package/dist/evidence/commitments.d.ts +46 -0
  38. package/dist/evidence/commitments.d.ts.map +1 -0
  39. package/dist/evidence/commitments.js +52 -0
  40. package/dist/evidence/commitments.js.map +1 -0
  41. package/dist/hook/post.d.ts +6 -0
  42. package/dist/hook/post.d.ts.map +1 -1
  43. package/dist/hook/post.js +1 -1
  44. package/dist/hook/post.js.map +1 -1
  45. package/dist/hook/pre.d.ts +6 -0
  46. package/dist/hook/pre.d.ts.map +1 -1
  47. package/dist/hook/pre.js +4 -1
  48. package/dist/hook/pre.js.map +1 -1
  49. package/dist/policy/engine.js +19 -1
  50. package/dist/policy/engine.js.map +1 -1
  51. package/dist/policy/types.d.ts +25 -2
  52. package/dist/policy/types.d.ts.map +1 -1
  53. package/package.json +1 -1
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Narrow filesystem seam used by the durable primitives. Production code binds
3
+ * this to node:fs; unit tests inject a fake to assert operation order and to
4
+ * inject failures without touching a real disk.
5
+ */
6
+ export interface DurableFs {
7
+ existsSync(path: string): boolean;
8
+ mkdirSync(path: string, opts: {
9
+ recursive: boolean;
10
+ mode: number;
11
+ }): void;
12
+ openSync(path: string, flags: string, mode: number): number;
13
+ writeSync(fd: number, buffer: Uint8Array, offset: number, length: number, position: number | null): number;
14
+ fsyncSync(fd: number): void;
15
+ closeSync(fd: number): void;
16
+ readFileSync(path: string): Buffer;
17
+ renameSync(oldPath: string, newPath: string): void;
18
+ unlinkSync(path: string): void;
19
+ }
20
+ /** Production binding of {@link DurableFs} to node:fs. */
21
+ export declare const nodeFs: DurableFs;
22
+ /**
23
+ * Create `path` (and any missing ancestors) and make the new directory entries
24
+ * durable. Missing components are collected before creation, created with
25
+ * 0o700, then fsynced from the deepest component upward followed by the
26
+ * deepest pre-existing ancestor. If `path` already exists this is a no-op.
27
+ */
28
+ export declare function ensureDirectoryDurable(path: string, fs?: DurableFs): void;
29
+ /**
30
+ * Durably append one line to a JSONL-style log file. Sequence: create parent
31
+ * directories, open append/create with 0o600, write the complete UTF-8 line
32
+ * plus exactly one newline, fsync the file, close it, and fsync the parent
33
+ * directory when the file was newly created.
34
+ */
35
+ export declare function durableAppendLine(path: string, line: string, fs?: DurableFs): void;
36
+ /**
37
+ * Durably create an empty file (and its parent directories) if it does not
38
+ * already exist: open append/create with 0o600, fsync the new file, close it,
39
+ * then fsync the parent directory. An existing file is left untouched. This is
40
+ * used to materialize the audit log so a lock manager that resolves the target
41
+ * realpath never bypasses the new-file durability path.
42
+ */
43
+ export declare function durableCreateEmptyFile(path: string, fs?: DurableFs): void;
44
+ /**
45
+ * Durably write content-addressed `bytes` to `path` via a same-directory temp
46
+ * file: create parents, write the temp with 0o600, fsync it, close, atomically
47
+ * rename onto the target, then fsync the parent directory.
48
+ *
49
+ * If the target already exists its bytes are compared: identical bytes are an
50
+ * idempotent success, differing bytes are reported as corruption. Descriptors
51
+ * are closed and the temp file removed on any failure while preserving the
52
+ * original exception.
53
+ */
54
+ export declare function durableWriteContentAddressed(path: string, bytes: Uint8Array, fs?: DurableFs): void;
55
+ /**
56
+ * Storage seam threaded through the audit logger and hook options. It exists
57
+ * solely so tests can inject failures; CLI execution always uses
58
+ * {@link nodeAuditStorage}.
59
+ */
60
+ export interface AuditStorage {
61
+ ensureDirectoryDurable(path: string): void;
62
+ createEmptyFile(path: string): void;
63
+ appendLine(path: string, line: string): void;
64
+ writeContentAddressed(path: string, bytes: Uint8Array): void;
65
+ }
66
+ /** Production {@link AuditStorage} backed by the fsync durable primitives. */
67
+ export declare const nodeAuditStorage: AuditStorage;
68
+ //# sourceMappingURL=durable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"durable.d.ts","sourceRoot":"","sources":["../../src/audit/durable.ts"],"names":[],"mappings":"AAaA;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1E,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5D,SAAS,CACP,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GAAG,IAAI,GACtB,MAAM,CAAC;IACV,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACnD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,0DAA0D;AAC1D,eAAO,MAAM,MAAM,EAAE,SAqBpB,CAAC;AA+BF;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAE,SAAkB,GAAG,IAAI,CAsBjF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAE,SAAkB,GAAG,IAAI,CA2B1F;AASD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAE,SAAkB,GAAG,IAAI,CAqBjF;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,UAAU,EACjB,EAAE,GAAE,SAAkB,GACrB,IAAI,CAuCN;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CAC9D;AAED,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,EAAE,YAK9B,CAAC"}
@@ -0,0 +1,214 @@
1
+ import { closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, renameSync, unlinkSync, writeSync, } from "node:fs";
2
+ import { basename, dirname, join, resolve } from "node:path";
3
+ /** Production binding of {@link DurableFs} to node:fs. */
4
+ export const nodeFs = {
5
+ existsSync: (p) => existsSync(p),
6
+ mkdirSync: (p, opts) => {
7
+ mkdirSync(p, opts);
8
+ },
9
+ openSync: (p, flags, mode) => openSync(p, flags, mode),
10
+ writeSync: (fd, buffer, offset, length, position) => writeSync(fd, buffer, offset, length, position),
11
+ fsyncSync: (fd) => {
12
+ fsyncSync(fd);
13
+ },
14
+ closeSync: (fd) => {
15
+ closeSync(fd);
16
+ },
17
+ readFileSync: (p) => readFileSync(p),
18
+ renameSync: (o, n) => {
19
+ renameSync(o, n);
20
+ },
21
+ unlinkSync: (p) => {
22
+ unlinkSync(p);
23
+ },
24
+ };
25
+ const FILE_MODE = 0o600;
26
+ const DIR_MODE = 0o700;
27
+ /**
28
+ * Write every byte of `buffer`, looping until the whole buffer is consumed. A
29
+ * single writeSync call is not guaranteed to consume the entire buffer, so the
30
+ * returned count is advanced explicitly.
31
+ */
32
+ function writeFull(fs, fd, buffer) {
33
+ let offset = 0;
34
+ while (offset < buffer.byteLength) {
35
+ const written = fs.writeSync(fd, buffer, offset, buffer.byteLength - offset, null);
36
+ if (written <= 0) {
37
+ throw new Error("durable write failed to make progress");
38
+ }
39
+ offset += written;
40
+ }
41
+ }
42
+ /** fsync a directory so a newly created directory entry becomes durable. */
43
+ function fsyncDirectory(fs, dir) {
44
+ const fd = fs.openSync(dir, "r", DIR_MODE);
45
+ try {
46
+ fs.fsyncSync(fd);
47
+ }
48
+ finally {
49
+ fs.closeSync(fd);
50
+ }
51
+ }
52
+ /**
53
+ * Create `path` (and any missing ancestors) and make the new directory entries
54
+ * durable. Missing components are collected before creation, created with
55
+ * 0o700, then fsynced from the deepest component upward followed by the
56
+ * deepest pre-existing ancestor. If `path` already exists this is a no-op.
57
+ */
58
+ export function ensureDirectoryDurable(path, fs = nodeFs) {
59
+ const target = resolve(path);
60
+ const missing = [];
61
+ let probe = target;
62
+ while (!fs.existsSync(probe)) {
63
+ missing.unshift(probe);
64
+ const parent = dirname(probe);
65
+ if (parent === probe)
66
+ break; // reached the filesystem root
67
+ probe = parent;
68
+ }
69
+ if (missing.length === 0)
70
+ return; // nothing created, nothing to flush
71
+ fs.mkdirSync(target, { recursive: true, mode: DIR_MODE });
72
+ for (let i = missing.length - 1; i >= 0; i--) {
73
+ fsyncDirectory(fs, missing[i]);
74
+ }
75
+ // Flush the pre-existing parent that now holds the shallowest new entry.
76
+ // Skip when the walk terminated at the filesystem root, in which case probe
77
+ // is itself one of the newly created components and was already flushed.
78
+ if (!missing.includes(probe)) {
79
+ fsyncDirectory(fs, probe);
80
+ }
81
+ }
82
+ /**
83
+ * Durably append one line to a JSONL-style log file. Sequence: create parent
84
+ * directories, open append/create with 0o600, write the complete UTF-8 line
85
+ * plus exactly one newline, fsync the file, close it, and fsync the parent
86
+ * directory when the file was newly created.
87
+ */
88
+ export function durableAppendLine(path, line, fs = nodeFs) {
89
+ const dir = dirname(path);
90
+ ensureDirectoryDurable(dir, fs);
91
+ const existed = fs.existsSync(path);
92
+ const fd = fs.openSync(path, "a", FILE_MODE);
93
+ let closed = false;
94
+ try {
95
+ writeFull(fs, fd, Buffer.from(line + "\n", "utf8"));
96
+ fs.fsyncSync(fd);
97
+ fs.closeSync(fd);
98
+ closed = true;
99
+ }
100
+ catch (err) {
101
+ // Close the descriptor without letting a secondary close error (POSIX can
102
+ // report a pending EIO on close after a failed fsync) mask the original
103
+ // write/fsync failure the caller must observe to fail closed.
104
+ if (!closed) {
105
+ try {
106
+ fs.closeSync(fd);
107
+ }
108
+ catch {
109
+ // preserve the original exception
110
+ }
111
+ }
112
+ throw err;
113
+ }
114
+ if (!existed) {
115
+ fsyncDirectory(fs, dir);
116
+ }
117
+ }
118
+ let tempCounter = 0;
119
+ function uniqueTempPath(dir, base) {
120
+ tempCounter = (tempCounter + 1) % Number.MAX_SAFE_INTEGER;
121
+ return join(dir, `.${base}.${process.pid}.${Date.now()}.${tempCounter}.tmp`);
122
+ }
123
+ /**
124
+ * Durably create an empty file (and its parent directories) if it does not
125
+ * already exist: open append/create with 0o600, fsync the new file, close it,
126
+ * then fsync the parent directory. An existing file is left untouched. This is
127
+ * used to materialize the audit log so a lock manager that resolves the target
128
+ * realpath never bypasses the new-file durability path.
129
+ */
130
+ export function durableCreateEmptyFile(path, fs = nodeFs) {
131
+ const dir = dirname(path);
132
+ ensureDirectoryDurable(dir, fs);
133
+ if (fs.existsSync(path))
134
+ return;
135
+ const fd = fs.openSync(path, "a", FILE_MODE);
136
+ let closed = false;
137
+ try {
138
+ fs.fsyncSync(fd);
139
+ fs.closeSync(fd);
140
+ closed = true;
141
+ }
142
+ catch (err) {
143
+ if (!closed) {
144
+ try {
145
+ fs.closeSync(fd);
146
+ }
147
+ catch {
148
+ // preserve the original exception
149
+ }
150
+ }
151
+ throw err;
152
+ }
153
+ fsyncDirectory(fs, dir);
154
+ }
155
+ /**
156
+ * Durably write content-addressed `bytes` to `path` via a same-directory temp
157
+ * file: create parents, write the temp with 0o600, fsync it, close, atomically
158
+ * rename onto the target, then fsync the parent directory.
159
+ *
160
+ * If the target already exists its bytes are compared: identical bytes are an
161
+ * idempotent success, differing bytes are reported as corruption. Descriptors
162
+ * are closed and the temp file removed on any failure while preserving the
163
+ * original exception.
164
+ */
165
+ export function durableWriteContentAddressed(path, bytes, fs = nodeFs) {
166
+ const dir = dirname(path);
167
+ ensureDirectoryDurable(dir, fs);
168
+ if (fs.existsSync(path)) {
169
+ const existing = fs.readFileSync(path);
170
+ if (Buffer.compare(Buffer.from(bytes), existing) === 0)
171
+ return;
172
+ throw new Error(`content-addressed file already exists with different bytes: ${path}`);
173
+ }
174
+ const temp = uniqueTempPath(dir, basename(path));
175
+ const fd = fs.openSync(temp, "w", FILE_MODE);
176
+ let closed = false;
177
+ let renamed = false;
178
+ try {
179
+ writeFull(fs, fd, bytes);
180
+ fs.fsyncSync(fd);
181
+ fs.closeSync(fd);
182
+ closed = true;
183
+ fs.renameSync(temp, path);
184
+ renamed = true;
185
+ fsyncDirectory(fs, dir);
186
+ }
187
+ catch (err) {
188
+ if (!closed) {
189
+ try {
190
+ fs.closeSync(fd);
191
+ }
192
+ catch {
193
+ // ignore close failure; preserve the original error
194
+ }
195
+ }
196
+ if (!renamed) {
197
+ try {
198
+ fs.unlinkSync(temp);
199
+ }
200
+ catch {
201
+ // best-effort temp cleanup; preserve the original error
202
+ }
203
+ }
204
+ throw err;
205
+ }
206
+ }
207
+ /** Production {@link AuditStorage} backed by the fsync durable primitives. */
208
+ export const nodeAuditStorage = {
209
+ ensureDirectoryDurable: (path) => ensureDirectoryDurable(path),
210
+ createEmptyFile: (path) => durableCreateEmptyFile(path),
211
+ appendLine: (path, line) => durableAppendLine(path, line),
212
+ writeContentAddressed: (path, bytes) => durableWriteContentAddressed(path, bytes),
213
+ };
214
+ //# sourceMappingURL=durable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"durable.js","sourceRoot":"","sources":["../../src/audit/durable.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,60 @@
1
- import type { AuditEntry, AuthorizationAction } from "../policy/types.js";
1
+ import { type CanonicalToolActionV1 } from "../evidence/commitments.js";
2
+ import { type AuditStorage } from "./durable.js";
3
+ import type { AuditEntry, AuditEntryV4, AuthorizationAction } from "../policy/types.js";
2
4
  import type { ToolAction } from "../runtime/types.js";
3
5
  import type { RuntimePhase } from "../runtime/types.js";
4
6
  export declare function computeCommitment(tool: string, decision: "allow" | "deny", ts: string, prev?: string, ruleMatched?: string | null, inputSummary?: string, authorization?: AuthorizationAction, commitmentVersion?: 1 | 2 | 3, phase?: RuntimePhase): string;
5
7
  export declare function summarizeInput(input: ToolAction): string;
8
+ export interface AuditEntryV4Fields {
9
+ phase: RuntimePhase;
10
+ tool: string;
11
+ decision: "allow" | "deny";
12
+ ts: string;
13
+ ruleMatched: string | null;
14
+ reason: string;
15
+ inputSummary: string;
16
+ policyCommitment: string;
17
+ actionCommitment: string;
18
+ authorization?: AuthorizationAction;
19
+ prev: string;
20
+ }
21
+ /**
22
+ * Version-4 entry commitment. Covers every security-relevant field with a
23
+ * domain separator: prev_commitment, phase, tool, decision, ts, rule, reason,
24
+ * the enforcement-time policy commitment, and the complete-action commitment.
25
+ * `inputSummary` is chained for display tamper-evidence only; the authoritative
26
+ * action binding is `actionCommitment`.
27
+ */
28
+ export declare function computeCommitmentV4(fields: AuditEntryV4Fields): string;
6
29
  export declare function auditDir(agentId: string): string;
7
30
  export declare function getLastCommitment(agentId: string): string;
8
- export declare function appendAuditEntry(agentId: string, entry: AuditEntry): void;
31
+ export declare function appendAuditEntry(agentId: string, entry: AuditEntry, storage?: AuditStorage): void;
32
+ /**
33
+ * Append a v4 entry produced by `build`, persisting the complete canonical
34
+ * action as a content-addressed sidecar BEFORE the entry that references it.
35
+ *
36
+ * The sidecar write and the entry append both happen while holding the same
37
+ * per-log lock used to choose `prev_commitment`, so the ordering is atomic with
38
+ * respect to concurrent appends. A crash may leave an unreferenced sidecar, but
39
+ * never a committed entry whose action evidence was not flushed first. Any
40
+ * storage/fsync error propagates so the caller (pre-hook) can fail closed.
41
+ */
9
42
  export declare function appendChainedAuditEntry<T extends {
10
- auditEntry: AuditEntry;
11
- }>(agentId: string, build: (prevCommitment: string) => T): T;
12
- export declare function buildEntry(input: ToolAction, decision: "allow" | "deny", ruleMatched: string | null, prevCommitment?: string): AuditEntry;
43
+ auditEntry: AuditEntryV4;
44
+ action: CanonicalToolActionV1;
45
+ }>(agentId: string, build: (prevCommitment: string) => T, storage?: AuditStorage): T;
46
+ export interface AuditEntryBindings {
47
+ reason: string;
48
+ policyCommitment: string;
49
+ actionCommitment: string;
50
+ }
51
+ /**
52
+ * Build a version-4 audit entry that binds the decision to the exact
53
+ * enforcement-time policy commitment and complete-action commitment. The caller
54
+ * (enforcement core) computes both commitments from the normalized policy and
55
+ * canonical action used for the decision; this function never recomputes them
56
+ * from mutable files.
57
+ */
58
+ export declare function buildEntry(input: ToolAction, decision: "allow" | "deny", ruleMatched: string | null, prevCommitment: string, bindings: AuditEntryBindings): AuditEntryV4;
13
59
  export declare function extractAuthorizationAction(input: ToolAction): AuthorizationAction | undefined;
14
60
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/audit/logger.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAexD,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,GAAG,MAAM,EAC1B,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,MAAY,EAClB,WAAW,GAAE,MAAM,GAAG,IAAW,EACjC,YAAY,GAAE,MAAW,EACzB,aAAa,CAAC,EAAE,mBAAmB,EACnC,iBAAiB,GAAE,CAAC,GAAG,CAAC,GAAG,CAAK,EAChC,KAAK,CAAC,EAAE,YAAY,GACnB,MAAM,CASR;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAGxD;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIzD;AAsCD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAKzE;AAED,wBAAgB,uBAAuB,CAAC,CAAC,SAAS;IAAE,UAAU,EAAE,UAAU,CAAA;CAAE,EAC1E,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,CAAC,GACnC,CAAC,CAUH;AAkCD,wBAAgB,UAAU,CACxB,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,OAAO,GAAG,MAAM,EAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,cAAc,GAAE,MAAY,GAC3B,UAAU,CA4BZ;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,UAAU,GAAG,mBAAmB,GAAG,SAAS,CAsB7F"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/audit/logger.ts"],"names":[],"mappings":"AAMA,OAAO,EAA2B,KAAK,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACjG,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAexD,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,GAAG,MAAM,EAC1B,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,MAAY,EAClB,WAAW,GAAE,MAAM,GAAG,IAAW,EACjC,YAAY,GAAE,MAAW,EACzB,aAAa,CAAC,EAAE,mBAAmB,EACnC,iBAAiB,GAAE,CAAC,GAAG,CAAC,GAAG,CAAK,EAChC,KAAK,CAAC,EAAE,YAAY,GACnB,MAAM,CASR;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAGxD;AAQD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAetE;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIzD;AAsCD,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,YAA+B,GACvC,IAAI,CAGN;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,CAAC,SAAS;IAAE,UAAU,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,qBAAqB,CAAA;CAAE,EAErE,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,CAAC,EACpC,OAAO,GAAE,YAA+B,GACvC,CAAC,CAoBH;AAwCD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,OAAO,GAAG,MAAM,EAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,kBAAkB,GAC3B,YAAY,CAmCd;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,UAAU,GAAG,mBAAmB,GAAG,SAAS,CAsB7F"}
@@ -1,8 +1,11 @@
1
1
  import { createHash } from "node:crypto";
2
- import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readSync, statSync } from "node:fs";
2
+ import { closeSync, existsSync, openSync, readSync, statSync } from "node:fs";
3
3
  import { dirname, join } from "node:path";
4
4
  import { lockSync } from "proper-lockfile";
5
- import { auditDirForDate } from "./paths.js";
5
+ import { actionSidecarPath, auditDirForDate } from "./paths.js";
6
+ import { sha256Hex, stableStringify } from "../evidence/canonical.js";
7
+ import { computeActionCommitment } from "../evidence/commitments.js";
8
+ import { nodeAuditStorage } from "./durable.js";
6
9
  const AUDIT_LOCK_STALE_MS = 5_000;
7
10
  const AUDIT_LOCK_WAIT_MS = 2_000;
8
11
  const AUDIT_LOCK_RETRY_MS = 10;
@@ -29,6 +32,34 @@ export function summarizeInput(input) {
29
32
  const raw = JSON.stringify(input.toolInput);
30
33
  return raw.length > 200 ? raw.slice(0, 200) + "…" : raw;
31
34
  }
35
+ // Domain separator for version-4 audit-entry commitments. v4 is a NEW format
36
+ // with no backward-compatibility constraint, so it uses the shared canonical
37
+ // serializer and an explicit domain string. Legacy v1--v3 commitments above are
38
+ // left byte-for-byte unchanged.
39
+ const AUDIT_ENTRY_V4_DOMAIN = "catp:audit-entry:v4\n";
40
+ /**
41
+ * Version-4 entry commitment. Covers every security-relevant field with a
42
+ * domain separator: prev_commitment, phase, tool, decision, ts, rule, reason,
43
+ * the enforcement-time policy commitment, and the complete-action commitment.
44
+ * `inputSummary` is chained for display tamper-evidence only; the authoritative
45
+ * action binding is `actionCommitment`.
46
+ */
47
+ export function computeCommitmentV4(fields) {
48
+ const payload = {
49
+ phase: fields.phase,
50
+ tool: fields.tool,
51
+ decision: fields.decision,
52
+ ts: fields.ts,
53
+ ruleMatched: fields.ruleMatched,
54
+ reason: fields.reason,
55
+ inputSummary: fields.inputSummary,
56
+ policyCommitment: fields.policyCommitment,
57
+ actionCommitment: fields.actionCommitment,
58
+ authorization: fields.authorization ?? null,
59
+ prev: fields.prev,
60
+ };
61
+ return sha256Hex(AUDIT_ENTRY_V4_DOMAIN + stableStringify(payload));
62
+ }
32
63
  export function auditDir(agentId) {
33
64
  const date = new Date().toISOString().slice(0, 10);
34
65
  return auditDirForDate(agentId, date);
@@ -75,27 +106,51 @@ function readLastAuditLine(file) {
75
106
  closeSync(fd);
76
107
  }
77
108
  }
78
- export function appendAuditEntry(agentId, entry) {
79
- const dir = auditDir(agentId);
80
- mkdirSync(dir, { recursive: true });
81
- const file = join(dir, "actions.jsonl");
82
- withAuditLock(file, () => appendEntryToFile(file, entry));
109
+ export function appendAuditEntry(agentId, entry, storage = nodeAuditStorage) {
110
+ const file = join(auditDir(agentId), "actions.jsonl");
111
+ withAuditLock(file, storage, () => appendEntryToFile(file, entry, storage));
83
112
  }
84
- export function appendChainedAuditEntry(agentId, build) {
85
- const dir = auditDir(agentId);
86
- mkdirSync(dir, { recursive: true });
113
+ /**
114
+ * Append a v4 entry produced by `build`, persisting the complete canonical
115
+ * action as a content-addressed sidecar BEFORE the entry that references it.
116
+ *
117
+ * The sidecar write and the entry append both happen while holding the same
118
+ * per-log lock used to choose `prev_commitment`, so the ordering is atomic with
119
+ * respect to concurrent appends. A crash may leave an unreferenced sidecar, but
120
+ * never a committed entry whose action evidence was not flushed first. Any
121
+ * storage/fsync error propagates so the caller (pre-hook) can fail closed.
122
+ */
123
+ export function appendChainedAuditEntry(agentId, build, storage = nodeAuditStorage) {
124
+ // Compute the date once so the log file and its action sidecars always land
125
+ // in the same daily directory even across a midnight boundary.
126
+ const date = new Date().toISOString().slice(0, 10);
127
+ const dir = auditDirForDate(agentId, date);
87
128
  const file = join(dir, "actions.jsonl");
88
- return withAuditLock(file, () => {
129
+ return withAuditLock(file, storage, () => {
89
130
  const result = build(getLastCommitmentFromFile(file));
90
- appendEntryToFile(file, result.auditEntry);
131
+ const entry = result.auditEntry;
132
+ // Re-check the binding at the persistence boundary so a mismatched
133
+ // entry/action pair can never be durably recorded.
134
+ if (computeActionCommitment(result.action) !== entry.action_commitment) {
135
+ throw new Error("internal error: action evidence does not match audit entry binding");
136
+ }
137
+ const sidecar = actionSidecarPath(agentId, date, entry.action_commitment);
138
+ storage.writeContentAddressed(sidecar, Buffer.from(stableStringify(result.action), "utf8"));
139
+ appendEntryToFile(file, entry, storage);
91
140
  return result;
92
141
  });
93
142
  }
94
- function appendEntryToFile(file, entry) {
95
- appendFileSync(file, JSON.stringify(entry) + "\n", "utf8");
143
+ // `input_summary` is capped for operator readability and is NON-AUTHORITATIVE:
144
+ // the security binding is the content-addressed action sidecar plus the entry's
145
+ // action_commitment, never this display string.
146
+ function appendEntryToFile(file, entry, storage) {
147
+ storage.appendLine(file, JSON.stringify(entry));
96
148
  }
97
- function withAuditLock(file, operation) {
98
- closeSync(openSync(file, "a"));
149
+ function withAuditLock(file, storage, operation) {
150
+ // Durably materialize the log file (fsync new file + parent) before
151
+ // proper-lockfile resolves its realpath, so lock setup cannot bypass the
152
+ // new-file durability path.
153
+ storage.createEmptyFile(file);
99
154
  const release = acquireAuditLock(file);
100
155
  try {
101
156
  return operation();
@@ -122,18 +177,42 @@ function acquireAuditLock(file) {
122
177
  }
123
178
  }
124
179
  }
125
- export function buildEntry(input, decision, ruleMatched, prevCommitment = "0") {
180
+ /**
181
+ * Build a version-4 audit entry that binds the decision to the exact
182
+ * enforcement-time policy commitment and complete-action commitment. The caller
183
+ * (enforcement core) computes both commitments from the normalized policy and
184
+ * canonical action used for the decision; this function never recomputes them
185
+ * from mutable files.
186
+ */
187
+ export function buildEntry(input, decision, ruleMatched, prevCommitment, bindings) {
126
188
  const ts = new Date().toISOString();
127
189
  const inputSummary = summarizeInput(input);
128
190
  const authorization = extractAuthorizationAction(input);
191
+ const phase = input.phase;
192
+ const commitment = computeCommitmentV4({
193
+ phase,
194
+ tool: input.toolName,
195
+ decision,
196
+ ts,
197
+ ruleMatched,
198
+ reason: bindings.reason,
199
+ inputSummary,
200
+ policyCommitment: bindings.policyCommitment,
201
+ actionCommitment: bindings.actionCommitment,
202
+ authorization,
203
+ prev: prevCommitment,
204
+ });
129
205
  const entry = {
130
- commitment_version: 3,
131
- phase: input.phase,
206
+ commitment_version: 4,
207
+ phase,
132
208
  ts,
133
209
  tool: input.toolName,
134
210
  decision,
135
211
  rule_matched: ruleMatched,
136
- commitment: computeCommitment(input.toolName, decision, ts, prevCommitment, ruleMatched, inputSummary, authorization, 3, input.phase),
212
+ reason: bindings.reason,
213
+ policy_commitment: bindings.policyCommitment,
214
+ action_commitment: bindings.actionCommitment,
215
+ commitment,
137
216
  input_summary: inputSummary,
138
217
  };
139
218
  if (authorization) {
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/audit/logger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/audit/logger.ts"],"names":[],"mappings":"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"}
@@ -2,4 +2,15 @@ export declare function catpHome(): string;
2
2
  export declare function validateAgentId(agentId: string): string;
3
3
  export declare function auditRoot(agentId: string): string;
4
4
  export declare function auditDirForDate(agentId: string, date: string): string;
5
+ /**
6
+ * Directory holding the content-addressed canonical action sidecars for a given
7
+ * agent/day: `$CATP_HOME/audit/<agent>/<YYYY-MM-DD>/actions`.
8
+ */
9
+ export declare function actionsDirForDate(agentId: string, date: string): string;
10
+ /**
11
+ * Absolute path of the durable sidecar storing the complete canonical action
12
+ * whose digest is `actionCommitment`. The commitment must be a 64-character
13
+ * lowercase hex digest so it can never escape the actions directory.
14
+ */
15
+ export declare function actionSidecarPath(agentId: string, date: string, actionCommitment: string): string;
5
16
  //# sourceMappingURL=paths.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/audit/paths.ts"],"names":[],"mappings":"AAGA,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAErE"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/audit/paths.ts"],"names":[],"mappings":"AAGA,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvE;AAID;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,GACvB,MAAM,CAKR"}
@@ -15,4 +15,23 @@ export function auditRoot(agentId) {
15
15
  export function auditDirForDate(agentId, date) {
16
16
  return join(auditRoot(agentId), date);
17
17
  }
18
+ /**
19
+ * Directory holding the content-addressed canonical action sidecars for a given
20
+ * agent/day: `$CATP_HOME/audit/<agent>/<YYYY-MM-DD>/actions`.
21
+ */
22
+ export function actionsDirForDate(agentId, date) {
23
+ return join(auditDirForDate(agentId, date), "actions");
24
+ }
25
+ const ACTION_COMMITMENT_HEX64 = /^[0-9a-f]{64}$/;
26
+ /**
27
+ * Absolute path of the durable sidecar storing the complete canonical action
28
+ * whose digest is `actionCommitment`. The commitment must be a 64-character
29
+ * lowercase hex digest so it can never escape the actions directory.
30
+ */
31
+ export function actionSidecarPath(agentId, date, actionCommitment) {
32
+ if (!ACTION_COMMITMENT_HEX64.test(actionCommitment)) {
33
+ throw new Error("action commitment must be a 64-character lowercase hex digest");
34
+ }
35
+ return join(actionsDirForDate(agentId, date), `${actionCommitment}.json`);
36
+ }
18
37
  //# sourceMappingURL=paths.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/audit/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,UAAU,QAAQ;IACtB,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAC;IAChG,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,OAAO,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,IAAY;IAC3D,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/audit/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,UAAU,QAAQ;IACtB,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAC;IAChG,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,OAAO,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,IAAY;IAC3D,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe,EAAE,IAAY;IAC7D,OAAO,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,uBAAuB,GAAG,gBAAgB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAAe,EACf,IAAY,EACZ,gBAAwB;IAExB,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,GAAG,gBAAgB,OAAO,CAAC,CAAC;AAC5E,CAAC"}