@agentplat/audit-postgres 0.3.0-beta.2 → 0.3.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,26 +4,64 @@ PostgreSQL sinks for applications that need durable audit or Session events
4
4
  without installing the Agent Room schema.
5
5
 
6
6
  ```ts
7
- import { createPostgresPool } from '@agentplat/postgres';
7
+ import { createPostgresPool } from "@agentplat/postgres";
8
8
  import {
9
9
  PostgresAuditSink,
10
+ PostgresCollectiveTelemetryMonotonicAnchorV1,
11
+ PostgresCollectiveTelemetryStoreV1,
10
12
  PostgresSessionEventSink,
11
13
  runAuditMigrations,
12
- } from '@agentplat/audit-postgres';
14
+ } from "@agentplat/audit-postgres";
13
15
 
14
16
  const pool = createPostgresPool();
15
- await runAuditMigrations(pool, { schema: 'agentplat_orders' });
17
+ await runAuditMigrations(pool, { schema: "agentplat_orders" });
18
+ const protectedWitnessPool = createPostgresPool({
19
+ connectionString: process.env.TELEMETRY_WITNESS_DATABASE_URL,
20
+ });
21
+ await runAuditMigrations(protectedWitnessPool, {
22
+ schema: "agentplat_witness",
23
+ });
16
24
 
17
- const audit = new PostgresAuditSink(pool, { schema: 'agentplat_orders' });
25
+ const audit = new PostgresAuditSink(pool, { schema: "agentplat_orders" });
18
26
  const sessionEvents = new PostgresSessionEventSink(pool, {
19
- schema: 'agentplat_orders',
27
+ schema: "agentplat_orders",
28
+ });
29
+
30
+ const telemetryStore = new PostgresCollectiveTelemetryStoreV1(pool, {
31
+ schema: "agentplat_orders",
32
+ tenantId: "tenant-a",
20
33
  });
34
+ const telemetryAnchor = new PostgresCollectiveTelemetryMonotonicAnchorV1(
35
+ protectedWitnessPool,
36
+ { schema: "agentplat_witness", tenantId: "tenant-a" },
37
+ );
21
38
  ```
22
39
 
23
40
  Both tables are append-only and all writes include `tenant_id`. Sinks redact
24
41
  secret-like keys recursively before persistence. Deterministic IDs make event
25
42
  retries idempotent.
26
43
 
44
+ `PostgresCollectiveTelemetryStoreV1` adds revision-and-state-digest CAS for the
45
+ signed telemetry chain and an append-only event table. Event identity conflicts
46
+ roll the state transaction back instead of accepting an ambiguous replay. The
47
+ runtime also requires an independently protected monotonic anchor. Migration
48
+ 004 and `PostgresCollectiveTelemetryMonotonicAnchorV1` provide one bounded CAS
49
+ head per stream. PostgreSQL permits only an exact monotonic successor and
50
+ forbids deletion, so storage is bounded by stream count rather than event
51
+ count. For rollback separation, construct that adapter with a pool and schema
52
+ protected independently from the replaceable application-state pool;
53
+ using the same database preserves restart continuity but not backup-domain
54
+ separation.
55
+
56
+ Migration 003 adds bounded, short-lived delivery receipts. A scope lock makes
57
+ the receipt-capacity check, telemetry state CAS, append-only event insert and
58
+ receipt insert one transaction. The nominal runtime handoff is therefore
59
+ idempotent by delivery digest independently of event retention. Runtime and
60
+ adapter consumers receive no independent record/release primitives: the
61
+ module-owned handoff privately removes the exact receipt only after the source
62
+ persists its recorded state, then ACKs that source envelope.
63
+ `maximumPendingDeliveryReceipts` defaults to 4096 and exhaustion fails closed.
64
+
27
65
  The package uses the shared version/checksum ledger from
28
66
  `@agentplat/postgres`. `migrate:down` is blocked unless the expected version,
29
67
  exact confirmation string, and explicit data-loss flag are all supplied. It is
package/dist/index.d.ts CHANGED
@@ -1,11 +1,60 @@
1
- import type { AuditRecord, AuditSink } from '@agentplat/audit';
2
- import type { SessionEventRecord, SessionEventSink } from '@agentplat/sessions';
3
- import type { Pool } from 'pg';
4
- export { auditMigrationDirectory, auditRollbackConfirmation, getAuditMigrationStatus, rollbackAuditMigrations, runAuditMigrations, } from './migrations.js';
5
- export type { AuditPostgresMigrationOptions } from './migrations.js';
1
+ import type { AuditRecord, AuditSink } from "@agentplat/audit";
2
+ import type { CollectiveTelemetryAnchorV1, CollectiveTelemetryDeliveryCommitResultV1, CollectiveTelemetryDeliveryReceiptV1, CollectiveTelemetryMonotonicAnchorPortV1, CollectiveTelemetryStateV1, CollectiveTelemetryStoreV1 } from "@agentplat/audit/collective-telemetry";
3
+ import type { SessionEventRecord, SessionEventSink } from "@agentplat/sessions";
4
+ import type { Pool } from "pg";
5
+ export { auditMigrationDirectory, auditRollbackConfirmation, getAuditMigrationStatus, rollbackAuditMigrations, runAuditMigrations, } from "./migrations.js";
6
+ export type { AuditPostgresMigrationOptions } from "./migrations.js";
6
7
  export interface PostgresSinkOptions {
7
8
  schema?: string;
8
9
  }
