OpenProgram Docs

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 in openprogram/store/session/session_store.py, openprogram/agent/dispatcher/titles.py, openprogram/agent/dispatcher/finalize.py, and apps/server/openprogram_server/_webui/ws_actions/branch.py.

1. Current contract

  • The trunk has no synthesized main special 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

ConcernCurrent sourceEvidence
Stored branch name and fallbackopenprogram/store/session/session_store.pyBranch metadata is read without a synthesized main name; unnamed entries fall back to a short id.
Progressive LLM namingopenprogram/agent/dispatcher/titles.pymaybe_auto_name_branch performs threshold checks, background generation, and write-back guards.
Turn-end triggeropenprogram/agent/dispatcher/finalize.pyFinalization invokes automatic branch naming after the turn.
Manual and WebSocket actionsapps/server/openprogram_server/_webui/ws_actions/branch.pyRename, short-id fallback, lock handling, and on-demand naming are exposed through the current branch actions.
Composer commandapps/web/components/chat/composer/slash/slash-commands.ts/branch and auto_name_branch are registered as current commands.

3. Naming policy

SourcePriorityMay automatic naming overwrite it?
User renameHighestNo; it sets the stored lock.
Existing stored branch nameStored valueOnly when the current automatic operation passes its lock and stale-write checks.
Automatic LLM resultBackground refinementNo when the branch is locked or the precondition changed.
Short identifierFallbackReplaced only after a valid name is stored.

4. State and lifecycle

  1. A branch is created with its metadata and can be displayed immediately through its short id if no name exists.
  2. At turn finalization, the branch's own context and turn count are checked against the progressive naming thresholds.
  3. 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.
  4. 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