mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Item 1 — Compensation primitive: replace AtomicBool gate with lock-owning
compensate_drain that takes the caller's already-held rt_transition guard
by value, re-acquires only the store lock, validates captured scope generation,
then restores journal entries via start_pair_under_held_locks. Split
start_pair_under_held_locks out of start_pair so both the normal and
compensation paths share the spawn-and-register body. execute_drain_journal
refactored to accept an injectable stop_fn via drain_journal_with_stop;
execute_drain_journal_with_stop_fn exposed for test injection. Tests: live
SIGKILL drain, structural lock-release proof, deterministic partial-failure
test with injected stop error covering stopped prefix and remaining tail.
Item 2 — Client stop + start serialization: mesh_stop_client Tauri command
in mesh_llm_scope.rs stops only a client-mode runtime; serve/absent are
no-ops. Client start (ensure_relay_mesh_for_record) acquires
workspace_transition through runtime installation to serialize against
apply_workspace, which holds workspace_transition from before the Option A
preflight through commit. fail_if_client_mesh_active preflight runs under
workspace_transition so no new client can start in the check→commit gap.
UI: 'Stop using shared compute' button in MeshComputeSettingsCard shown when
isConsuming; calls new meshStopClient() in tauriMesh.ts. e2eBridge mock for
mesh_stop_client added.
Item 3 — Fallible migrations + atomic marker: rename_provider_to_runtime_in_personas
propagates Result; migrate_agent_keys_to_dev_service_at returns Result and
propagates from copy_agent_keys_between_stores. run_scoped_migrations uses ?
on persona-provider step. _ready marker written via temp+rename (atomic).
dev-key migration skipped in unit-test builds (#[cfg(not(test))]) to avoid
macOS Keychain dialogs. Tests: old-marker upgrade (no scope deletion), partial
migration failure withholds v1 until repair succeeds.
Item 4 — Global-config captured respawn: Phase 2 restart validates captured
scope generation under store lock before stop, and again before respawn via
start_local_agent_pairs_with_preflight_at (new captured variant using
definitions_dir). persist_last_error validates generation under store lock.
Item 5 — Snapshot imports captured operation context: both confirm_agent_snapshot_import
and confirm_team_snapshot_import capture owner keys at entry, verify against
captured_scope.owner_pubkey immediately, thread captured keys through all
mint/retention/engram phases. Re-verify owner key under store lock before
Phase 3a write. Outbound profile/memory phases use captured_scope.relay_url.
Item 6 — CI red: rustfmt applied (agents_scoped.rs, import.rs); clippy
needless_borrow at team_snapshot.rs:793 fixed; e2eBridge apply_workspace mock
returns { applied: true, degraded: [] } in both immediate and delayed branches;
mesh_stop_client mock case added. Stale 3-line doc fragment removed from
mesh_llm.rs; visibility of re-exported agents_scoped fns bumped to pub(crate).
Item 7 — Listener behavioral test: useNestNotifications.test.mjs exercises
workspace-degraded toast payload, unlisten cleanup, and boundary payloads
without requiring a real Tauri runtime. Doc comment updated: event-sync dispatch
failure does not emit workspace-degraded (shutdown-time, no toast surface).
Item 8 — Dead code (minor): backfill_persona_snapshots AppHandle shim removed;
stale scope_init.rs:388-393 comment corrected; make_base_dir test helper removed.
File-size gate: mesh_llm.rs (999), import.rs (999), team_snapshot.rs (999).
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
72 lines
2.8 KiB
Rust
72 lines
2.8 KiB
Rust
pub(crate) use backfill::backfill_standalone_agents_in_dir;
|
|
pub(crate) use detach::detach_directory_backed_teams_in_dir;
|
|
pub(crate) use fold::fold_personas_in_dir;
|
|
pub(crate) use materialize::materialize_runtimes_in_file;
|
|
pub(crate) use team_suffix::strip_baked_team_instructions_in_dir;
|
|
|
|
/// Rename `provider` → `runtime` in a scoped `definitions_dir/personas.json`.
|
|
///
|
|
/// Runs BEFORE `fold_personas_in_dir` so the fold reads the correct `runtime`
|
|
/// field. Idempotent: records that already have `runtime` are unchanged.
|
|
/// Returns `Ok(())` when there is no `personas.json` to migrate.
|
|
/// Returns `Err` when the file exists but the patch fails.
|
|
pub(crate) fn migrate_persona_provider_to_runtime_at(
|
|
definitions_dir: &std::path::Path,
|
|
) -> Result<(), String> {
|
|
let path = definitions_dir.join("personas.json");
|
|
if path.exists() {
|
|
rename_provider_to_runtime_in_personas(&path)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Reconcile `mcp_command` values in a scoped `definitions_dir`.
|
|
pub(crate) fn reconcile_provider_mcp_commands_at(definitions_dir: &std::path::Path) -> Result<(), String> {
|
|
let path = definitions_dir.join("managed-agents.json");
|
|
if path.exists() {
|
|
reconcile_mcp_commands_in_file(&path)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Reconcile Databricks V1 → V2 provider entries in a scoped `definitions_dir`.
|
|
pub(crate) fn reconcile_databricks_v1_to_v2_at(definitions_dir: &std::path::Path) -> Result<(), String> {
|
|
use crate::managed_agents::baked_build_env;
|
|
let rewrite_v1_provider = baked_build_env()
|
|
.get("BUZZ_AGENT_PROVIDER")
|
|
.map(|v| v == "databricks_v2")
|
|
.unwrap_or(false);
|
|
let path = definitions_dir.join("managed-agents.json");
|
|
if path.exists() {
|
|
reconcile_databricks_v1_to_v2_in_file(&path, rewrite_v1_provider)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Refresh legacy built-in agent avatars in a scoped `definitions_dir`.
|
|
pub(crate) fn refresh_builtin_agent_avatars_at(definitions_dir: &std::path::Path) -> Result<(), String> {
|
|
let path = definitions_dir.join("managed-agents.json");
|
|
if path.exists() {
|
|
refresh_builtin_agent_avatars_in_file(&path, LEGACY_BUILTIN_AVATARS, &crate::util::now_iso())?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Reconcile legacy command names in a scoped `definitions_dir`.
|
|
pub(crate) fn reconcile_legacy_command_names_at(definitions_dir: &std::path::Path) -> Result<(), String> {
|
|
let path = definitions_dir.join("managed-agents.json");
|
|
if path.exists() {
|
|
reconcile_legacy_command_names_in_file(&path)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Materialize per-record runtimes in a scoped `definitions_dir`.
|
|
pub(crate) fn materialize_agent_runtimes_at(definitions_dir: &std::path::Path) -> Result<(), String> {
|
|
let path = definitions_dir.join("managed-agents.json");
|
|
if path.exists() {
|
|
materialize_runtimes_in_file(&path)?;
|
|
}
|
|
Ok(())
|
|
}
|