aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-28 18:50:08 -0500
committerCraig Jennings <c@cjennings.net>2026-07-28 18:50:08 -0500
commit43a4cf73959e4f78bacbe5b3b40dde479377f9ff (patch)
tree0b9ea7fd68b9e0ef07e4bf13fae926ff601f3ee2
parentbff01385a17fd8435f202d70362db13a139774d6 (diff)
downloadrulesets-43a4cf73959e4f78bacbe5b3b40dde479377f9ff.tar.gz
rulesets-43a4cf73959e4f78bacbe5b3b40dde479377f9ff.zip
fix(triage): report a dead server after loadChats, not a quiet account
The load call returned 'loaded whatever happened. ignore-errors catches nothing there, because a bad argument kills the server process rather than signalling in elisp. A death during the load was invisible. The tail now returns 'server-died when the server is gone, and the recipe treats that as SCAN FAILED. A dead server leaves a thin chat hash, and a thin hash reads exactly like an account with little unread. That's the false all-clear the down/not-loaded rule already guards against, arriving one step later in the lifecycle. It's also the independent evidence the gotcha asks for when it says to treat a short chat list as a real short list. Without it the loadChats crash stayed invisible through two investigations. I used telega-server-live-p, the wrapper for the process-live-p expression the gotcha names. The fboundp guard comes from Step 0, which uses the same pair. A launch that failed outright leaves telega unloaded, and that should read as 'server-died rather than signalling void-function.
-rw-r--r--.ai/workflows/triage-intake.telegram.org22
-rw-r--r--claude-templates/.ai/workflows/triage-intake.telegram.org22
2 files changed, 42 insertions, 2 deletions
diff --git a/.ai/workflows/triage-intake.telegram.org b/.ai/workflows/triage-intake.telegram.org
index f8ac04b..1319da5 100644
--- a/.ai/workflows/triage-intake.telegram.org
+++ b/.ai/workflows/triage-intake.telegram.org
@@ -128,13 +128,33 @@ emacsclient -e "(progn
# NOTE: the chat-list argument must be a TL object, not the symbol 'main.
# `telega--loadChats' puts it straight into the request as :chat_list, and a
# bare symbol kills the server outright (see the SEGFAULT gotcha below).
-emacsclient -e "(progn (ignore-errors (telega--loadChats '(:@type \"chatListMain\"))) (ignore-errors (telega--loadChats '(:@type \"chatListMain\"))) 'loaded)"
+#
+# The liveness check on the tail is the load's only failure signal. `ignore-errors'
+# catches nothing here, because a bad argument kills the server process rather than
+# signalling in elisp, so without this the call returns 'loaded either way.
+# The `fboundp' guard matches Step 0: if the launch failed outright telega is not
+# loaded, and that should read as 'server-died like any other failure rather than
+# signalling void-function.
+emacsclient -e "(progn (ignore-errors (telega--loadChats '(:@type \"chatListMain\"))) (ignore-errors (telega--loadChats '(:@type \"chatListMain\"))) (if (and (fboundp 'telega-server-live-p) (telega-server-live-p)) 'loaded 'server-died))"
#+end_src
On a persisted session telega reaches status "Ready" within ~2s; the chat list
loads over a few more. If =(hash-table-count telega--chats)= is 0 or thin,
re-issue =telega--loadChats= and poll until it stabilizes.
+⚠ *=server-died= is SCAN FAILED, never a quiet account.* A server that dies
+during the load leaves a thin =telega--chats= hash, and a thin hash reads exactly
+like an account with little unread. That is the same false all-clear the
+down/not-loaded rule exists to prevent, arriving one step later in the lifecycle.
+It also fits the SCAN FAILED definition above: the launch was attempted and did
+not hold. So on =server-died=, report SCAN FAILED rather than scanning, and never
+report a low unread count from that run.
+
+This is the independent evidence the SEGFAULT gotcha asks for when it says to
+treat a short chat list as a real short list. Without the check there is no way
+to tell the two apart, which is how the =loadChats= crash stayed invisible
+through two investigations.
+
*** Step 2 — read unread, classified by last-message type
The single most important filter: =messageContactRegistered=. Telegram counts a
diff --git a/claude-templates/.ai/workflows/triage-intake.telegram.org b/claude-templates/.ai/workflows/triage-intake.telegram.org
index f8ac04b..1319da5 100644
--- a/claude-templates/.ai/workflows/triage-intake.telegram.org
+++ b/claude-templates/.ai/workflows/triage-intake.telegram.org
@@ -128,13 +128,33 @@ emacsclient -e "(progn
# NOTE: the chat-list argument must be a TL object, not the symbol 'main.
# `telega--loadChats' puts it straight into the request as :chat_list, and a
# bare symbol kills the server outright (see the SEGFAULT gotcha below).
-emacsclient -e "(progn (ignore-errors (telega--loadChats '(:@type \"chatListMain\"))) (ignore-errors (telega--loadChats '(:@type \"chatListMain\"))) 'loaded)"
+#
+# The liveness check on the tail is the load's only failure signal. `ignore-errors'
+# catches nothing here, because a bad argument kills the server process rather than
+# signalling in elisp, so without this the call returns 'loaded either way.
+# The `fboundp' guard matches Step 0: if the launch failed outright telega is not
+# loaded, and that should read as 'server-died like any other failure rather than
+# signalling void-function.
+emacsclient -e "(progn (ignore-errors (telega--loadChats '(:@type \"chatListMain\"))) (ignore-errors (telega--loadChats '(:@type \"chatListMain\"))) (if (and (fboundp 'telega-server-live-p) (telega-server-live-p)) 'loaded 'server-died))"
#+end_src
On a persisted session telega reaches status "Ready" within ~2s; the chat list
loads over a few more. If =(hash-table-count telega--chats)= is 0 or thin,
re-issue =telega--loadChats= and poll until it stabilizes.
+⚠ *=server-died= is SCAN FAILED, never a quiet account.* A server that dies
+during the load leaves a thin =telega--chats= hash, and a thin hash reads exactly
+like an account with little unread. That is the same false all-clear the
+down/not-loaded rule exists to prevent, arriving one step later in the lifecycle.
+It also fits the SCAN FAILED definition above: the launch was attempted and did
+not hold. So on =server-died=, report SCAN FAILED rather than scanning, and never
+report a low unread count from that run.
+
+This is the independent evidence the SEGFAULT gotcha asks for when it says to
+treat a short chat list as a real short list. Without the check there is no way
+to tell the two apart, which is how the =loadChats= crash stayed invisible
+through two investigations.
+
*** Step 2 — read unread, classified by last-message type
The single most important filter: =messageContactRegistered=. Telegram counts a