feat(desktop): unified AgentRecord groundwork — record-first resolution + runtime materialization (Phase 1A.1)#1618
Merged
Merged
Conversation
…ase 1A slice 1) Add display_name, name_pool, and is_builtin to ManagedAgentRecord — the three user-facing fields the persona layer carries that the agent record did not already snapshot. All serde-default so existing stores deserialize unchanged; not yet published (the 30177 projection is untouched, per the frozen Phase-1 interface). Part of the unified agent model (#centralize-personas-and-agents): AgentRecord = ManagedAgentRecord + persona-only fields, identity optional. Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
…ce 2a) Add slug (former PersonaRecord.id, preserves 30175 d_tag coordinates for key-less definitions) and is_active (archived-definition flag) to ManagedAgentRecord, and teach hydrate_keys to skip key-less records — definitions mint keys on first start, so there is no keyring entry to look up and no outage to report. desktop-tauri tests: 1020 passed, 0 failed. Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Add record.runtime (absorbed from PersonaRecord.runtime) and record_agent_command(): override > record.runtime > legacy persona lookup > default. Convert all record-based effective_agent_command call sites (spawn, restore, summary, spawn_hash, readiness, model discovery, config surface, profile reconcile) to the record-first path. Records without a materialized runtime resolve exactly as before via the persona fallback, so pre-migration stores see zero behavior change. effective_agent_command remains for persona-scoped callers (persona dialogs, divergence checks) until the store migration lands. desktop-tauri tests: 1024 passed (4 new record_agent_command tests). Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Add materialize_agent_runtimes to run_boot_migrations: copies each persona-linked record's runtime onto the record itself (idempotent, never overwrites an existing runtime, skips unlinked/unknown personas). After this runs, record_agent_command resolves from the record's own runtime — the persona list is no longer consulted on the spawn path. Includes Pinky's cutover acceptance test: spawn_config_hash is IDENTICAL before vs after materialization for a persona-linked record, so no running agent shows a spurious restart badge at migration. desktop-tauri tests: 1028 passed. Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Extend the opt-IN exclusion test with real (non-empty) values for the Phase 1A record fields (display_name, slug, runtime, name_pool, is_builtin, is_active) and assert none reach the published projection — publishing them is a Phase 2 relay-canonicalization decision, and this makes the frozen-interface contract with the boot reconcile executable. Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
…slice 3b-1) source_team + source_team_persona_slug move onto ManagedAgentRecord — the definition-side team lineage the persona layer carried. With these, the record is a strict superset of PersonaRecord's user-facing fields and the store fold no longer loses information. Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
…3b-2) PersonaRecord::into_agent_record projects a persona onto a key-less unified record (id -> slug, preserving the 30175 d_tag coordinate; identity empty until first start mints keys). The inverse to_persona_view presents slugged definitions in the legacy shape for the persona command surface until Phase 1B unifies the UI. Round-trip is field-exact (test-pinned via serde_json::Value equality). Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
The file-size guard flagged five files at their limits. Real splits, not limit bumps: - discovery.rs / nest.rs: inline test modules move to discovery/tests.rs and nest/tests.rs (the repo's established pattern) — both files drop under the 1000-line default (802 / 679). - migration.rs: materialize_agent_runtimes + its tests move to a migration/materialize.rs child module (reuses the parent's private JSON-patch helpers). - commands/agents.rs: the kind:0 profile-reconcile surface (ProfileReconcileData, reconcile_agent_profile, legacy-avatar backfill, needs-sync predicate) moves to agents_profile.rs. All five ratchet entries lowered to the new sizes so the freed headroom cannot silently refill. Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
This was referenced Jul 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 1A (first half) of the unified agent model (#centralize-personas-and-agents):
ManagedAgentRecordbecomes a strict superset ofPersonaRecord's user-facing fields, and all spawn/summary/config paths resolve record-first. Zero user-visible behavior change — this PR is the groundwork that makes the store fold (A2, next PR) a data migration instead of a behavior change.display_name,slug(former persona id — preserves the 30175d_tagcoordinate for future key-less definitions),runtime,name_pool,is_builtin,is_active,source_team,source_team_persona_slug. All serde-defaulted; existing stores parse unchanged.record_agent_command()— explicit override > record's ownruntime> legacy persona lookup > default. All record-basedeffective_agent_commandcall sites converted (spawn, restore, summary, spawn-hash, readiness, model discovery, config surface, profile reconcile). Pre-migration records carry noruntime, so they fall through to the persona path and resolve exactly as before.materialize_agent_runtimescopies each persona-linked record's runtime onto the record (idempotent, never overwrites, skips unknown personas). Cutover invariant test-pinned:spawn_config_hashis identical before vs after materialization, so no running agent shows a spurious restart badge.PersonaRecord::into_agent_record/ManagedAgentRecord::to_persona_view, round-trip pinned by serde-Value equality. Wired in by A2's store fold.Deliberately NOT in this PR (A2): folding
personas.jsoninto the unified store, persona-command shims, and the spawn-time persona re-pin collapse (which waits for Phase 1B's UI unification so persona edits keep propagating while the persona UI exists).Testing
just desktop-tauri-test: 1041 passed, 0 failed (17 new tests: resolution ladder, fold round-trip, migration idempotence/skip cases, hash-invariance cutover, wire-projection exclusions)just clippy(workspace),just fmt-check,just desktop-tauri-fmt-check: green