Add owner-authorized manual workflow triggers - #6964
Conversation
ca2c16c to
e191591
Compare
59cdda3 to
5c314b3
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
8368014 to
bb7de1e
Compare
f9a9a12 to
0f5fded
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
bb7de1e to
8a1ec91
Compare
0f5fded to
afaf077
Compare
Co-authored-by: Larry <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
Co-authored-by: Larry <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
Co-authored-by: Larry <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
Co-authored-by: Larry <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
Co-authored-by: Larry <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
Signed-off-by: Logan Johnson <loganj@squareup.com>
Signed-off-by: Logan Johnson <loganj@squareup.com>
afaf077 to
143744f
Compare
jedwards27
left a comment
There was a problem hiding this comment.
Review verdict: request changes
Reviewed exact head 143744f8d8768b7209f65a9486580d3d89b228ec against base 92f15c042a3e314483bcb5478f9525b81681f2c2.
1. Major — Desktop retry does not preserve the operation identity after ambiguous delivery
desktop/src-tauri/src/commands/workflows.rs:321-341 rebuilds a trigger for each command invocation. The builder generates a fresh random request ID (crates/buzz-sdk/src/builders.rs:1643-1678), while submit_event keeps the signed event only for the current call and drops it on transport/status/parse failure (desktop/src-tauri/src/relay/submit.rs:16-50,58-78). Relay duplicate recovery is keyed to the exact event ID (crates/buzz-relay/src/handlers/command_executor.rs:992-1005).
If the relay commits a trigger/run but its response is lost, Desktop reports failure; the user's retry builds a different event and can execute a second run, duplicating messages, webhooks, or other external effects. This defeats the retry/idempotency contract added by the PR.
Author action: retain and resubmit the exact signed trigger across outcome-ambiguous failures. If restart recovery is promised, journal it durably and scope it to relay/community/identity. Add a production-seam regression that commits the first request, loses its response, retries through Desktop, and asserts one event ID, one run ID, and one side effect; mutation-prove that rebuilding on retry fails the test.
Verification owner: author for implementation/regression; reviewer for exact-head renderer → Tauri → relay confirmation.
2. Moderate — Primary Desktop trigger paths silently fail and animate before settlement
The main card/editor paths invoke the mutation without error handling (desktop/src/features/workflows/ui/WorkflowsView.tsx:155-162,208-212; desktop/src/app/AppWorkflowEditorOverlayProvider.tsx:98-105,118-122), and the card starts its action animation before the request settles (desktop/src/features/workflows/ui/WorkflowCard.tsx:285-288). The explicit alert in WorkflowDetailPanel.tsx:144-154 does not cover these primary entry points. Current E2E counts the mocked command invocation, bypassing revision fetch, signing, and relay rejection/acceptance (desktop/tests/e2e/workflows.spec.ts:1042-1063; desktop/src/testing/e2eBridge.ts:4032-4043).
A stale revision, disabled workflow, revoked authority, or network failure therefore produces no actionable user-visible result while motion implies the workflow fired, encouraging retries and amplifying finding 1.
Author action: provide accessible pending/error/retry state on every trigger entry point and animate success only after confirmed run creation. Add rejection/retry coverage beyond the mock invocation counter, including at least one revision GET → signing → relay acceptance/rejection integration path.
Verification owner: author for behavior/tests; reviewer for product and integration verification.
Validation and residual risk
Two independent review lanes traced the production seam and confirmed both findings. On the same clean head, package runs passed for buzz-sdk, buzz-cli, and buzz-workflow (workflow: 169 passed, 2 ignored); git diff --check passed. GitHub currently reports 31 successful and 6 skipped checks, including PostgreSQL, relay/backend E2E, Desktop core/integration, macOS, and Windows. Green CI does not exercise the committed-response-loss retry boundary above.
Native GUI/VoiceOver observation was not run on the shared machine; this is a reviewer confidence gap, not separate author rework. A possible crash window after run commit and before spawned execution remains unproven and is not an additional blocker in this review.
jedwards27
left a comment
There was a problem hiding this comment.
Review verdict: request changes
Reviewed base 92f15c042a3e314483bcb5478f9525b81681f2c2 through exact live head 143744f8d8768b7209f65a9486580d3d89b228ec, integrating both assigned lanes. Both independently confirmed two author-actionable defects.
1. Desktop retries can execute a workflow twice after an ambiguous committed delivery
Desktop builds a trigger with a fresh randomized request-id and immediately performs one-shot submission (desktop/src-tauri/src/commands/workflows.rs:321-341; crates/buzz-sdk/src/builders.rs:1643-1678). The signed event exists only in that call stack and is discarded on transport/status/parse error (desktop/src-tauri/src/relay/submit.rs:16-50,58-78). A user retry rebuilds a different event. Relay duplicate recovery, however, is keyed to the exact original event ID (crates/buzz-relay/src/handlers/command_executor.rs:992-1005).
If the relay commits the first run but its response is lost, Desktop reports failure; retry creates a second run and can duplicate message/webhook/external effects. The server idempotency mechanism is sound, but the shipped caller cannot use it at the outcome-ambiguous boundary.
Author action: retain and resubmit the exact signed trigger across ambiguous outcomes, durably if restart recovery is promised. Add a production-seam committed-response-loss regression asserting one event ID, one run ID, and one side effect; mutation-prove rebuilding on retry fails.
2. Primary Desktop trigger paths silently fail and animate before settlement
The card/editor entry points call mutate without error handling (desktop/src/features/workflows/ui/WorkflowsView.tsx:155-162,208-212; desktop/src/app/AppWorkflowEditorOverlayProvider.tsx:98-105,118-122), while WorkflowCard starts its action animation before the request settles (WorkflowCard.tsx:285-288). Stale revision, disabled/revoked authority, preflight, and network rejection therefore produce no actionable status while the UI implies firing—encouraging the dangerous retry above.
Author action: expose accessible pending/error/retry state on every trigger entry point, animate success only after confirmed run creation, and add rejection/retry coverage that binds revision fetch → Tauri signing → relay response rather than only a mock invocation counter.
Verification
Exact-head SDK/CLI/workflow package suites passed (workflow 169 passed, 2 ignored; SDK 304 passed). Relevant exact-head CI is green. Native GUI/VoiceOver and locally ignored PostgreSQL cases remain reviewer/CI confidence gaps, not additional author work.
— :bot: Jude’s code review agent
🤖
I’m Larry.
Summary
People can manually start workflows owned by their managed agents without allowing any channel member to run another owner’s automation. Each request identifies the exact signed workflow version it intends to run. Missing or stale versions, disabled workflows, and revoked authority are rejected.
The CLI and Desktop construct these requests through the shared SDK. Separate invocations create separate runs, including within the same second. Retrying the same signed request returns the original committed run ID and response while its authorization and version remain valid.
Related issue
Stacked on the exact-revision foundation (#6960). Replaces the manual-trigger portion of #6721; automatic agent mention waking is a separate sibling, #6965. No separate issue was identified in the earlier scope search.
Behavior and compatibility
Testing
Prior unchanged behavior: at
0f5fded7, Blox validation passed the full database/relay packages, root unit groups, Desktop Rust tests, formatting, and Clippy. The backend CI archive gate ran all 10 manual-trigger/revoked-owner regressions and 11 foundation database tests against a fresh desired-schema database. Coverage includes out-of-order and same-second requests, sequential and concurrent retries, authorization, approval version binding, and revoked-owner disclosure.Current candidate
143744f8d8768b7209f65a9486580d3d89b228ecis rebased only onto revised foundation92f15c04; manual-trigger source semantics are unchanged (range-diff preserved). Foundation 0043 retains nullable captured revision IDs and its mixed-writer invalidation guard, but length checks useNOT VALIDto avoid historical scans while enforcing subsequent writes. No extra migration belongs to this sibling, no inferred legacy revisions, and no deferred validation job. Schema-first rollout still takes relation locks; runtime opt-in migration has unbounded lock/statement timeouts.Earlier readiness is withdrawn pending exact-head CI and the shared database redesign review. Prior published
afaf0775completed 31 successful checks / 6 skips; prior focused 9 command-executor PostgreSQL and 169 workflow unit tests remain evidence for unchanged manual behavior, not the new head. Earlier broad local relay failures due to missing infrastructure remain recorded.The unchanged combined experiment passed a real signed manual trigger through executor/sink/storage and outer ACP, recovering four injected authority HTTP 503s before one session/one prompt (two-second duplicate observation). That used a disposable combined worktree and does not establish general exactly-once or actual reconnect behavior. Sibling topology remains unchanged; no merge or deployment.