From 5cd5e14160bfe38afa61c50f5ceb158720ea3559 Mon Sep 17 00:00:00 2001 From: Mikael Hugo Date: Fri, 15 May 2026 18:16:08 +0200 Subject: [PATCH] feat(headless): surface memory auth pause --- src/headless-query.ts | 26 +++++++++++++++++++ .../headless-query-memory-extraction.test.ts | 3 +++ 2 files changed, 29 insertions(+) diff --git a/src/headless-query.ts b/src/headless-query.ts index a5ca374bc..634d3042d 100644 --- a/src/headless-query.ts +++ b/src/headless-query.ts @@ -185,6 +185,12 @@ export interface QuerySnapshot { }; memoryExtraction?: { total_attempts: number; + subsystem_pause: { + paused: boolean; + reason: string | null; + unit_key: string | null; + created_at: string | null; + }; recent_attempts: Array<{ unit_key: string; status: string; @@ -439,8 +445,28 @@ export async function buildQuerySnapshot( adapter ?.prepare("SELECT count(*) AS cnt FROM memory_extraction_attempts") .get()?.cnt ?? recent.length; + const latestAuthFailure = + adapter + ?.prepare(`SELECT unit_key, reason, created_at + FROM memory_extraction_attempts + WHERE status = 'error' AND failure_class = 'auth' + ORDER BY created_at DESC, id DESC + LIMIT 1`) + .get() ?? null; memoryExtraction = { total_attempts: Number(total), + subsystem_pause: { + paused: !!latestAuthFailure, + reason: latestAuthFailure?.reason + ? String(latestAuthFailure.reason) + : null, + unit_key: latestAuthFailure?.unit_key + ? String(latestAuthFailure.unit_key) + : null, + created_at: latestAuthFailure?.created_at + ? String(latestAuthFailure.created_at) + : null, + }, recent_attempts: recent.map((row) => ({ unit_key: String(row.unit_key ?? ""), status: String(row.status ?? ""), diff --git a/src/tests/headless-query-memory-extraction.test.ts b/src/tests/headless-query-memory-extraction.test.ts index d36e59e8b..8d3accb22 100644 --- a/src/tests/headless-query-memory-extraction.test.ts +++ b/src/tests/headless-query-memory-extraction.test.ts @@ -21,6 +21,8 @@ const querySrc = readFileSync( test("QuerySnapshot type declares memoryExtraction section", () => { assert.match(querySrc, /memoryExtraction\?:/); assert.match(querySrc, /total_attempts:\s*number/); + assert.match(querySrc, /subsystem_pause:/); + assert.match(querySrc, /paused:\s*boolean/); assert.match(querySrc, /recent_attempts:/); assert.match(querySrc, /failure_class:\s*string \| null/); }); @@ -29,4 +31,5 @@ test("buildQuerySnapshot reads memory extraction attempts", () => { assert.match(querySrc, /listMemoryExtractionAttempts\(5\)/); assert.match(querySrc, /memory_extraction_attempts/); assert.match(querySrc, /failure_class/); + assert.match(querySrc, /failure_class = 'auth'/); });