No error is a dead end: crash, click, and your agent is already looking
Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
@@ -23,6 +23,23 @@
|
||||
# 5. It follows from now rather than replaying the boot, so a session that
|
||||
# starts after a crash does not open with a notification about something
|
||||
# already lived through.
|
||||
#
|
||||
# And, since the escalation ladder landed:
|
||||
#
|
||||
# 6. With no agent chosen, the notification is exactly what it always was:
|
||||
# no action, no hint, no promise it cannot keep. "none" is the shipped
|
||||
# state and the quiet one.
|
||||
# 7. With an agent chosen, the click payload is carried as data in a
|
||||
# `panama-exec` hint -- never as a libnotify action, which would tie the
|
||||
# click to this long-lived `journalctl -f` still being alive to hear it --
|
||||
# and it carries the PID and the signal, which are the two facts a
|
||||
# diagnosis cannot start without.
|
||||
# 8. The body names the agent, because "diagnose with AI" tells nobody what
|
||||
# is about to open.
|
||||
# 9. The offer can be switched off on its own, without switching the crash
|
||||
# report off with it.
|
||||
# 10. The watcher never announces the agent it just launched. A crash watcher
|
||||
# that notifies about panama-agent is a loop with a toast in it.
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
@@ -42,17 +59,19 @@ calls="$work/calls"
|
||||
stub="$work/bin"
|
||||
mkdir -p "$stub"
|
||||
|
||||
# Two crashes of one program, one of another, and one belonging to somebody
|
||||
# else. journalctl is replaced by a stub that emits them and exits, so the
|
||||
# watcher's follow loop terminates instead of hanging the test.
|
||||
# Two crashes of one program, one of another, one belonging to somebody else,
|
||||
# and one from the ladder's own machinery. journalctl is replaced by a stub that
|
||||
# emits them and exits, so the watcher's follow loop terminates instead of
|
||||
# hanging the test.
|
||||
uid="$(id -u)"
|
||||
cat >"$stub/journalctl" <<STUB
|
||||
#!/usr/bin/env bash
|
||||
printf '%s\n' \\
|
||||
'{"COREDUMP_UID":"$uid","COREDUMP_EXE":"/usr/bin/panama-test-crasher","COREDUMP_COMM":"panama-test-cra"}' \\
|
||||
'{"COREDUMP_UID":"$uid","COREDUMP_EXE":"/usr/bin/panama-test-crasher","COREDUMP_COMM":"panama-test-cra"}' \\
|
||||
'{"COREDUMP_UID":"$uid","COREDUMP_EXE":"/usr/bin/other-program","COREDUMP_COMM":"other-program"}' \\
|
||||
'{"COREDUMP_UID":"99999","COREDUMP_EXE":"/usr/bin/someone-elses","COREDUMP_COMM":"someone-elses"}'
|
||||
'{"COREDUMP_UID":"$uid","COREDUMP_EXE":"/usr/bin/panama-test-crasher","COREDUMP_COMM":"panama-test-cra","COREDUMP_PID":"4242","COREDUMP_SIGNAL_NAME":"SIGSEGV"}' \\
|
||||
'{"COREDUMP_UID":"$uid","COREDUMP_EXE":"/usr/bin/panama-test-crasher","COREDUMP_COMM":"panama-test-cra","COREDUMP_PID":"4243","COREDUMP_SIGNAL_NAME":"SIGSEGV"}' \\
|
||||
'{"COREDUMP_UID":"$uid","COREDUMP_EXE":"/usr/bin/other-program","COREDUMP_COMM":"other-program","COREDUMP_PID":"4244","COREDUMP_SIGNAL_NAME":"SIGABRT"}' \\
|
||||
'{"COREDUMP_UID":"99999","COREDUMP_EXE":"/usr/bin/someone-elses","COREDUMP_COMM":"someone-elses","COREDUMP_PID":"4245","COREDUMP_SIGNAL_NAME":"SIGSEGV"}' \\
|
||||
'{"COREDUMP_UID":"$uid","COREDUMP_EXE":"$repo_dir/bin/panama-agent-crash","COREDUMP_COMM":"panama-agent-cr","COREDUMP_PID":"4246","COREDUMP_SIGNAL_NAME":"SIGSEGV"}'
|
||||
STUB
|
||||
chmod +x "$stub/journalctl"
|
||||
|
||||
@@ -69,8 +88,22 @@ exit 0
|
||||
STUB
|
||||
chmod +x "$stub/busctl"
|
||||
|
||||
: >"$calls"
|
||||
PATH="$stub:$PATH" timeout 20 "$watcher" >/dev/null 2>&1
|
||||
# Fabricated settings rather than this machine's, so the contract's answer does
|
||||
# not depend on which agent the person running it happens to prefer.
|
||||
settings="$work/settings.json"
|
||||
|
||||
# Runs the watcher once against a given settings file and returns what it asked
|
||||
# notify-send for.
|
||||
run_watcher() {
|
||||
: >"$calls"
|
||||
PATH="$stub:$PATH" PANAMA_PATH="$repo_dir" PANAMA_AGENT_SETTINGS="$settings" \
|
||||
timeout 20 "$watcher" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# ── The shipped state: no agent ─────────────────────────────────────────────
|
||||
|
||||
printf '{"preferredAgent":"none"}\n' >"$settings"
|
||||
run_watcher
|
||||
|
||||
# ── 1. Once per program ─────────────────────────────────────────────────────
|
||||
|
||||
@@ -92,6 +125,58 @@ grep -q 'someone-elses' "$calls" \
|
||||
grep -q 'panama-test-cra ' "$calls" \
|
||||
&& note 'the notification uses the truncated kernel comm field rather than the executable name'
|
||||
|
||||
# ── 6. No agent means no offer ──────────────────────────────────────────────
|
||||
|
||||
grep -q 'panama-exec' "$calls" \
|
||||
&& note 'with no agent chosen the notification still carries a diagnose command, which would click into nothing'
|
||||
grep -q 'System Health has the details' "$calls" \
|
||||
|| note 'with no agent chosen the notification lost its plain body'
|
||||
|
||||
# ── 10. Never its own machinery ─────────────────────────────────────────────
|
||||
#
|
||||
# Five entries go in; two programs come out. The third crash belongs to another
|
||||
# user, the fourth is the duplicate, and the fifth is panama-agent-crash itself.
|
||||
|
||||
grep -q 'panama-agent' "$calls" \
|
||||
&& note 'a crash in the ladder machinery was announced, which is how a crash loop becomes a notification loop'
|
||||
sent="$(wc -l <"$calls")"
|
||||
(( sent == 2 )) \
|
||||
|| note "with no agent chosen the watcher sent $sent notifications for five journal entries; two are warranted"
|
||||
|
||||
# ── 7 & 8. An agent chosen ──────────────────────────────────────────────────
|
||||
|
||||
printf '{"preferredAgent":"claude","crashDiagnoseOffer":true}\n' >"$settings"
|
||||
run_watcher
|
||||
|
||||
offer="$(grep 'panama-test-crasher' "$calls" | head -1)"
|
||||
|
||||
[[ "$offer" == *"panama-exec"* ]] \
|
||||
|| note 'with an agent chosen the notification carries no panama-exec hint, so the click has nothing to run'
|
||||
[[ "$offer" == *"$repo_dir/bin/panama-agent-crash"* ]] \
|
||||
|| note 'the hint does not invoke panama-agent-crash by absolute path; the shell that runs the click is started by systemd and has no repo bin on PATH'
|
||||
[[ "$offer" == *"4242"* ]] \
|
||||
|| note 'the hint carries no PID; coredumpctl cannot be asked about a crash without one'
|
||||
[[ "$offer" == *"SIGSEGV"* ]] \
|
||||
|| note 'the hint carries no signal name, which is the first thing a diagnosis reads'
|
||||
[[ "$offer" == *"Claude Code"* ]] \
|
||||
|| note 'the body does not name the agent, so the click does not say what it opens'
|
||||
[[ "$offer" == *"--action"* ]] \
|
||||
&& note 'a libnotify action was used as well; the click must come back through the hint alone'
|
||||
|
||||
sent="$(wc -l <"$calls")"
|
||||
(( sent == 2 )) \
|
||||
|| note "with an agent chosen the watcher sent $sent notifications for five journal entries; two are warranted"
|
||||
|
||||
# ── 9. The offer switches off on its own ────────────────────────────────────
|
||||
|
||||
printf '{"preferredAgent":"claude","crashDiagnoseOffer":false}\n' >"$settings"
|
||||
run_watcher
|
||||
|
||||
grep -q 'panama-exec' "$calls" \
|
||||
&& note 'crashDiagnoseOffer=false still offered a diagnosis'
|
||||
grep -q 'panama-test-crasher' "$calls" \
|
||||
|| note 'switching the offer off also switched the crash report off; they are separate things'
|
||||
|
||||
# ── 4 & 5. How it listens ───────────────────────────────────────────────────
|
||||
|
||||
grep -q 'org.freedesktop.Notifications' "$watcher" \
|
||||
|
||||
Reference in New Issue
Block a user