fix(desktop): cascade persona respond_to edits to linked inheriting instances (#2501) - #4115
Conversation
…nstances (block#2501) A persona definition's "Who can talk to this agent" edit updated only the definition record; every already-minted agent instance kept its mint-time respond_to (owner-only by default), because the harness boots the gate from the instance record (build_respond_to_env) and no write path ever propagated behavior changes from the definition. Manual managed-agents.json edits worked, confirming the store was authoritative and the write path was the gap. update_persona_with now cascades behavioral-group edits to linked instance records, with the same discrimination rule the display_name cascade uses: - An instance whose respond_to still equals the PRE-edit definition value was inheriting → it adopts the new definition mode/allowlist/parallelism. - An instance carrying a different value holds an explicit instance-level pin → preserved untouched (parity with the pool-named-instance rule). - Every linked instance's definition mirror fields refresh either way, so future mint/inspect paths see the current definition bytes. Absent definition parallelism does not stomp an instance's pool width; unknown mode strings fail loudly rather than rewriting inheriting instances to a default the author didn't choose (same contract as mint). Adds 6 regression tests: inheriting cascade, pinned-override preservation, mixed fleet, definition-clear resets to default, unknown mode fail-loudly, and absent parallelism preservation. cargo test --lib: 2094 pass. Signed-off-by: Sarthak Singh <sarthak.singh@juspay.in>
|
Nice — this is the cascade 1. No empty-allowlist guard on the inherit branch — it regenerates the The inherit branch copies the definition allowlist verbatim: record.respond_to = match persona.respond_to.as_deref() {
Some(wire) => RespondTo::parse_wire(wire)?,
None => RespondTo::default(),
};
record.respond_to_allowlist = persona.respond_to_allowlist.clone();
2. The inheritance discriminator is mode-only, so it clobbers a same-mode allowlist pin. if record.respond_to == old_mode {
3. Scope / coordination with #2505. This is backend-only, so defect 1 (person-picker never persisting Happy to build and run an end-to-end regen check (owner-only → allowlist-with-members, mixed inheriting/pinned fleet, restart + re-mint) once the empty-allowlist skip is in. |
Summary
respond_to(owner-only by default). The harness bootsBUZZ_ACP_RESPOND_TOfrom the instance record (build_respond_to_env), so UI edits had zero runtime effect — exactly the three-way desync the issue documents (UI says Anyone, definition saysdefinition_respond_to=anyone, harness bootsowner-only).update_persona_withnow cascades behavioral-group edits to linked instance records, using the same discrimination rule the existing display_name cascade applies (pool-named instances carry an override and are skipped): an instance whoserespond_tostill equals the pre-edit definition value was inheriting → it adopts the new mode/allowlist/parallelism; an instance carrying a different value holds an explicit pin → preserved untouched. Definition mirror fields on every linked instance refresh either way.parallelismdoes not stomp an instance's pool width.Root cause
create_managed_agentmints the instancerecord.respond_toonce viaresolve_mint_behavioral_defaults(explicit input > definition default > owner-only). After that the instance record is the only thingbuzz-acpreads at spawn. The persona edit path (update_persona→apply_persona_behavior) updated the definition only — the cascade to linked instances existed foravatar_url/display_name(Issue pattern) but was never built for the behavioral group, so the instance record froze at mint time. The issue reporter's workaround (hand-editingmanaged-agents.json) worked precisely because the store is authoritative — the write path was the gap.Changes
desktop/src-tauri/src/commands/personas/update.rs: capture pre-edit behavior signature; newpropagate_persona_behaviorhelper (mirrorspropagate_persona_name_rename) applying the cascade with override discrimination + mirror refresh; called fromupdate_persona_withwhen the behavior signature changed.desktop/src-tauri/src/commands/personas/update/behavior_cascade_tests.rs: 6 pinned regression tests — inheriting cascade, pinned-override preservation, mixed fleet per-instance semantics, definition-clear resets to default, unknown mode fails loudly without half-apply, absent parallelism preserves instance width.Verification
cargo test --lib— 2094 passed, 0 failed (includes the 6 new tests).pnpm typecheck— clean.Fixes #2501