Merge branch 'codex/sleep-03-gateway-credential-expiry' into codex/sleep-04-tool-review-expiry

* codex/sleep-03-gateway-credential-expiry:
  perf(server): bound gateway expiry deadline discovery

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-24 10:09:27 -07:00
commit 36e1c9f23e
7 files changed
+57 -8

No files matched your search

+9 -1
View File
@@ -26,7 +26,9 @@ reconstructs existing rows but does not provide continuous replica discovery.
## Worker contract
`nextCredentialExpiryAt` reads the earliest non-null expiry across both tables.
`nextCredentialExpiryAt` reads one earliest non-null expiry from each table using
expiry-first indexes, then compares those at most two values. The migration adds
the session expiry index; the token expiry index already exists.
An empty credential store or retained non-expiring tokens returns no deadline.
`registerGatewayCredentialExpiryWork` supplies cleanup and deadline selection to
the shared `registerDeadlineWork` helper. Provider and authentication behavior
@@ -47,6 +49,12 @@ in-flight work.
## Evidence and limits
The concurrent session index runs through the migration executor's existing
per-file top-level path. Initial application and repeat application were tested.
A PostgreSQL plan with 20,000 sessions and 20,000 tokens, including 19,000
non-expiring tokens, used both expiry indexes and read one row from each.
This establishes bounded lookup on that fixture, not production latency.
The new PostgreSQL suite exercises real session/token creation, configured idle
state, non-expiring history, expiry ordering, revoked-token cleanup, outer commit
and rollback, startup reconstruction, a backlog larger than one cleanup batch,
+1
View File
@@ -504,6 +504,7 @@ const MIGRATIONS_WITH_TOP_LEVEL_STATEMENTS = new Set([
"0332_little_night_nurse.sql",
"0345_luxuriant_carmella_unuscione.sql",
"0369_late_logan.sql",
"0378_mean_scream.sql",
]);
async function applyPendingMigrationsManually(
@@ -0,0 +1 @@
CREATE INDEX CONCURRENTLY IF NOT EXISTS "tool_gateway_sessions_expiry_idx" ON "tool_gateway_sessions" USING btree ("expires_at");
@@ -1,6 +1,6 @@
{
"id": "406521f8-5352-415b-805d-786854381e03",
"prevId": "9c1b4cac-52f1-4c6e-89b3-c9a7816016c7",
"id": "01c4455a-e59c-43e6-940b-09b9c76171d8",
"prevId": "a0fcd9b8-f125-4985-8795-f567466b9aef",
"version": "7",
"dialect": "postgresql",
"tables": {
@@ -28508,6 +28508,13 @@
"primaryKey": false,
"notNull": true
},
"checkout_name": {
"name": "checkout_name",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "''"
},
"object_key": {
"name": "object_key",
"type": "text",
@@ -28601,8 +28608,8 @@
"method": "btree",
"with": {}
},
"execution_workspace_restore_points_live_generation_uniq": {
"name": "execution_workspace_restore_points_live_generation_uniq",
"execution_workspace_restore_points_live_status_uniq": {
"name": "execution_workspace_restore_points_live_status_uniq",
"columns": [
{
"expression": "execution_workspace_id",
@@ -28615,10 +28622,16 @@
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "checkout_name",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"where": "\"execution_workspace_restore_points\".\"status\" <> 'deleted'",
"where": "\"execution_workspace_restore_points\".\"status\" in ('pending', 'active', 'expiring')",
"concurrently": false,
"method": "btree",
"with": {}
@@ -55184,6 +55197,21 @@
"method": "btree",
"with": {}
},
"tool_gateway_sessions_expiry_idx": {
"name": "tool_gateway_sessions_expiry_idx",
"columns": [
{
"expression": "expires_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"tool_gateway_sessions_run_idx": {
"name": "tool_gateway_sessions_run_idx",
"columns": [
+7
View File
@@ -2633,6 +2633,13 @@
"when": 1792790134086,
"tag": "0377_clear_settled_native_run_process_identity",
"breakpoints": true
},
{
"idx": 378,
"version": "7",
"when": 1792861534317,
"tag": "0378_mean_scream",
"breakpoints": true
}
]
}
+1
View File
@@ -710,6 +710,7 @@ export const toolGatewaySessions = pgTable(
uniqueIndex("tool_gateway_sessions_token_hash_uq").on(table.tokenHash),
index("tool_gateway_sessions_company_agent_idx").on(table.companyId, table.agentId),
index("tool_gateway_sessions_company_expires_idx").on(table.companyId, table.expiresAt),
index("tool_gateway_sessions_expiry_idx").on(table.expiresAt),
index("tool_gateway_sessions_run_idx").on(table.companyId, table.runId),
index("tool_gateway_sessions_issue_idx").on(table.companyId, table.issueId),
index("tool_gateway_sessions_gateway_idx").on(table.companyId, table.gatewayId),
+5 -2
View File
@@ -11609,9 +11609,12 @@ export function createToolGatewayService(
async nextCredentialExpiryAt(): Promise<number | null> {
const [row] = await db.execute<{ at: string | Date | null }>(sql`
select min(expires_at) as at from (
select ${toolMcpGatewayTokens.expiresAt} as expires_at from ${toolMcpGatewayTokens}
(select ${toolMcpGatewayTokens.expiresAt} as expires_at from ${toolMcpGatewayTokens}
where ${toolMcpGatewayTokens.expiresAt} is not null
order by ${toolMcpGatewayTokens.expiresAt} limit 1)
union all
select ${toolGatewaySessions.expiresAt} as expires_at from ${toolGatewaySessions}
(select ${toolGatewaySessions.expiresAt} as expires_at from ${toolGatewaySessions}
order by ${toolGatewaySessions.expiresAt} limit 1)
) expiries
`);
return row?.at == null ? null : new Date(row.at).getTime();