← back to Answer Cockpit
TK-11793: pane batch TTL 12s + warmed once per build (/api/queue 12.6s → fast); E2E proven: posting the LABEL 'Bravo' → server translated to 2 → session ANSWER_RECEIVED=Bravo
c938da940d104dc4af3377f257a9dda7025575d1 · 2026-09-15 23:51:09 -0700 · Steve Abrams
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Files touched
M lib/queue.jsM lib/transcript.js
Diff
commit c938da940d104dc4af3377f257a9dda7025575d1
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Sep 15 23:51:09 2026 -0700
TK-11793: pane batch TTL 12s + warmed once per build (/api/queue 12.6s → fast); E2E proven: posting the LABEL 'Bravo' → server translated to 2 → session ANSWER_RECEIVED=Bravo
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
---
lib/queue.js | 1 +
lib/transcript.js | 5 ++++-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/lib/queue.js b/lib/queue.js
index 578d12f..ada641e 100644
--- a/lib/queue.js
+++ b/lib/queue.js
@@ -191,6 +191,7 @@ async function build(opts = {}) {
const byTk = memo.byTicket(memos);
const rows = res.rows.filter((r) => r.live && NEEDS_STEVE.has(r.color) && TTY_RE.test(String(r.tty)) && r.tty !== writeback.SELF_TTY);
rows.sort((a, b) => (a.variant === 'stopped' ? 0 : 1) - (b.variant === 'stopped' ? 0 : 1) || (PRIORITY[a.color] ?? 9) - (PRIORITY[b.color] ?? 9) || String(a.tty).localeCompare(String(b.tty)));
+ transcript.allPaneContents(); // warm ONE pane batch for every resolve below (and the detection pass)
const items = rows.map((r) => buildItem(r, byTk, opts));
// Pane-detected questions: a live claude session whose SCREEN shows a real AskUserQuestion
// menu but whose dot is not a needs-Steve color (none/green/pink — e.g. it could not dot
diff --git a/lib/transcript.js b/lib/transcript.js
index 347409b..ed5c072 100644
--- a/lib/transcript.js
+++ b/lib/transcript.js
@@ -234,7 +234,10 @@ function resolve(row) {
// instead of 23 calls). Cached 4s. Used both for per-tty detail and for the queue's
// "question on screen but dot not set" detection (pane truth beats dot truth).
let paneBatch = { ts: 0, map: new Map() };
-const PANE_BATCH_MS = 4000;
+// 12s: one batch (≈4.5s for ~30 sessions) must serve a whole /api/queue build — the scan alone
+// takes ~4s, so a 4s TTL expired mid-build and the batch was read 2-3× per request (12s+).
+// Writes never rely on this: guardTarget() calls invalidatePanes() before resolving.
+const PANE_BATCH_MS = 12000;
function invalidatePanes() { paneBatch = { ts: 0, map: paneBatch.map }; }
function allPaneContents() {
if (Date.now() - paneBatch.ts < PANE_BATCH_MS) return paneBatch.map;
← 2f37523 TK-11793: pane is authoritative for the on-screen menu on ev
·
back to Answer Cockpit
·
chore: lint, refactor, v0.2.0 (session close) 813fd6a →