@poppykit/server 0.5.0 → 0.5.1

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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  Local migration block2 adds Operations v2 codecs, negotiated API/MCP/conversation mechanics and durable revision ownership, execution claims, local atomic effects and host external reconciliation. See [OPERATIONS.md](OPERATIONS.md). This is a local SDK checkpoint, not full CLI integration or package publication.
4
4
 
5
+ ## 0.5.1 — 2026-11-01
6
+
7
+ Handle PostgreSQL socket loss while an SDK transaction or migration owns a
8
+ checked-out connection. Invalidate failed transaction handles, discard broken
9
+ connections, and preserve the original migration error when rollback also fails.
10
+ A failed COMMIT still requires durable-state reconciliation before retry.
11
+
5
12
  ## 0.5.0 — current-spec core migration
6
13
 
7
14
  Separate delegated resource Sessions from OAuth account grants; discover issuers and
package/STORAGE.md CHANGED
@@ -235,3 +235,9 @@ shared handles. See [legacy retirement](migrations/RETIREMENT.md) before any del
235
235
  ## Business operation persistence
236
236
 
237
237
  [Operations storage contracts](OPERATIONS.md#store-contract-retention-and-migration) are separate from authentication lifecycle operations and message receipts. BusinessOperationStore uses an asynchronous transaction for same-database effects, unlike synchronous issuer/conversation callbacks. SQLite and PostgreSQL use the separate business_operations record kind. Use the same company database instance for policy, operation storage and local effects. No existing SQL history, credentials or uncertain work is deleted. Unknown versions fail closed. External effects require a durable downstream idempotency/reconciliation contract. Never prune or release an uncertain business claim after a worker deadline.
238
+
239
+ Postgres adapters handle socket errors while they own a checked-out connection.
240
+ Connection loss invalidates the transaction, rejects the operation and discards
241
+ the broken connection. A successful retry must reconcile durable state first;
242
+ a lost COMMIT response does not prove rollback. Callers still own their pool and
243
+ its idle `error` handler, and host-enlisted connection lifetimes.
@@ -35,6 +35,9 @@ export async function postgresMigration(schema) {
35
35
  export async function migratePostgres(pool, schema) {
36
36
  schemaName(schema);
37
37
  const client = await pool.connect();
38
+ let connectionError;
39
+ const onError = (error) => { connectionError = error; };
40
+ client.on('error', onError);
38
41
  try {
39
42
  await client.query('BEGIN');
40
43
  await client.query("SET LOCAL statement_timeout='5s'");
@@ -50,11 +53,12 @@ export async function migratePostgres(pool, schema) {
50
53
  await client.query('COMMIT');
51
54
  }
52
55
  catch (error) {
53
- await client.query('ROLLBACK');
56
+ await client.query('ROLLBACK').catch((failure) => { connectionError = failure; });
54
57
  throw error;
55
58
  }
56
59
  finally {
57
- client.release();
60
+ client.release(connectionError);
61
+ client.removeListener('error', onError);
58
62
  }
59
63
  }
60
64
  function scopeActive(context) {
@@ -117,6 +121,9 @@ export class PostgresRuntime {
117
121
  }
118
122
  }
119
123
  const client = await this.pool.connect(), context = { client, active: true, locks: new Set(), state: { serial: 0, active: true }, childActive: false };
124
+ let connectionError;
125
+ const onError = (error) => { connectionError = error; context.state.active = false; };
126
+ client.on('error', onError);
120
127
  try {
121
128
  await client.query('BEGIN');
122
129
  await client.query("SET LOCAL statement_timeout='5s'");
@@ -134,13 +141,14 @@ export class PostgresRuntime {
134
141
  }
135
142
  catch (error) {
136
143
  context.state.active = false;
137
- await client.query('ROLLBACK').catch(() => { });
144
+ await client.query('ROLLBACK').catch((failure) => { connectionError = failure; });
138
145
  throw error;
139
146
  }
140
147
  finally {
141
148
  context.active = false;
142
149
  context.state.active = false;
143
- client.release();
150
+ client.release(connectionError);
151
+ client.removeListener('error', onError);
144
152
  }
145
153
  }
146
154
  connection() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poppykit/server",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "private": false,
5
5
  "description": "Personal Agent Protocol company SDK",
6
6
  "repository": {