Skip to content

goal 0017: real-time surfaces audit — direct-UI/service mutations now emit mill-data-changed - #16

Merged
alicoding merged 1 commit into
mainfrom
goal/0017-realtime-surfaces-audit
Aug 12, 2026
Merged

goal 0017: real-time surfaces audit — direct-UI/service mutations now emit mill-data-changed#16
alicoding merged 1 commit into
mainfrom
goal/0017-realtime-surfaces-audit

Conversation

@alicoding

Copy link
Copy Markdown
Owner

Summary

  • Root cause: only mcpsvc emitted mill-data-changed (MCP-authored writes only) — CompositionService/ConfigureService/GuardrailService emitted nothing, so a direct-UI create/edit/delete never reached another open surface.
  • New shared internal/services/dataevent package is the one place EventName/Changed/Emit live; every direct-mutation service now calls it (workflow/request/list/mcpserver/decision (new)/execenv (new)/guardrail-rule (new)).
  • Fixed App.tsx's mill-data-changed routing (was misrouting list/mcpserver to refreshRequests()+refreshWorkflows(), neither of which holds either).
  • New shared/configureEntityStore.ts backs Configure's Lists/Decisions/MCP Servers/ExecEnv sections (mirrors store.ts's workflows/requests pattern) so a live update reaches an already-mounted tab; ConfigureAttributes switched to the existing shared workflows store.
  • WorkflowRunsPanel/HomeView/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 fallback).
  • docs/SPEC.md's realtime bullet documents the "including Mill's own UI mutations" gap this closes. Goal file archived, BACKLOG.md updated.

Test plan

  • Go unit tests per service using a new dataevent.TestHook seam (compositionservice_dataevent_test.go, configureservice_dataevent_test.go, guardrailservice_dataevent_test.go)
  • New e2e spec realtime-cross-surface.spec.ts: an MCP-authored import_list reaching 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
  • Full local lefthook pre-commit suite green (go-vet, golangci-lint, go-test -race, file-loc-limit, boundaries, vitest, eslint, tsc, go-build-desktop/server, root-file-naming)
  • Full Playwright e2e suite run (169 relevant specs green; one transient worker-contention flake confirmed passing in isolation, this repo's own documented local-only flake class)

🤖 Generated with Claude Code

https://claude.ai/code/session_01FYwojT8GdUbYSoggbvEFft

…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
@alicoding
alicoding merged commit 87d3bd6 into main Aug 12, 2026
16 checks passed
@alicoding
alicoding deleted the goal/0017-realtime-surfaces-audit branch August 12, 2026 07:23
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
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