fix(statusline): resolve the handle from the v3 binding, not the v2 map

The statusline resolved its handle from ~/.althing/session_handles.json.
forseti corrected the grounding and I verified it: that file is a v2
artifact and v3 never opens it. `grep -rn session_handles althing/` is
empty, postbox's resolve_config takes --handle then ALTHING_HANDLE and
nothing else, and `althing-cli use` -- the tool that maintained the map
-- was deleted at the cutover. Whatever is in it now is hand-kept and
drifts silently.

launch-history.json is written by dev_launch, which is the thing that
sets ALTHING_HANDLE in the first place, so it is the real cwd-to-handle
binding. Shape is {cwd: {command: {at, handle}}} with several commands
per directory, so this takes the most recent by timestamp rather than
whichever key happens to sort first. The v2 map stays as a fallback for
its broader coverage.

Worth recording why this was wrong: I wrote the resolution this morning
by reading the v2 statusline block it replaced and keeping its data
source while updating its commands. The commands were the visible half
of the cutover and the data source was not, so it survived a rewrite
that was otherwise about removing v2.
This commit is contained in:
2026-08-28 16:01:11 -07:00
parent c648a40b68
commit 8a04d6f1bb
+19 -3
View File
@@ -141,9 +141,25 @@ if command -v postbox >/dev/null 2>&1; then
# "no mail" -- the exact conflation v3 exists to prevent.
export ALTHING_POST_OFFICE="${ALTHING_POST_OFFICE:-http://10.100.50.40:8390}"
h="${ALTHING_HANDLE:-}"
# ALTHING_HANDLE isn't set in the statusline env resolve the per-project handle
# from althing's session map, keyed by the cwd Claude Code passes on stdin.
[ -z "$h" ] && [ -n "$cwd" ] && h=$(jq -r --arg d "$cwd" '.[$d] // empty' "$HOME/.althing/session_handles.json" 2>/dev/null)
# ALTHING_HANDLE isn't set in the statusline env, so resolve the handle from the
# cwd Claude Code passes on stdin.
#
# ⚠ PREFER launch-history.json. session_handles.json is a **v2 artifact** — v3's
# postbox never opens it (`grep -rn session_handles althing/` is empty; resolve_config
# takes --handle then ALTHING_HANDLE and nothing else), and the tool that used to
# maintain it, `althing-cli use`, was deleted at the cutover. Whatever is in it now is
# hand-kept and drifts silently.
#
# launch-history.json is written by dev_launch, which is the thing that sets
# ALTHING_HANDLE in the first place, so it is the real cwd->handle binding. Shape is
# {cwd: {command: {at, handle}}} with several commands per directory (claude, kimi,
# grok), so take the most recent by `at` rather than whichever key sorts first.
if [ -z "$h" ] && [ -n "$cwd" ]; then
h=$(jq -r --arg d "$cwd" '(.[$d] // {}) | to_entries | max_by(.value.at) | .value.handle // empty' \
"$HOME/.althing/launch-history.json" 2>/dev/null)
# Fallback only: broader coverage, but frozen and hand-maintained.
[ -z "$h" ] && h=$(jq -r --arg d "$cwd" '.[$d] // empty' "$HOME/.althing/session_handles.json" 2>/dev/null)
fi
if [ -n "$h" ]; then
# `timeout` is load-bearing, not belt-and-braces: v2 read a local SQLite file,
# v3 makes an HTTP call. An unreachable post office must cost this segment two