10
+ export interface PostgresCollectiveTelemetryStoreOptions extends PostgresSinkOptions {
11
+ tenantId: string;
12
+ maximumPendingDeliveryReceipts?: number;
13
+ }
14
+ export interface PostgresCollectiveTelemetryAnchorOptions extends PostgresSinkOptions {
15
+ tenantId: string;
16
+ }
17
+ /** CAS state plus append-only signed events for collective telemetry. */
18
+ export declare class PostgresCollectiveTelemetryStoreV1 implements CollectiveTelemetryStoreV1 {
19
+ private readonly stateTable;
20
+ private readonly eventTable;
21
+ private readonly deliveryReceiptTable;
22
+ private readonly maximumPendingDeliveryReceipts;
23
+ private readonly tenantId;
24
+ private readonly poolQuery;
25
+ private readonly poolConnect;
26
+ constructor(pool: Pool, options: PostgresCollectiveTelemetryStoreOptions);
27
+ load(streamId: string): Promise<CollectiveTelemetryStateV1 | null>;
28
+ save(state: CollectiveTelemetryStateV1, expectedRevision: number | null, expectedStateDigest: string | null): Promise<boolean>;
29
+ loadDelivery(streamId: string, deliveryDigest: string): Promise<CollectiveTelemetryDeliveryReceiptV1 | null>;
30
+ commitDelivery(input: {
31
+ readonly state: CollectiveTelemetryStateV1;
32
+ readonly expectedRevision: number;
33
+ readonly expectedStateDigest: string;
34
+ readonly receipt: CollectiveTelemetryDeliveryReceiptV1;
35
+ }): Promise<CollectiveTelemetryDeliveryCommitResultV1>;
36
+ releaseDelivery(streamId: string, deliveryDigest: string): Promise<boolean>;
37
+ }
38
+ /**
39
+ * Bounded monotonic witness for telemetry stream heads. It can be placed
40
+ * on a separately protected PostgreSQL pool/schema from the mutable stream
41
+ * state so an application-state rollback cannot silently roll the witness
42
+ * back with it.
43
+ */
44
+ export declare class PostgresCollectiveTelemetryMonotonicAnchorV1 implements CollectiveTelemetryMonotonicAnchorPortV1 {
45
+ private readonly table;
46
+ private readonly tenantId;
47
+ private readonly poolQuery;
48
+ private readonly poolConnect;
49
+ constructor(pool: Pool, options: PostgresCollectiveTelemetryAnchorOptions);
50
+ load(anchorKey: string): Promise<CollectiveTelemetryAnchorV1 | null>;
51
+ save(input: {
52
+ readonly anchorKey: string;
53
+ readonly anchor: CollectiveTelemetryAnchorV1;
54
+ readonly expectedRevision: number | null;
55
+ readonly expectedStateDigest: string | null;
56
+ }): Promise<boolean>;
57
+ }
9
58
  /** Append-only, redacting PostgreSQL AuditSink. */
