pub fn migrate_promote_template_sessions_v1(
wstore: &Arc<WaveStore>,
filestore: &Arc<FileStore>,
_data_dir: &Path,
) -> TemplatePromoteStatsExpand description
Phase 1 two-tier picker migration: promote any seeded template that
carries a session zone into a fresh user-owned definition, then move
its :current + :archive:* zones onto the new definition_id.
Why this exists (Q1 = Option C in
docs/specs/SPEC_AGENT_PICKER_TWO_TIER_2026_05_24.md):
after the picker UI split, clicking a “template” card in the
Templates section MUST create a new agent — not silently append to
whatever session the user previously ran against that template
directly (e.g. “Maks’s conversation” living at agent:claude:current).
Without this migration the template card would either reattach to
the existing session (broken — wrong intent) or be effectively
non-functional. The migration moves any such pre-existing session
out of the template namespace onto a new user-owned definition so
the template is pristine post-migration.
Algorithm:
- List zone ids; partition the
agent:<id>:currentandagent:<id>:archive:*zones by definition id. - For each definition id with at least one zone, look up the
matching
db_agent_definitionsrow.- Skip if missing (zone refers to a deleted definition).
- Skip if
is_seeded = 0(already user-owned — no work). - Otherwise: clone the template into a new user definition
(mirrors
agent_def_create_from_templatesemantics).
- Pick the new name: most-recently-active named instance’s
instance_nameif any exists, else fall back to the template’s ownname. - Move every matching zone (
:current+ every:archive:*) from the old defId to the new defId via FileStore’s existing write-then-delete pattern. - Repoint every
db_agent_instancesrow that referenced the old defId to point at the new defId (preserves thecontinueOfInstanceIdreattach flow).
Idempotency: the migration is self-gated on the data invariant
(“no seeded def has a session zone”). It runs on every startup;
when the invariant already holds the inner loop has zero
iterations and returns the default stats in sub-ms. There used to
be a marker-file gate (TEMPLATE_PROMOTE_MARKER_V1), but it
produced an “early-marker” failure mode: a portable launched at v
N had no seeded-def zones, set the marker, and on v N+1 startups
(when seeded-def zones DID exist from prior real use) the marker
caused the migration to skip. The 2026-05-24 rework dropped the
marker check; this is safe because the seeded-def-with-zone
invariant is detectable per-startup at constant cost. data_dir
is retained for API compatibility.
Failure mode: per-template errors are logged + counted; we DO NOT abort startup. Errors that prevent a template from being promoted leave its zones in place; the next startup retries (no marker gate to block retry).