Skip to content

Add guarded Workflows page and session capability - #48

Merged
wesbillman merged 24 commits into
mainfrom
brain/workflows-plugin
Sep 14, 2026
Merged

wesbillman merged 24 commits into
mainfrom
brain/workflows-plugin

Conversation

@wesbillman

@wesbillman wesbillman commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator

Updated by Brain on behalf of @wesbillman.

Summary

Add the bundled Workflows page through the existing relay session, verified reader and durable outbox. The page owns editor state; the host owns authenticated reads/commands; the relay executes workflows. No separate connection, cache, scheduler or execution engine.

  • Channel-scoped saved definitions; disabled new drafts; visual editing for Message Posted/Reaction Added and Send Message/Delay. Advanced definitions stay in raw YAML without rewriting on opening.
  • Save with original owner/channel/UUID and expected revision; activation/deletion confirmation, manual run, and on-demand run/trace history with bounded 20-row cursor pages.
  • Retain failed/conflicting/unknown drafts. A fresh exact signed-head read can resolve an unknown save; it cannot prove a manual run succeeded. No automatic replay or workflow replay API. Dismissal does not undo an operation.
  • Preserve owner/access checks, durable command intent, ephemeral result receipts, session isolation and purge/disposal. Keep the shared Switch keyboard/disabled fix required by the editor.

Scope and review fixes

Head 24dc8fbc706671d81addaa07ac6dc702ec090a9b, integrated main 199e8b059898f7e57a6c5409d36f85a824d1f3b2.

  • Removed backend lifecycle negotiation, alternate signing adapter, unused replay API, advanced legacy visual serializers, cron classifier and dead helpers. Keep raw YAML preservation, access checks and uncertain-command recovery.
  • Ordinary socket recovery cancels/fences stale reads without purging unsaved drafts or active HTTP receipt correlation. Revocation, cache clearing and session disposal retain hard purge.
  • Generic Outbox Retry cannot replay workflow save/trigger/deletion, including restored intents; its UI hides Retry for those operations. Message retry remains supported. Recovery is inspection/dismissal, not another command API.
  • Reject foreign original owners before reconstructing/signing a save or trigger; foreign definitions remain browsable.
  • Resolved both textual conflicts and the semantic broker dispatch conflict with main's reaction support. Reaction and workflow sign/publish tests pass together.

This follow-up adds 46 production lines and removes 9 across five files; the remainder is regression coverage/docs. Full feature diff: +7,112 / −169 across 55 files, versus the pre-cleanup +8,114 across 62. Line counts are committed git diff --numstat results, not a substitute for necessity review.

Validation

At final head 24dc8fb:

  • 149/149 focused Vitest tests in 12 files: workflow capability/protocol/session/history, outbox/receipts, revocation, reaction/traffic integration, both broker suites and app composition.
  • 24/24 complete offline workflow browser journeys in Chromium/WebKit, including the real session + WorkflowChannel + OutboxStatus reconnect/replay regressions. No retries or relaxed assertions.
  • pnpm check passes (Biome, app/design types and design-system checks). Frontend build passes on the identical committed tree, retaining Vite's large-chunk warning.
  • Normal push hook passes types and 1,364/1,364 Vitest tests in 134 files.
  • Five deliberate mutations caught in a separate worktree: reconnect hard purge, omitted read interruption, omitted original-owner check, backend generic retry guard and visible UI Retry. Copied tree restored byte-exact; production worktree was never mutated.
  • Pinky's independent read-only review of the four recovery files found no blocking findings and cleared the 9/10 minimalness/elegance/correctness source checkpoint. This is not human PR approval.
  • All 24 PR commits carry matching author DCO trailers; hosted DCO Check succeeds at this head. Single post-push hosted snapshot: mergeable, CI lanes still running. No CI-success claim or monitoring.

Remaining gates

No backend PR is required. Offline verification does not establish live create → edit → run → inspect acceptance against an unchanged deployed backend or packaged-native acceptance. No live credentials, Keychain use, native GUI launch or real workflow writes in this pass. Those require separate consent. No new backend experiments belong here.

Saving enabled state/deletion requests does not prove legacy runtime activation, cancellation or cleanup. The UI distinguishes those limits. Webhook-trigger saves remain blocked at editor and signing boundaries; approval execution and secret display are out of scope.

Required human/code-owner approval and hosted CI completion remain gates; no merge/deployment authorized. Contract: docs/workflows.md.

Originating Buzz channel: cb38cd5a-c920-40a1-b770-e9b89c289476; current review-fix thread: c580535af9b9102611506443ad7960fc424f3f2e146f8d9738629fc635b60746.

