Skip to content

fix(capture): the SessionStart finalize-all backstop never fires #492

Description

@boskodev790

vouch capture finalize-all is wired into the claude-code SessionStart hook to sweep buffers left by sessions that ended without SessionEnd (#304). it can never do that: the shipped hook passes no --session-id, and nothing sets VOUCH_SESSION_ID, so the command silently no-ops on every session start.

wherecli.py:2404:

sid = session_id or os.environ.get("VOUCH_SESSION_ID") or ""
if not sid:
    # No session ID provided; silently succeed
    _emit_json({"finalized": [], "skipped_recent": [], "skipped_current": []})
    return

the shipped hook (adapters/claude-code/.claude/settings.json) is bare:

vouch capture finalize-all || true

and grep -rn VOUCH_SESSION_ID finds only the cli reader plus two tests that set it themselves — nothing in the adapter, the hook wiring, or the runtime ever exports it. so sid is always "" and the sweep returns {"finalized": [], ...} every time.

unlike capture finalize, finalize-all never reads the stdin hook payload — which is where claude code actually puts session_id.

why it matters#304 added this as the recovery path for buffers orphaned when a session dies without SessionEnd, and the settings.json comment says so outright ("fallback: windowclose event not yet supported"). those buffers instead accumulate in .vouch/captures/ indefinitely and their sessions never roll up into pending proposals, so the session never reaches the review queue at all.

why it went unnoticedtest_adapter_settings_wires_capture_hooks (tests/test_capture.py:399) asserts observe / finalize / banner are wired but never finalize-all, and every cli test for the command passes --session-id or the env var explicitly. the shipped configuration is the one path no test exercises.

fix — read the session id off the stdin payload the same way capture_finalize_cmd already does at SessionEnd, keeping --session-id and VOUCH_SESSION_ID as fallbacks. happy to send it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions