fn template_parent_id_if_seeded(mstore: &Store, parent_id: &str) -> StringExpand description
Resolve the identity bindings for an instance from the direct agent↔account links only.
Phase 3 slice 2 PR-B (the flip): the resolver previously dual-read —
preferring db_agent_identity_links keyed on the instance’s DEFINITION
id, falling back to the bundle bindings (db_identity_bindings) when no
direct links existed (PR-A, #1927). That fallback was removed here, and
Phase 4c of SPEC_PRESET_TO_BUNDLE_REFACTOR_2026_07_02.md later dropped
db_identity_bundles/db_identity_bindings entirely — every write path
(launch flow, per-agent Accounts tab, OAuth Connect/Reconnect) writes a
direct link, and the m0013/m0014 migrations (#1927/#1952) backfilled
direct links for every pre-existing bundle binding before the drop.
parent_template_id: the launch’s eligible TEMPLATE parent’s own id —
"" unless the caller has already confirmed, via
template_parent_id_if_seeded, that db_agents.parent_template_id
actually points at a row with is_seeded = 1. That column is NOT
exclusively “which template was I launched from”: forkagentdefinition
(template.rs) reuses the same column to record a plain agent fork’s
SOURCE agent id, is_seeded = 0. reagent P0 on #3092 caught an earlier
version of this fallback trusting the column unconditionally — a fork
of any regular agent that had a bound identity would silently inherit
and spawn on the SOURCE agent’s credentials, even though forks are
deliberately created with accounts: "" and no link of their own
(fail-closed by design, the same convention conversation_visibility
documents right next to parent_id in template.rs). Callers MUST
resolve this through template_parent_id_if_seeded, never pass
d.parent_id directly.
Agent-concept consolidation’s definition flip
(SPEC_AGENT_ARCHITECTURE_2026_05_27.md Phase 3d) made agent_def_get
resolve a template launch’s own row for the first time, which enabled
Step 5’s definition-provider gate for that whole agent class — but
binding an identity to a TEMPLATE (the Agent Setup modal’s supported
target) has always written the link under the TEMPLATE’s id, never the
launch’s own id, since nothing writes a launch-scoped link. Without
this fallback, enabling Step 5 would have converted every template
launch with a genuinely configured account into a hard spawn failure —
the direct link lookup below finds nothing under the launch’s own id
regardless of whether an account is actually bound, because it never
was.
broker publishes identity:no-direct-links when the direct set is
empty — a standing diagnostic for a non-sentinel identity resolving to
zero links (e.g. a stale/migrated-away instance). None in tests /
call sites that don’t have a broker handle.
parent_id’s eligible-template gate for resolve_bindings_for_instance
(see that function’s doc comment for the P0 this closes): returns
parent_id back only when it names a row with is_seeded = 1 — a
genuine template — never for a plain agent-to-agent fork, which reuses
the same parent_id/parent_template_id column for unrelated lineage.
mstore is the store parent_id was read from (the same one
agent_def_get resolved the launch’s own row through); an empty
parent_id, a lookup failure, or a parent that resolves but isn’t
seeded all return "" — “no eligible template parent,” not an error.