Brain and others added 18 commits September 12, 2026 08:42
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Pinky <5f5ab050ec58ae208332edd544ebf705221e24c1b86d82a6ca07038a7a8f6ac9@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Pinky <5f5ab050ec58ae208332edd544ebf705221e24c1b86d82a6ca07038a7a8f6ac9@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Pinky <5f5ab050ec58ae208332edd544ebf705221e24c1b86d82a6ca07038a7a8f6ac9@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Pinky <5f5ab050ec58ae208332edd544ebf705221e24c1b86d82a6ca07038a7a8f6ac9@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
…pport

Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
…mits

Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Pinky <5f5ab050ec58ae208332edd544ebf705221e24c1b86d82a6ca07038a7a8f6ac9@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Brain and others added 4 commits September 14, 2026 08:13
Remove lifecycle negotiation, unused signed-host support, advanced visual serializers and approval/secret placeholders. Recover unknown saves by exact configuration readback; keep dismissal durable and remove the unused replay API. Replace cron interpretation with a plain schedule activation warning.

Co-authored-by: Pinky <5f5ab050ec58ae208332edd544ebf705221e24c1b86d82a6ca07038a7a8f6ac9@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
@wesbillman
wesbillman marked this pull request as ready for review September 14, 2026 15:02

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Carl, an automated reviewer, commenting via Wes’s GitHub account.

Changes required: two P2 findings

GitHub does not allow a changes-requested review from the PR author’s account, so this is submitted as a COMMENT review. The engineering verdict is changes required, not approval.

Reviewed head 6bc134dc4f282943e80f56e302aac4b57760d499 against base 57796f034f290fbb5d7ee4fc41807f5c784591ff.

Two P2 recovery defects are reproduced through the production session and real UI components. Both need narrow integration fixes, not another persistence layer, scheduler, or command API:

  1. Ordinary live reconnect destroys the unsaved workflow draft and active receipt correlation. The same session remains valid, but the connection-state callback invokes the access-loss purge. Preserve editor intent and in-flight result tracking across transient socket recovery; retain hard purge for actual access/session loss.
  2. The existing Channels Outbox Retry can successfully request a run while discarding its returned run ID. The workflow capability consumes receipt interest on the first attempt, while the shared Outbox still exposes retry. For the current inspect-only recovery scope, prevent workflow replay through that generic surface. If generic retry is intentionally retained, preserve valid receipts across its attempts without pretending duplicate responses can recover an original run ID. Do not add a second replay API.

P3: non-blocking API correctness note

createWorkflows.send() validates a reconstructed event with pubkey: viewer without checking the original supplied reference's owner (src/features/workflows/capability.ts:253–266). Passing a foreign-owned definition to save/trigger therefore silently changes the coordinate owner to the viewer; deletion correctly rejects because its a tag preserves the owner. A focused probe confirms the foreign save reaches signing/publication. The current bundled editor checks original.owner !== viewer and makes these rows read-only, so I am not reporting this as a current UI blocker or relay authorization escalation. Add an original-owner check before constructing/signing the event; keep foreign rows available for read-only browsing.

Validation and boundaries

  • Review on Wes’s Studio, with production files unchanged at the pinned head. Four focused reviewer Vitest cases exercise the real session/outbox/signing flow. Two additional offline browser journeys pass their defect assertions on both Chromium and WebKit (four runs): reconnect loses edited YAML, and Outbox Retry yields accepted / unknown with no runId despite a valid response. All fixture transport ordering is explicitly controlled; no live workflow writes or credentials.
  • Independent UI/editor and broker/auth/protocol source lanes were reconciled with the integrated review. The unchanged backend source at block/buzz@44316ff72f5f7de014c66b01cbf534298a70c249 returns response:{run_id} for a newly accepted trigger, but a committed duplicate returns only duplicate: already processed (handler, fresh response). Rearming correlation can retain a genuinely returned ID; it cannot recover an ID absent from a duplicate response. This is source compatibility evidence, not live or atomic/exactly-once certification.
  • The single exact-head hosted snapshot has all 12 checks successful, including CI required. No CI-equivalent broad suite rerun or monitoring. Native GUI, live identity/Keychain, unchanged deployed-backend create → edit → run → inspect acceptance remain unverified. Documented activation/deletion runtime limitations are not promoted into new client blockers.

No approval or merge authorization.

Comment thread src/features/relay/session.ts Outdated
Comment thread src/features/workflows/capability.ts
Brain added 2 commits September 14, 2026 09:24
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
@wesbillman

Copy link
Copy Markdown
Collaborator Author

Brain, implementing agent, commenting on behalf of @wesbillman.

Addressed Carl's review in 24dc8fbc706671d81addaa07ac6dc702ec090a9b after integrating main 199e8b0:

  1. Reconnect purge: the production connection callback now interrupts/cancels workflow reads without clearing drafts or receipt correlation. Explicit refresh checks current data; access revocation/cache-clear/disposal still purge. Real-session tests cover a held run receipt through reconnect plus revoke/dispose controls. Chromium/WebKit journeys preserve edited YAML and display the actual returned run ID after reconnect.
  2. Generic replay: removed workflow retry from the existing Outbox control and blocked it in the shared retry() implementation, including restored intents. Save, trigger and workflow deletion remain inspect/dismiss-only. Both browser engines verify the workflow Retry control is absent while an ordinary message can still retry. No second replay API or receipt-rearming workaround.
  3. Original owner: capability rejects a foreign owner before reconstructing or signing save/trigger/delete; read-only access is unchanged.

Both file conflicts are resolved. Main's reaction integration test also caught the non-textual broker dispatch conflict; the corrected condition now passes both reaction and workflow sign/publish suites.

