Branch naming
Status: current design and implementation reference
Branches use their own name when one exists and otherwise expose a short identifier. Automatic naming is progressive and must not overwrite a user-controlled name.
The canonical implementation is inopenprogram/store/session/session_store.py,openprogram/agent/dispatcher/titles.py,openprogram/agent/dispatcher/finalize.py, andapps/server/openprogram_server/_webui/ws_actions/branch.py.
1. Current contract
- The trunk has no synthesized
mainspecial case. An unnamed branch uses the short hexadecimal identifier; a named branch uses its own name. - Manual branch naming is handled by the branch WebSocket actions. The short identifier is the fallback when no name is stored.
- Automatic naming is a background operation triggered from turn finalization at the configured thresholds. It reads the branch context and rechecks the lock before writing.
- Automatic naming must not replace a name that the user has locked. A stale background result is discarded when the stored branch metadata no longer matches the operation's preconditions.
2. Implemented paths
| Concern | Current source | Evidence |
|---|---|---|
| Stored branch name and fallback | openprogram/store/session/session_store.py | Branch metadata is read without a synthesized main name; unnamed entries fall back to a short id. |
| Progressive LLM naming | openprogram/agent/dispatcher/titles.py | maybe_auto_name_branch performs threshold checks, background generation, and write-back guards. |
| Turn-end trigger | openprogram/agent/dispatcher/finalize.py | Finalization invokes automatic branch naming after the turn. |
| Manual and WebSocket actions | apps/server/openprogram_server/_webui/ws_actions/branch.py | Rename, short-id fallback, lock handling, and on-demand naming are exposed through the current branch actions. |
| Composer command | apps/web/components/chat/composer/slash/slash-commands.ts | /branch and auto_name_branch are registered as current commands. |
3. Naming policy
| Source | Priority | May automatic naming overwrite it? |
|---|---|---|
| User rename | Highest | No; it sets the stored lock. |
| Existing stored branch name | Stored value | Only when the current automatic operation passes its lock and stale-write checks. |
| Automatic LLM result | Background refinement | No when the branch is locked or the precondition changed. |
| Short identifier | Fallback | Replaced only after a valid name is stored. |
4. State and lifecycle
- A branch is created with its metadata and can be displayed immediately through its short id if no name exists.
- At turn finalization, the branch's own context and turn count are checked against the progressive naming thresholds.
- The LLM generation runs in the background. Before writing, it rereads the branch/session state and abandons the result when a manual lock or stale precondition is detected.
- WebSocket consumers receive the branch update through the current branch/session update path; the UI must keep the short-id fallback while generation is pending.
5. Boundaries
- The design does not introduce a second branch entity, a second naming store, or a new special trunk name.
- Branch naming does not change the session title contract or the DAG parent relationships.
- The exact prompt wording and future threshold changes remain implementation details; any change must update the canonical Markdown page and this visualization together.
- Cross-function naming coordination, cross-session naming policy, and historical migration of old branch metadata are not claimed by this page.
6. Verification notes
The implementation evidence above is a source-path contract, not a claim that every browser state or race has been exhaustively tested. Validation should cover manual rename versus a concurrent automatic result, unnamed trunk fallback, fork branch progression, and the WebSocket update received after background naming.
Last updated · 2026-10-10