chore: branches polish — global-leak docs + unknown-name warning (T103)

This commit is contained in:
Joseph Doherty
2026-04-27 04:34:32 -04:00
parent a06f90a164
commit 374a76c867
2 changed files with 66 additions and 0 deletions
+31
View File
@@ -9,11 +9,15 @@ existing event readers remain branch-agnostic.
"""
from __future__ import annotations
import logging
from sqlite3 import Connection
from chat.eventlog.projector import on
from chat.eventlog.log import Event
logger = logging.getLogger(__name__)
@on("branch_created")
def _apply_branch_created(conn: Connection, e: Event) -> None:
@@ -37,9 +41,26 @@ def _apply_branch_switched(conn: Connection, e: Event) -> None:
"""Set is_active=1 on the named branch and is_active=0 on all others.
Atomic via two UPDATEs ordered to avoid the unique-active-index race.
If the named branch does not exist, a warning is emitted and the
is_active flags are still cleared (preserving prior behavior — the
second UPDATE simply matches no rows). Callers should validate the
name upstream; this guard surfaces accidental mismatches in the log.
"""
p = e.payload
name = p["name"]
# Warn (don't raise) if the target branch is missing. The existing
# outcome — zero active branches — is preserved; this just makes the
# condition observable instead of silent.
exists = conn.execute(
"SELECT 1 FROM branches WHERE name = ? LIMIT 1",
(name,),
).fetchone()
if exists is None:
logger.warning(
"branch_switched to unknown branch name %r; no branch will be active",
name,
)
# Clear ALL is_active flags first (avoids the unique-index trip).
conn.execute("UPDATE branches SET is_active = 0 WHERE is_active = 1")
conn.execute(
@@ -79,6 +100,16 @@ def get_branch(conn: Connection, name: str) -> dict | None:
def list_branches(conn: Connection, chat_id: str | None = None) -> list[dict]:
"""Return branch rows, optionally scoped to a chat.
When ``chat_id`` is provided the filter is ``chat_id = ? OR chat_id IS NULL``,
so global (null-chat) branches are returned in *every* per-chat scope. This
is intentional: the bootstrapped ``"main"`` branch (and any future
null-chat branches) are global by design — they belong to no single chat
and should appear alongside per-chat branches in any chat-scoped listing.
Callers that want only per-chat branches should filter the result on
``chat_id is not None``.
"""
if chat_id is None:
rows = conn.execute(
"SELECT id, name, origin_event_id, head_event_id, chat_id, "