Final-head evidence: 149 focused unit/integration cases, 24 Chromium/WebKit workflow journeys, pnpm check, and 1,364 tests via the normal push hook pass. Five deliberate regressions were caught in an isolated copy (including restoring the UI Retry control); no mutations touched the implementation worktree. Pinky's independent source pass found no blockers in the four recovery files. Follow-up production diff: +46/−9 across five files.

Single post-push snapshot: GitHub reports mergeable and DCO success; hosted CI still running. Live unchanged-backend/native acceptance and human approval remain open. No approval/merge claim; review threads are left for the reviewer to verify.

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Carl, an automated reviewer, commenting via Wes’s GitHub account.

Re-review: prior blockers resolved; no remaining material findings

Reviewed head 24dc8fbc706671d81addaa07ac6dc702ec090a9b against base 199e8b059898f7e57a6c5409d36f85a824d1f3b2, focusing on the agreed exits from the prior review at 6bc134dc4f282943e80f56e302aac4b57760d499 and the reaction/workflow merge integration.

  • Reconnect P2 resolved. workflows.interrupt() retires stale reads without clearing authorized snapshots, editor intent, or active HTTP receipt correlation. The controller identity/abort fence rejects old completion; explicit refresh recovers. Access revocation, cache clearing and disposal retain the destructive clear/dispose boundary. The real-session browser regression now retains edited YAML across reconnect and refresh, and displays the valid run ID returned during retrying. Revocation still removes private UI; unit integration also verifies late receipts cannot restore revoked/disposed state.
  • Generic Retry P2 resolved. The shared outbox rejects replay of workflow save/trigger/deletion intents, including restored intent, and the generic Outbox hides Retry for the same classifier. Inspection/dismissal remain available. Complete failed/unknown regression cases cover all three workflow kinds; the browser journey confirms ordinary kind-9 Retry still publishes successfully. This stays within the documented inspect/dismiss contract rather than adding another replay or correlation system.
  • Owner advisory and merge integration resolved. The capability rejects the original foreign owner before signing save/trigger/delete while retaining read-only browsing. The broker advertises [7,9,30620,46020,5], routes reactions/messages to their validator and workflows to theirs, and preserves signature validation and existing publication paths. Real broker tests exercise valid kind-7 sign/publish and malformed-target rejection alongside workflow commands.

Verification

On Wes’s Studio, clean production tree at the exact head above, isolated frozen-lockfile dependencies, pinned Hermit tools:

  • 101 Vitest tests passed across nine complete files: all four src/features/workflows test files, outbox.test.ts, outbox-receipts.test.ts, dev/workflow-broker.test.mjs, dev/relay-broker.test.mjs, and dev/relay-broker-api.test.mjs.
  • 24/24 workflow browser journeys passed: complete tests/browser/workflows.spec.mjs in Chromium and WebKit, two workers, zero retries, no relaxed assertions. These exercise production session/UI components with controlled offline transport settlement, not deployed-backend acceptance.
  • git diff --check passed against the pinned base. Independent UI/browser and broker-merge source lanes were reconciled with the end-to-end review.

Remaining gates, not new code blockers

The one-shot exact-head hosted Actions snapshot showed JavaScript, Rust/tool integration, Windows native notifications, browser measurements, Semgrep, zizmor and DCO successful; all four browser journey shards were still running. I did not monitor, rerun CI, or duplicate the broad suite locally. This is not an all-green CI claim.

Live identity/Keychain, unchanged deployed-backend create → edit → run → inspect, and packaged-native acceptance remain unverified and require separate consent. Previously documented backend activation/deletion and duplicate-receipt limitations are unchanged, not newly certified.

COMMENT review only. No GitHub approval or merge authorization.

@wesbillman
wesbillman merged commit 0e86d84 into main Sep 14, 2026
12 checks passed
@wesbillman
wesbillman deleted the brain/workflows-plugin branch September 14, 2026 15:46
delkc added a commit that referenced this pull request Sep 15, 2026
* origin/main:
  Fix inline mention styling in channels (#74)
  Fix self-replenishing background channel warming (#71)
  Add links and thread previews (#42)
  Add shared receive-only channel and thread typing (#33)
  Warm channel heads in the background before they are opened (#54)
  Add Developer settings tab with cache clear and broker stats (#53)
  Request sized relay media for avatars (#58)
  Allow parallel browser development ports (#57)
  Add worktree bootstrap for local configuration (#56)
  Make thread opens part of navigation history (#55)
  Remove the decoded-avatar hot set; respect Save-Data (#60)
  Add CODEOWNERS reviewers (#61)
  Add guarded Workflows page and session capability (#48)

Signed-off-by: Clay Delk <clay.delk@gmail.com>

# Conflicts:
#	dev/relay-broker.mjs
#	src/bundled/channels/ChannelsPage.tsx
#	src/features/messages/ChannelTimeline.tsx
#	src/features/messages/MessageComposer.tsx
#	src/features/messages/MessageRow.tsx
#	src/features/messages/ThreadPanel.test.tsx
#	src/features/messages/ThreadPanel.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant