Skip to content

bug: Research: make branch assignments survive DB reset or reconstruct from git history #297

Description

@marcinkardas

Operating system(s)

  • Windows
  • macOS
  • Linux

What happened?

Branch name assignments (threads.branch_name) are stored only in SQLite (desktop.sqlite). Pi session files (.jsonl) contain no branch information. As a result, syncShellIndex — which scans session files on every startup — cannot reconstruct branch assignments if the database is lost, reset, or a different database instance is used (e.g. dev vs. prod, new machine, corrupted DB).

Any scenario that produces a fresh or empty desktop.sqlite permanently moves all sessions to "Unassigned" with no automatic recovery path.

Steps to reproduce

  1. Assign sessions to git branches by sending messages through the Howcode Composer.
  2. Delete or replace ~/Library/Application Support/howcode/state/desktop.sqlite (or switch to a DB instance that lacks the assignments).
  3. Restart Howcode — all sessions appear under "Unassigned" despite the Pi .jsonl files being intact.

syncShellIndex completes without errors but branch_name stays NULL for all threads because mapSessionSummaryToRecord returns no branchName and the UPSERT resolves to COALESCE(threads.branch_name, NULL).

Agent implementation prompt

assignThreadBranch() in desktop/thread-state-db/thread-writes.ts writes branch names only to threads.branch_name in SQLite. mapSessionSummaryToRecord in desktop/pi-threads/session-index.ts does not read or return a branchName field. syncSessionSummaries in desktop/thread-state-db/session-writes.ts upserts with COALESCE(threads.branch_name, excluded.branch_name) which preserves existing values but cannot populate them from session files.

Investigate and implement durable branch assignment storage. Options to consider:

  1. Write branch name into the Pi session JSONL as a session_info-style entry when assignThreadBranch is called; extend applySessionFileEntry and SessionSummary to read it back; populate branchName in mapSessionSummaryToRecord so syncShellIndex can reconstruct assignments from files alone.
  2. During syncShellIndex, for sessions with branch_name IS NULL, use git log --format="%H %D" --before=<session_startedAt> against the project's repo to infer which branch was active when the session started. The session start timestamp is available in .meta.json (startedAt) alongside each .jsonl.

Relevant files:

  • desktop/pi-threads/session-index.ts (readSessionSummary,
  • mapSessionSummaryToRecord),
  • desktop/thread-state-db/session-writes.ts (syncSessionSummaries),
  • desktop/thread-state-db/thread-writes.ts (assignThreadBranch),
  • desktop/pi-threads/composer-actions.ts (call site for assignThreadBranch).

App version or commit

0.1.66-dev

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions