goal 0017: real-time surfaces audit — direct-UI/service mutations now emit mill-data-changed - #16
Merged
Merged
Conversation
…ed too Root cause (audit, 2026-08-12): only mcpsvc emitted the live-sync event, so an MCP-authored change propagated to every open surface but a plain UI create/edit/delete never did. Gives CompositionService, ConfigureService, and GuardrailService their own emit via a new shared internal/services/dataevent package (the one place EventName/Changed/ Emit are now defined, replacing mcpsvc's locally-owned copies); GuardrailService's rule CRUD introduces a new "guardrail-rule" entity, ConfigureService's decision/execenv CRUD introduce "decision"/ "execenv". Fixes App.tsx's mill-data-changed routing, which misrouted list/mcpserver to refreshRequests()+refreshWorkflows() (neither store holds either) instead of doing nothing useful at all. Frontend: a new shared/configureEntityStore.ts (mirrors store.ts's workflows/requests pattern) backs Configure's Lists/Decisions/MCP Servers/ExecEnv sections, replacing each page's own local-state fetch so a live update from another surface actually reaches an already-mounted tab; ConfigureAttributes switches to the existing shared workflows store. WorkflowRunsPanel, HomeView, and ActivityRunsExplorer subscribe to entity:"run"; CompositionView's armed-badge refresh and useGuardrailBadges subscribe to entity:"workflow"/"guardrail-rule"; ReviewView adds a guardrail-pending-changed subscription alongside its existing 2s poll (kept as the documented DBOS-has-no-per-step-event fallback). Proofs: per-service Go tests using a new dataevent.TestHook seam (application.Get() is always nil under `go test`, so this is the only way to observe an Emit call); a new e2e spec (realtime-cross-surface.spec.ts) proves the flagship two-surface scenario both directions — an MCP-authored import_list reaching an open Configure > Lists tab, and a direct-UI workflow create in one browser window reaching a canvas picker open in a second window — neither page ever reloads. docs/SPEC.md's realtime bullet gets a note on the "including Mill's own UI mutations" gap this closes. Goal file moved to archive/, BACKLOG.md updated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYwojT8GdUbYSoggbvEFft
4 tasks
alicoding
added a commit
that referenced
this pull request
Aug 15, 2026
goal 0017: real-time surfaces audit — direct-UI/service mutations now emit mill-data-changed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
mcpsvcemittedmill-data-changed(MCP-authored writes only) —CompositionService/ConfigureService/GuardrailServiceemitted nothing, so a direct-UI create/edit/delete never reached another open surface.internal/services/dataeventpackage is the one placeEventName/Changed/Emitlive; every direct-mutation service now calls it (workflow/request/list/mcpserver/decision (new)/execenv (new)/guardrail-rule (new)).App.tsx'smill-data-changedrouting (was misroutinglist/mcpservertorefreshRequests()+refreshWorkflows(), neither of which holds either).shared/configureEntityStore.tsbacks Configure's Lists/Decisions/MCP Servers/ExecEnv sections (mirrorsstore.ts's workflows/requests pattern) so a live update reaches an already-mounted tab;ConfigureAttributesswitched to the existing shared workflows store.WorkflowRunsPanel/HomeView/ActivityRunsExplorersubscribe toentity:"run";CompositionView's armed-badge refresh anduseGuardrailBadgessubscribe toentity:"workflow"/"guardrail-rule";ReviewViewadds aguardrail-pending-changedsubscription alongside its existing 2s poll (kept as the documented fallback).docs/SPEC.md's realtime bullet documents the "including Mill's own UI mutations" gap this closes. Goal file archived,BACKLOG.mdupdated.Test plan
dataevent.TestHookseam (compositionservice_dataevent_test.go,configureservice_dataevent_test.go,guardrailservice_dataevent_test.go)realtime-cross-surface.spec.ts: an MCP-authoredimport_listreaching an open Configure > Lists tab live, and a direct-UI workflow create in one browser window reaching a canvas picker open in a second window — neither page reloads🤖 Generated with Claude Code
https://claude.ai/code/session_01FYwojT8GdUbYSoggbvEFft