10
59
  export declare class PostgresAuditSink implements AuditSink {
11
60
  private readonly pool;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAM/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,6BAA6B,EAAE,MAAM,iBAAiB,CAAC;AAErE,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,mDAAmD;AACnD,qBAAa,iBAAkB,YAAW,SAAS;IAI/C,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAGZ,IAAI,EAAE,IAAI,EAC3B,OAAO,GAAE,mBAAwB;IAQ7B,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAuBhD;AAED,4EAA4E;AAC5E,qBAAa,wBAAyB,YAAW,gBAAgB;IAI7D,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAGZ,IAAI,EAAE,IAAI,EAC3B,OAAO,GAAE,mBAAwB;IAQ7B,MAAM,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;CAiBxD;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,mBAAmB,GAC5B,iBAAiB,CAEnB;AAED,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,mBAAmB,GAC5B,wBAAwB,CAE1B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,13 +1,363 @@
1
- import { redactAuditDetails } from '@agentplat/audit';
2
- import { defaultPostgresSchema, qualifyPostgresName, } from '@agentplat/postgres';
3
- export { auditMigrationDirectory, auditRollbackConfirmation, getAuditMigrationStatus, rollbackAuditMigrations, runAuditMigrations, } from './migrations.js';
1
+ import { redactAuditDetails } from "@agentplat/audit";
2
+ import { defaultPostgresSchema, qualifyPostgresName, } from "@agentplat/postgres";
3
+ export { auditMigrationDirectory, auditRollbackConfirmation, getAuditMigrationStatus, rollbackAuditMigrations, runAuditMigrations, } from "./migrations.js";
4
+ /** CAS state plus append-only signed events for collective telemetry. */
5
+ export class PostgresCollectiveTelemetryStoreV1 {
6
+ stateTable;
7
+ eventTable;
8
+ deliveryReceiptTable;
9
+ maximumPendingDeliveryReceipts;
10
+ tenantId;
11
+ poolQuery;
12
+ poolConnect;
13
+ constructor(pool, options) {
14
+ if (!options.tenantId)
15
+ throw new TypeError("collective telemetry tenant is required");
16
+ const maximumPendingDeliveryReceipts = options.maximumPendingDeliveryReceipts ?? 4_096;
17
+ if (!Number.isSafeInteger(maximumPendingDeliveryReceipts) ||
18
+ maximumPendingDeliveryReceipts < 1 ||
19
+ maximumPendingDeliveryReceipts > 100_000)
20
+ throw new TypeError("maximumPendingDeliveryReceipts is invalid");
21
+ const schema = options.schema ?? defaultPostgresSchema;
22
+ this.stateTable = qualifyPostgresName(schema, "collective_telemetry_states");
23
+ this.eventTable = qualifyPostgresName(schema, "collective_telemetry_events");
24
+ this.deliveryReceiptTable = qualifyPostgresName(schema, "collective_telemetry_delivery_receipts");
25
+ this.tenantId = options.tenantId;
26
+ this.poolQuery = pool.query.bind(pool);
27
+ this.poolConnect = pool.connect.bind(pool);
28
+ this.maximumPendingDeliveryReceipts = maximumPendingDeliveryReceipts;
29
+ }
30
+ async load(streamId) {
31
+ const result = await this.poolQuery(`SELECT revision, sequence, logical_time_high_water_ms, state_digest, state
32
+ FROM ${this.stateTable}
33
+ WHERE tenant_id = $1 AND stream_id = $2`, [this.tenantId, streamId]);
34
+ const row = result.rows[0];
35
+ if (!row)
36
+ return null;
37
+ if (row.state.tenantId !== this.tenantId ||
38
+ row.state.streamId !== streamId ||
39
+ row.state.revision !== Number(row.revision) ||
40
+ row.state.sequence !== Number(row.sequence) ||
41
+ row.state.logicalTimeHighWaterMs !==
42
+ Number(row.logical_time_high_water_ms) ||
43
+ row.state.stateDigest !== row.state_digest)
44
+ throw new Error("collective telemetry PostgreSQL columns diverge from state");
45
+ return row.state;
46
+ }
47
+ async save(state, expectedRevision, expectedStateDigest) {
48
+ state = structuredClone(state);
49
+ if (state.tenantId !== this.tenantId ||
50
+ state.revision !==
51
+ (expectedRevision === null ? 0 : expectedRevision + 1) ||
52
+ (expectedRevision === null) !== (expectedStateDigest === null))
53
+ return false;
54
+ const client = await this.poolConnect();
55
+ try {
56
+ await client.query("BEGIN");
57
+ const result = expectedRevision === null
58
+ ? await client.query(`INSERT INTO ${this.stateTable}
59
+ (tenant_id, stream_id, revision, sequence, logical_time_high_water_ms, state_digest, state)
60
+ VALUES ($1,$2,$3,$4,$5,$6,$7::jsonb) ON CONFLICT DO NOTHING`, [
61
+ state.tenantId,
62
+ state.streamId,
63
+ state.revision,
64
+ state.sequence,
65
+ state.logicalTimeHighWaterMs,
66
+ state.stateDigest,
67
+ JSON.stringify(state),
68
+ ])
69
+ : await client.query(`UPDATE ${this.stateTable}
70
+ SET revision = $4, sequence = $5, logical_time_high_water_ms = $6,
71
+ state_digest = $7, state = $8::jsonb, updated_at = transaction_timestamp()
72
+ WHERE tenant_id = $1 AND stream_id = $2 AND revision = $3
73
+ AND state_digest = $9
74
+ AND sequence < $5 AND logical_time_high_water_ms <= $6`, [
75
+ state.tenantId,
76
+ state.streamId,
77
+ expectedRevision,
78
+ state.revision,
79
+ state.sequence,
80
+ state.logicalTimeHighWaterMs,
81
+ state.stateDigest,
82
+ JSON.stringify(state),
83
+ expectedStateDigest,
84
+ ]);
85
+ if ((result.rowCount ?? 0) !== 1) {
86
+ await client.query("ROLLBACK");
87
+ return false;
88
+ }
89
+ const event = state.events.at(-1);
90
+ if (event && event.sequence === state.sequence) {
91
+ await client.query(`INSERT INTO ${this.eventTable}
92
+ (tenant_id, stream_id, sequence, event_id, event_digest, event)
93
+ VALUES ($1,$2,$3,$4,$5,$6::jsonb) ON CONFLICT DO NOTHING`, [
94
+ state.tenantId,
95
+ state.streamId,
96
+ event.sequence,
97
+ event.eventId,
98
+ event.eventDigest,
99
+ JSON.stringify(event),
100
+ ]);
101
+ const retained = await client.query(`SELECT event_digest FROM ${this.eventTable}
102
+ WHERE tenant_id = $1 AND event_id = $2`, [state.tenantId, event.eventId]);
103
+ if (retained.rows[0]?.event_digest !== event.eventDigest)
104
+ throw new Error("collective telemetry event identity conflict");
105
+ }
106
+ await client.query("COMMIT");
107
+ return true;
108
+ }
109
+ catch (error) {
110
+ await client.query("ROLLBACK");
111
+ throw error;
112
+ }
113
+ finally {
114
+ client.release();
115
+ }
116
+ }
117
+ async loadDelivery(streamId, deliveryDigest) {
118
+ const result = await this.poolQuery(`SELECT record_input_digest, event_digest, sequence
119
+ FROM ${this.deliveryReceiptTable}
120
+ WHERE tenant_id = $1 AND stream_id = $2 AND delivery_digest = $3`, [this.tenantId, streamId, deliveryDigest]);
121
+ const row = result.rows[0];
122
+ return row
123
+ ? {
124
+ schemaVersion: 1,
125
+ streamId,
126
+ deliveryDigest,
127
+ recordInputDigest: row.record_input_digest,
128
+ eventDigest: row.event_digest,
129
+ sequence: Number(row.sequence),
130
+ }
131
+ : null;
132
+ }
133
+ async commitDelivery(input) {
134
+ input = structuredClone(input);
135
+ if (input.state.tenantId !== this.tenantId ||
136
+ input.state.streamId !== input.receipt.streamId ||
137
+ input.state.revision !== input.expectedRevision + 1)
138
+ return "conflict";
139
+ const event = input.state.events.at(-1);
140
+ if (!event ||
141
+ event.sequence !== input.state.sequence ||
142
+ event.eventDigest !== input.receipt.eventDigest ||
143
+ event.sequence !== input.receipt.sequence)
144
+ throw new TypeError("collective telemetry delivery receipt/event binding is invalid");
145
+ const client = await this.poolConnect();
146
+ try {
147
+ await client.query("BEGIN");
148
+ await client.query("SELECT pg_advisory_xact_lock(hashtextextended($1, 0))", [`${this.tenantId}:collective-telemetry-deliveries`]);
149
+ const existing = await client.query(`SELECT record_input_digest
150
+ FROM ${this.deliveryReceiptTable}
151
+ WHERE tenant_id = $1 AND stream_id = $2 AND delivery_digest = $3`, [this.tenantId, input.receipt.streamId, input.receipt.deliveryDigest]);
152
+ if (existing.rows[0]) {
153
+ if (existing.rows[0].record_input_digest !==
154
+ input.receipt.recordInputDigest)
155
+ throw new Error("collective telemetry delivery digest collision");
156
+ await client.query("COMMIT");
157
+ return "already_recorded";
158
+ }
159
+ const count = await client.query(`SELECT count(*) AS pending FROM ${this.deliveryReceiptTable}
160
+ WHERE tenant_id = $1`, [this.tenantId]);
161
+ if (Number(count.rows[0]?.pending ?? 0) >=
162
+ this.maximumPendingDeliveryReceipts)
163
+ throw new Error("collective telemetry delivery receipt capacity exhausted");
164
+ const saved = await client.query(`UPDATE ${this.stateTable}
165
+ SET revision = $4, sequence = $5,
166
+ logical_time_high_water_ms = $6, state_digest = $7,
167
+ state = $8::jsonb, updated_at = transaction_timestamp()
168
+ WHERE tenant_id = $1 AND stream_id = $2 AND revision = $3
169
+ AND state_digest = $9 AND sequence < $5
170
+ AND logical_time_high_water_ms <= $6`, [
171
+ input.state.tenantId,
172
+ input.state.streamId,
173
+ input.expectedRevision,
174
+ input.state.revision,
175
+ input.state.sequence,
176
+ input.state.logicalTimeHighWaterMs,
177
+ input.state.stateDigest,
178
+ JSON.stringify(input.state),
179
+ input.expectedStateDigest,
180
+ ]);
181
+ if ((saved.rowCount ?? 0) !== 1) {
182
+ await client.query("ROLLBACK");
183
+ return "conflict";
184
+ }
185
+ await client.query(`INSERT INTO ${this.eventTable}
186
+ (tenant_id, stream_id, sequence, event_id, event_digest, event)
187
+ VALUES ($1,$2,$3,$4,$5,$6::jsonb)`, [
188
+ input.state.tenantId,
189
+ input.state.streamId,
190
+ event.sequence,
191
+ event.eventId,
192
+ event.eventDigest,
193
+ JSON.stringify(event),
194
+ ]);
195
+ await client.query(`INSERT INTO ${this.deliveryReceiptTable}
196
+ (tenant_id, stream_id, delivery_digest, record_input_digest,
197
+ event_digest, sequence)
198
+ VALUES ($1,$2,$3,$4,$5,$6)`, [
199
+ input.state.tenantId,
200
+ input.state.streamId,
201
+ input.receipt.deliveryDigest,
202
+ input.receipt.recordInputDigest,
203
+ input.receipt.eventDigest,
204
+ input.receipt.sequence,
205
+ ]);
206
+ await client.query("COMMIT");
207
+ return "committed";
208
+ }
209
+ catch (error) {
210
+ await client.query("ROLLBACK").catch(() => undefined);
211
+ throw error;
212
+ }
213
+ finally {
214
+ client.release();
215
+ }
216
+ }
217
+ async releaseDelivery(streamId, deliveryDigest) {
218
+ await this.poolQuery(`DELETE FROM ${this.deliveryReceiptTable}
219
+ WHERE tenant_id = $1 AND stream_id = $2 AND delivery_digest = $3`, [this.tenantId, streamId, deliveryDigest]);
220
+ return true;
221
+ }
222
+ }
223
+ /**
224
+ * Bounded monotonic witness for telemetry stream heads. It can be placed
225
+ * on a separately protected PostgreSQL pool/schema from the mutable stream
226
+ * state so an application-state rollback cannot silently roll the witness
227
+ * back with it.
228
+ */
229
+ export class PostgresCollectiveTelemetryMonotonicAnchorV1 {
230
+ table;
231
+ tenantId;
232
+ poolQuery;
233
+ poolConnect;
234
+ constructor(pool, options) {
235
+ validateTelemetryIdentifier(options.tenantId, "tenantId");
236
+ this.tenantId = options.tenantId;
237
+ this.table = qualifyPostgresName(options.schema ?? defaultPostgresSchema, "collective_telemetry_monotonic_anchors");
238
+ this.poolQuery = pool.query.bind(pool);
239
+ this.poolConnect = pool.connect.bind(pool);
240
+ }
241
+ async load(anchorKey) {
242
+ validateTelemetryIdentifier(anchorKey, "anchorKey");
243
+ const result = await this.poolQuery(`SELECT revision, sequence, state_digest, logical_time_high_water_ms
244
+ FROM ${this.table}
245
+ WHERE tenant_id = $1 AND anchor_key = $2`, [this.tenantId, anchorKey]);
246
+ return result.rows[0] ? telemetryAnchorFromRow(result.rows[0]) : null;
247
+ }
248
+ async save(input) {
249
+ const request = {
250
+ anchorKey: input.anchorKey,
251
+ anchor: Object.freeze({ ...input.anchor }),
252
+ expectedRevision: input.expectedRevision,
253
+ expectedStateDigest: input.expectedStateDigest,
254
+ };
255
+ validateTelemetryIdentifier(request.anchorKey, "anchorKey");
256
+ validateTelemetryAnchor(request.anchor);
257
+ if ((request.expectedRevision === null) !==
258
+ (request.expectedStateDigest === null) ||
259
+ (request.expectedRevision !== null &&
260
+ (!Number.isSafeInteger(request.expectedRevision) ||
261
+ request.expectedRevision < 0)) ||
262
+ (request.expectedStateDigest !== null &&
263
+ !/^sha256:[0-9a-f]{64}$/.test(request.expectedStateDigest)) ||
264
+ request.anchor.revision !== (request.expectedRevision ?? -1) + 1)
265
+ return false;
266
+ const client = await this.poolConnect();
267
+ try {
268
+ await client.query("BEGIN");
269
+ await client.query("SELECT pg_advisory_xact_lock(hashtextextended($1, 0))", [`${this.tenantId}:collective-telemetry-anchor:${request.anchorKey}`]);
270
+ const retained = await client.query(`SELECT revision, sequence, state_digest, logical_time_high_water_ms
271
+ FROM ${this.table}
272
+ WHERE tenant_id = $1 AND anchor_key = $2`, [this.tenantId, request.anchorKey]);
273
+ const current = retained.rows[0]
274
+ ? telemetryAnchorFromRow(retained.rows[0])
275
+ : null;
276
+ if ((current?.revision ?? null) !== request.expectedRevision ||
277
+ (current?.stateDigest ?? null) !== request.expectedStateDigest ||
278
+ request.anchor.sequence < (current?.sequence ?? -1) ||
279
+ request.anchor.logicalTimeHighWaterMs <
280
+ (current?.logicalTimeHighWaterMs ?? -1)) {
281
+ await client.query("ROLLBACK");
282
+ return false;
283
+ }
284
+ const advanced = current === null
285
+ ? await client.query(`INSERT INTO ${this.table}
286
+ (tenant_id, anchor_key, revision, sequence, state_digest,
287
+ logical_time_high_water_ms, previous_state_digest)
288
+ VALUES ($1,$2,$3,$4,$5,$6,NULL)
289
+ ON CONFLICT DO NOTHING`, [
290
+ this.tenantId,
291
+ request.anchorKey,
292
+ request.anchor.revision,
293
+ request.anchor.sequence,
294
+ request.anchor.stateDigest,
295
+ request.anchor.logicalTimeHighWaterMs,
296
+ ])
297
+ : await client.query(`UPDATE ${this.table}
298
+ SET revision = $4, sequence = $5, state_digest = $6,
299
+ logical_time_high_water_ms = $7,
300
+ previous_state_digest = $8
301
+ WHERE tenant_id = $1 AND anchor_key = $2
302
+ AND revision = $3 AND state_digest = $8`, [
303
+ this.tenantId,
304
+ request.anchorKey,
305
+ request.expectedRevision,
306
+ request.anchor.revision,
307
+ request.anchor.sequence,
308
+ request.anchor.stateDigest,
309
+ request.anchor.logicalTimeHighWaterMs,
310
+ request.expectedStateDigest,
311
+ ]);
312
+ if ((advanced.rowCount ?? 0) !== 1) {
313
+ await client.query("ROLLBACK");
314
+ return false;
315
+ }
316
+ await client.query("COMMIT");
317
+ return true;
318
+ }
319
+ catch (error) {
320
+ await client.query("ROLLBACK").catch(() => undefined);
321
+ throw error;
322
+ }
323
+ finally {
324
+ client.release();
325
+ }
326
+ }
327
+ }
328
+ function telemetryAnchorFromRow(row) {
329
+ const anchor = Object.freeze({
330
+ revision: Number(row.revision),
331
+ sequence: Number(row.sequence),
332
+ stateDigest: row.state_digest,
333
+ logicalTimeHighWaterMs: Number(row.logical_time_high_water_ms),
334
+ });
335
+ validateTelemetryAnchor(anchor);
336
+ return anchor;
337
+ }
338
+ function validateTelemetryAnchor(anchor) {
339
+ if (!anchor ||
340
+ !Number.isSafeInteger(anchor.revision) ||
341
+ anchor.revision < 0 ||
342
+ !Number.isSafeInteger(anchor.sequence) ||
343
+ anchor.sequence < 0 ||
344
+ anchor.sequence !== anchor.revision ||
345
+ !Number.isSafeInteger(anchor.logicalTimeHighWaterMs) ||
346
+ anchor.logicalTimeHighWaterMs < 0 ||
347
+ !/^sha256:[0-9a-f]{64}$/.test(anchor.stateDigest))
348
+ throw new TypeError("collective telemetry anchor is invalid");
349
+ }
350
+ function validateTelemetryIdentifier(value, label) {
351
+ if (!/^[A-Za-z0-9][A-Za-z0-9._:@/+-=]{0,255}$/.test(value))
352
+ throw new TypeError(`collective telemetry ${label} is invalid`);
353
+ }
4
354
  /** Append-only, redacting PostgreSQL AuditSink. */
5
355
  export class PostgresAuditSink {
6
356
  pool;
7
357
  table;
8
358
  constructor(pool, options = {}) {
9
359
  this.pool = pool;
10
- this.table = qualifyPostgresName(options.schema ?? defaultPostgresSchema, 'audit_records');
360
+ this.table = qualifyPostgresName(options.schema ?? defaultPostgresSchema, "audit_records");
11
361
  }
12
362
  async write(record) {
13
363
  await this.pool.query(`INSERT INTO ${this.table} (
@@ -34,7 +384,7 @@ export class PostgresSessionEventSink {
34
384
  table;
35
385
  constructor(pool, options = {}) {
36
386
  this.pool = pool;
37
- this.table = qualifyPostgresName(options.schema ?? defaultPostgresSchema, 'session_events');
387
+ this.table = qualifyPostgresName(options.schema ?? defaultPostgresSchema, "session_events");
38
388
  }
39
389
  async append(record) {
40
390
  const event = redactAuditDetails(record.event);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAGtD,OAAO,EACL,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAOzB,mDAAmD;AACnD,MAAM,OAAO,iBAAiB;IAIT;IAHF,KAAK,CAAS;IAE/B,YACmB,IAAU,EAC3B,UAA+B,EAAE;QADhB,SAAI,GAAJ,IAAI,CAAM;QAG3B,IAAI,CAAC,KAAK,GAAG,mBAAmB,CAC9B,OAAO,CAAC,MAAM,IAAI,qBAAqB,EACvC,eAAe,CAChB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,MAAmB;QAC7B,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnB,eAAe,IAAI,CAAC,KAAK;;;;8CAIe,EACxC;YACE,MAAM,CAAC,QAAQ;YACf,MAAM,CAAC,EAAE;YACT,MAAM,CAAC,OAAO,IAAI,IAAI;YACtB,MAAM,CAAC,SAAS,IAAI,IAAI;YACxB,MAAM,CAAC,MAAM;YACb,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC;YAC/B,IAAI,CAAC,SAAS,CACZ,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CACzD;YACD,MAAM,CAAC,SAAS,IAAI,IAAI;YACxB,MAAM,CAAC,SAAS,IAAI,IAAI;YACxB,MAAM,CAAC,SAAS;SACjB,CACF,CAAC;IACJ,CAAC;CACF;AAED,4EAA4E;AAC5E,MAAM,OAAO,wBAAwB;IAIhB;IAHF,KAAK,CAAS;IAE/B,YACmB,IAAU,EAC3B,UAA+B,EAAE;QADhB,SAAI,GAAJ,IAAI,CAAM;QAG3B,IAAI,CAAC,KAAK,GAAG,mBAAmB,CAC9B,OAAO,CAAC,MAAM,IAAI,qBAAqB,EACvC,gBAAgB,CACjB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAA0B;QACrC,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,CAAC,KAA8B,CAAC,CAAC;QACxE,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnB,eAAe,IAAI,CAAC,KAAK;;;oDAGqB,EAC9C;YACE,MAAM,CAAC,QAAQ;YACf,MAAM,CAAC,SAAS;YAChB,MAAM,CAAC,QAAQ;YACf,MAAM,CAAC,OAAO;YACd,MAAM,CAAC,UAAU;YACjB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;SACtB,CACF,CAAC;IACJ,CAAC;CACF;AAED,MAAM,UAAU,uBAAuB,CACrC,IAAU,EACV,OAA6B;IAE7B,OAAO,IAAI,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,IAAU,EACV,OAA6B;IAE7B,OAAO,IAAI,wBAAwB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import type { PostgresMigrationStatus } from '@agentplat/postgres';
2
- import type { Pool } from 'pg';
1
+ import type { PostgresMigrationStatus } from "@agentplat/postgres";
2
+ import type { Pool } from "pg";
3
3
  export declare const auditMigrationDirectory: string;
4
4
  export interface AuditPostgresMigrationOptions {
5
5
  schema?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAEV,uBAAuB,EACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAK/B,eAAO,MAAM,uBAAuB,QAEnC,CAAC;AAEF,MAAM,WAAW,6BAA6B;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAwBD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,IAAI,EACV,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,uBAAuB,CAAC,CAOlC;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,IAAI,EACV,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,uBAAuB,CAAC,CAMlC;AAED,wBAAgB,yBAAyB,CACvC,MAAM,SAAwB,EAC9B,OAAO,SAAI,GACV,MAAM,CAER;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,6BAA6B,GAAG;IACvC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GACA,OAAO,CAAC,uBAAuB,CAAC,CAUlC"}
1
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAEV,uBAAuB,EACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAU/B,eAAO,MAAM,uBAAuB,QAEnC,CAAC;AAEF,MAAM,WAAW,6BAA6B;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAoBD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,IAAI,EACV,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,uBAAuB,CAAC,CAOlC;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,IAAI,EACV,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,uBAAuB,CAAC,CAMlC;AAED,wBAAgB,yBAAyB,CACvC,MAAM,SAAwB,EAC9B,OAAO,SAAI,GACV,MAAM,CAER;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,6BAA6B,GAAG;IACvC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GACA,OAAO,CAAC,uBAAuB,CAAC,CAUlC"}
@@ -1,23 +1,22 @@
1
- import { readFile } from 'node:fs/promises';
2
- import { fileURLToPath } from 'node:url';
3
- import { defaultPostgresSchema, getPostgresMigrationStatus, postgresRollbackConfirmation, rollbackPostgresMigration, runPostgresMigrations, } from '@agentplat/postgres';
4
- const applicationId = '@agentplat/audit-postgres';
5
- const migrationName = '001_audit_and_session_events';
6
- export const auditMigrationDirectory = fileURLToPath(new URL('../migrations/', import.meta.url));
1
+ import { readFile } from "node:fs/promises";
2
+ import { fileURLToPath } from "node:url";
3
+ import { defaultPostgresSchema, getPostgresMigrationStatus, postgresRollbackConfirmation, rollbackPostgresMigration, runPostgresMigrations, } from "@agentplat/postgres";
4
+ const applicationId = "@agentplat/audit-postgres";
5
+ const migrationNames = [
6
+ "001_audit_and_session_events",
7
+ "002_collective_telemetry",
8
+ "003_collective_telemetry_delivery_receipts",
9
+ "004_collective_telemetry_monotonic_anchors",
10
+ ];
11
+ export const auditMigrationDirectory = fileURLToPath(new URL("../migrations/", import.meta.url));
7
12
  async function migrations() {
8
- const [up, down] = await Promise.all([
9
- readFile(new URL(`../migrations/${migrationName}.up.sql`, import.meta.url), 'utf8'),
10
- readFile(new URL(`../migrations/${migrationName}.down.sql`, import.meta.url), 'utf8'),
11
- ]);
12
- return [
13
- {
14
- version: 1,
15
- name: migrationName,
16
- up,
17
- down,
18
- destructiveDown: true,
19
- },
20
- ];
13
+ return Promise.all(migrationNames.map(async (name, index) => {
14
+ const [up, down] = await Promise.all([
15
+ readFile(new URL(`../migrations/${name}.up.sql`, import.meta.url), "utf8"),
16
+ readFile(new URL(`../migrations/${name}.down.sql`, import.meta.url), "utf8"),
17
+ ]);
18
+ return { version: index + 1, name, up, down, destructiveDown: true };
19
+ }));
21
20
  }
22
21
  export async function runAuditMigrations(pool, options = {}) {
23
22
  return runPostgresMigrations(pool, {
@@ -34,7 +33,7 @@ export async function getAuditMigrationStatus(pool, options = {}) {
34
33
  migrations: await migrations(),
35
34
  });
36
35
  }
37
- export function auditRollbackConfirmation(schema = defaultPostgresSchema, version = 1) {
36
+ export function auditRollbackConfirmation(schema = defaultPostgresSchema, version = 4) {
38
37
  return postgresRollbackConfirmation(applicationId, schema, version);
39
38
  }
40
39
  export async function rollbackAuditMigrations(pool, options) {
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACL,qBAAqB,EACrB,0BAA0B,EAC1B,4BAA4B,EAC5B,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAO7B,MAAM,aAAa,GAAG,2BAA2B,CAAC;AAClD,MAAM,aAAa,GAAG,8BAA8B,CAAC;AAErD,MAAM,CAAC,MAAM,uBAAuB,GAAG,aAAa,CAClD,IAAI,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAC3C,CAAC;AAOF,KAAK,UAAU,UAAU;IACvB,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACnC,QAAQ,CACN,IAAI,GAAG,CAAC,iBAAiB,aAAa,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EACjE,MAAM,CACP;QACD,QAAQ,CACN,IAAI,GAAG,CAAC,iBAAiB,aAAa,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EACnE,MAAM,CACP;KACF,CAAC,CAAC;IACH,OAAO;QACL;YACE,OAAO,EAAE,CAAC;YACV,IAAI,EAAE,aAAa;YACnB,EAAE;YACF,IAAI;YACJ,eAAe,EAAE,IAAI;SACtB;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAU,EACV,UAAyC,EAAE;IAE3C,OAAO,qBAAqB,CAAC,IAAI,EAAE;QACjC,aAAa;QACb,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,UAAU,EAAE,MAAM,UAAU,EAAE;KAC/B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAAU,EACV,UAAyC,EAAE;IAE3C,OAAO,0BAA0B,CAAC,IAAI,EAAE;QACtC,aAAa;QACb,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,UAAU,EAAE,MAAM,UAAU,EAAE;KAC/B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,MAAM,GAAG,qBAAqB,EAC9B,OAAO,GAAG,CAAC;IAEX,OAAO,4BAA4B,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAAU,EACV,OAIC;IAED,OAAO,yBAAyB,CAAC,IAAI,EAAE;QACrC,aAAa;QACb,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,YAAY,EAAE,KAAK;QACnB,UAAU,EAAE,MAAM,UAAU,EAAE;QAC9B,sBAAsB,EAAE,OAAO,CAAC,sBAAsB;QACtD,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,aAAa,EAAE,OAAO,CAAC,aAAa;KACrC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACL,qBAAqB,EACrB,0BAA0B,EAC1B,4BAA4B,EAC5B,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAO7B,MAAM,aAAa,GAAG,2BAA2B,CAAC;AAClD,MAAM,cAAc,GAAG;IACrB,8BAA8B;IAC9B,0BAA0B;IAC1B,4CAA4C;IAC5C,4CAA4C;CACpC,CAAC;AAEX,MAAM,CAAC,MAAM,uBAAuB,GAAG,aAAa,CAClD,IAAI,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAC3C,CAAC;AAOF,KAAK,UAAU,UAAU;IACvB,OAAO,OAAO,CAAC,GAAG,CAChB,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACvC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACnC,QAAQ,CACN,IAAI,GAAG,CAAC,iBAAiB,IAAI,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EACxD,MAAM,CACP;YACD,QAAQ,CACN,IAAI,GAAG,CAAC,iBAAiB,IAAI,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAC1D,MAAM,CACP;SACF,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;IACvE,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAU,EACV,UAAyC,EAAE;IAE3C,OAAO,qBAAqB,CAAC,IAAI,EAAE;QACjC,aAAa;QACb,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,UAAU,EAAE,MAAM,UAAU,EAAE;KAC/B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAAU,EACV,UAAyC,EAAE;IAE3C,OAAO,0BAA0B,CAAC,IAAI,EAAE;QACtC,aAAa;QACb,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,UAAU,EAAE,MAAM,UAAU,EAAE;KAC/B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,MAAM,GAAG,qBAAqB,EAC9B,OAAO,GAAG,CAAC;IAEX,OAAO,4BAA4B,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAAU,EACV,OAIC;IAED,OAAO,yBAAyB,CAAC,IAAI,EAAE;QACrC,aAAa;QACb,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,YAAY,EAAE,KAAK;QACnB,UAAU,EAAE,MAAM,UAAU,EAAE;QAC9B,sBAAsB,EAAE,OAAO,CAAC,sBAAsB;QACtD,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,aAAa,EAAE,OAAO,CAAC,aAAa;KACrC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,4 @@
1
+ DROP TRIGGER IF EXISTS collective_telemetry_events_append_only_delete ON __AGENTPLAT_SCHEMA__.collective_telemetry_events;
2
+ DROP TRIGGER IF EXISTS collective_telemetry_events_append_only_update ON __AGENTPLAT_SCHEMA__.collective_telemetry_events;
3
+ DROP TABLE IF EXISTS __AGENTPLAT_SCHEMA__.collective_telemetry_events;
4
+ DROP TABLE IF EXISTS __AGENTPLAT_SCHEMA__.collective_telemetry_states;
@@ -0,0 +1,34 @@
1
+ CREATE TABLE __AGENTPLAT_SCHEMA__.collective_telemetry_states (
2
+ tenant_id text NOT NULL,
3
+ stream_id text NOT NULL,
4
+ revision bigint NOT NULL CHECK (revision >= 0),
5
+ sequence bigint NOT NULL CHECK (sequence >= 0),
6
+ logical_time_high_water_ms bigint NOT NULL CHECK (logical_time_high_water_ms >= 0),
7
+ state_digest text NOT NULL CHECK (state_digest ~ '^sha256:[0-9a-f]{64}$'),
8
+ state jsonb NOT NULL CHECK (jsonb_typeof(state) = 'object'),
9
+ updated_at timestamptz NOT NULL DEFAULT transaction_timestamp(),
10
+ PRIMARY KEY (tenant_id, stream_id)
11
+ );
12
+
13
+ CREATE TABLE __AGENTPLAT_SCHEMA__.collective_telemetry_events (
14
+ tenant_id text NOT NULL,
15
+ stream_id text NOT NULL,
16
+ sequence bigint NOT NULL CHECK (sequence > 0),
17
+ event_id text NOT NULL,
18
+ event_digest text NOT NULL CHECK (event_digest ~ '^sha256:[0-9a-f]{64}$'),
19
+ event jsonb NOT NULL CHECK (jsonb_typeof(event) = 'object'),
20
+ PRIMARY KEY (tenant_id, event_id),
21
+ UNIQUE (tenant_id, stream_id, sequence)
22
+ );
23
+
24
+ CREATE INDEX collective_telemetry_states_updated_idx
25
+ ON __AGENTPLAT_SCHEMA__.collective_telemetry_states (tenant_id, updated_at DESC);
26
+ CREATE INDEX collective_telemetry_events_stream_idx
27
+ ON __AGENTPLAT_SCHEMA__.collective_telemetry_events (tenant_id, stream_id, sequence);
28
+
29
+ CREATE TRIGGER collective_telemetry_events_append_only_update
30
+ BEFORE UPDATE ON __AGENTPLAT_SCHEMA__.collective_telemetry_events
31
+ FOR EACH ROW EXECUTE FUNCTION __AGENTPLAT_SCHEMA__.agentplat_prevent_audit_mutation();
32
+ CREATE TRIGGER collective_telemetry_events_append_only_delete
33
+ BEFORE DELETE ON __AGENTPLAT_SCHEMA__.collective_telemetry_events
34
+ FOR EACH ROW EXECUTE FUNCTION __AGENTPLAT_SCHEMA__.agentplat_prevent_audit_mutation();
@@ -0,0 +1 @@
1
+ DROP TABLE IF EXISTS __AGENTPLAT_SCHEMA__.collective_telemetry_delivery_receipts;
@@ -0,0 +1,21 @@
1
+ CREATE TABLE __AGENTPLAT_SCHEMA__.collective_telemetry_delivery_receipts (
2
+ tenant_id text NOT NULL,
3
+ stream_id text NOT NULL,
4
+ delivery_digest text NOT NULL CHECK (delivery_digest ~ '^sha256:[0-9a-f]{64}$'),
5
+ record_input_digest text NOT NULL CHECK (record_input_digest ~ '^sha256:[0-9a-f]{64}$'),
6
+ event_digest text NOT NULL CHECK (event_digest ~ '^sha256:[0-9a-f]{64}$'),
7
+ sequence bigint NOT NULL CHECK (sequence > 0),
8
+ created_at timestamptz NOT NULL DEFAULT transaction_timestamp(),
9
+ PRIMARY KEY (tenant_id, stream_id, delivery_digest),
10
+ FOREIGN KEY (tenant_id, stream_id)
11
+ REFERENCES __AGENTPLAT_SCHEMA__.collective_telemetry_states (tenant_id, stream_id)
12
+ ON DELETE RESTRICT,
13
+ FOREIGN KEY (tenant_id, stream_id, sequence)
14
+ REFERENCES __AGENTPLAT_SCHEMA__.collective_telemetry_events
15
+ (tenant_id, stream_id, sequence)
16
+ ON DELETE RESTRICT
17
+ );
18
+
19
+ CREATE INDEX collective_telemetry_delivery_receipts_capacity_idx
20
+ ON __AGENTPLAT_SCHEMA__.collective_telemetry_delivery_receipts
21
+ (tenant_id, created_at ASC);
@@ -0,0 +1,2 @@
1
+ DROP TABLE IF EXISTS __AGENTPLAT_SCHEMA__.collective_telemetry_monotonic_anchors;
2
+ DROP FUNCTION IF EXISTS __AGENTPLAT_SCHEMA__.agentplat_enforce_telemetry_anchor_advance();
@@ -0,0 +1,43 @@
1
+ CREATE TABLE __AGENTPLAT_SCHEMA__.collective_telemetry_monotonic_anchors (
2
+ tenant_id text NOT NULL,
3
+ anchor_key text NOT NULL,
4
+ revision bigint NOT NULL CHECK (revision >= 0),
5
+ sequence bigint NOT NULL CHECK (sequence >= 0),
6
+ state_digest text NOT NULL CHECK (state_digest ~ '^sha256:[0-9a-f]{64}$'),
7
+ logical_time_high_water_ms bigint NOT NULL CHECK (logical_time_high_water_ms >= 0),
8
+ previous_state_digest text NULL CHECK (
9
+ previous_state_digest IS NULL OR
10
+ previous_state_digest ~ '^sha256:[0-9a-f]{64}$'
11
+ ),
12
+ created_at timestamptz NOT NULL DEFAULT transaction_timestamp(),
13
+ updated_at timestamptz NOT NULL DEFAULT transaction_timestamp(),
14
+ PRIMARY KEY (tenant_id, anchor_key),
15
+ CHECK ((revision = 0) = (previous_state_digest IS NULL)),
16
+ CHECK (revision = sequence)
17
+ );
18
+
19
+ CREATE FUNCTION __AGENTPLAT_SCHEMA__.agentplat_enforce_telemetry_anchor_advance()
20
+ RETURNS trigger
21
+ LANGUAGE plpgsql
22
+ AS $agentplat$
23
+ BEGIN
24
+ IF NEW.tenant_id <> OLD.tenant_id OR
25
+ NEW.anchor_key <> OLD.anchor_key OR
26
+ NEW.revision <> OLD.revision + 1 OR
27
+ NEW.sequence <> OLD.sequence + 1 OR
28
+ NEW.previous_state_digest <> OLD.state_digest OR
29
+ NEW.created_at <> OLD.created_at OR
30
+ NEW.logical_time_high_water_ms < OLD.logical_time_high_water_ms THEN
31
+ RAISE EXCEPTION 'collective telemetry monotonic anchor must advance exactly once';
32
+ END IF;
33
+ NEW.updated_at := transaction_timestamp();
34
+ RETURN NEW;
35
+ END
36
+ $agentplat$;
37
+
38
+ CREATE TRIGGER collective_telemetry_monotonic_anchors_monotonic_update
39
+ BEFORE UPDATE ON __AGENTPLAT_SCHEMA__.collective_telemetry_monotonic_anchors
40
+ FOR EACH ROW EXECUTE FUNCTION __AGENTPLAT_SCHEMA__.agentplat_enforce_telemetry_anchor_advance();
41
+ CREATE TRIGGER collective_telemetry_monotonic_anchors_append_only_delete
42
+ BEFORE DELETE ON __AGENTPLAT_SCHEMA__.collective_telemetry_monotonic_anchors
43
+ FOR EACH ROW EXECUTE FUNCTION __AGENTPLAT_SCHEMA__.agentplat_prevent_audit_mutation();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentplat/audit-postgres",
3
- "version": "0.3.0-beta.2",
3
+ "version": "0.3.0-beta.5",
4
4
  "description": "PostgreSQL audit and session event sinks for AgentPlat without Agent Rooms.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -21,10 +21,10 @@
21
21
  "dependencies": {
22
22
  "@types/pg": "^8.11.10",
23
23
  "pg": "^8.13.1",
24
- "@agentplat/audit": "^0.3.0-beta.2",
25
- "@agentplat/sessions": "^0.3.0-beta.2",
26
- "@agentplat/postgres": "^0.3.0-beta.2",
27
- "@agentplat/core": "^0.3.0-beta.2"
24
+ "@agentplat/audit": "^0.3.0-beta.5",
25
+ "@agentplat/core": "^0.3.0-beta.5",
26
+ "@agentplat/postgres": "^0.3.0-beta.5",
27
+ "@agentplat/sessions": "^0.3.0-beta.5"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/node": "^20.10.0"