mirror of
https://github.com/block/buzz.git
synced 2026-10-31 14:31:02 +00:00
The three capabilities dispatch to an AgentService trait rather than to the Tauri commands directly. Those commands need an AppHandle and a State, so depending on them here would make every handler untestable without booting an app and would entangle the capability layer with the desktop runtime. Behind the seam, handlers are pure and the tests below drive the real pipeline against a fake. The seams are async because the mutations they will call are: minting a key, writing the agent store, and publishing to the relay all await. That forces ExecutionLog to be a trait instead of a borrowed rusqlite::Connection, which is !Sync and must not be held across an .await. The production adapter confines each connection to one blocking task; the test double serializes behind a Mutex. Cross-call exclusion is SQLite's either way, since claim() does its read and insert inside a single IMMEDIATE transaction. ServiceError distinguishes Failed from Unknown. Failed promises no side effects persisted; Unknown promises nothing and becomes indeterminate. A service that mutated and then lost track must say Unknown, because reporting a clean failure would invite a retry of something that may already have happened. Nothing in AgentService returns secret material: a create reports the new agent's pubkey, never its nsec. A test serializes a create response and asserts the absence of nsec, privateKey, private_key, and secret, so the guarantee is checked rather than asserted in a comment. Co-authored-by: Bradley Axen <baxen@squareup.com> Signed-off-by: Bradley Axen <baxen@squareup.com>