Skip to content

Commit bb4916c

Browse files
alicodingclaude
andauthored
docs: goal 0057 queued -- live-sync audit, no reload ever (owner-directed) (#112)
Claude-Session: https://claude.ai/code/session_01FJ8wStsHyu7XPLTspNjMnQ Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 02d2d8a commit bb4916c

2 files changed

Lines changed: 81 additions & 11 deletions

File tree

docs/goals/0057-live-sync-audit.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# 0057 — Live-sync audit: no surface ever needs a reload
2+
3+
**Raised:** 2026-08-14, owner-directed after hitting the runs-panel
4+
staleness live ("the problem is that it is not real time — why do we
5+
have to reload our app ever in any part; can we now look at other
6+
parts of the app to make sure we don't have similar issues").
7+
Queue position: ahead of 0052 (owner-picked by asking now).
8+
9+
## The bug class this generalizes
10+
11+
The runs-panel instance (fixed in its own PR, with regression test
12+
`TestRunWorkflow_EmitsRunDataEventOnStartAndCompletion`): a surface
13+
fetches once on mount, stays mounted across tab switches, and relies
14+
on `mill-data-changed{entity}` to refresh — but one or more mutation
15+
paths for that entity never emit. Result: data a user watches goes
16+
stale, or appears empty, until a full app reload. Goal 0017
17+
established the event and swept the then-known surfaces; this goal
18+
audits systematically instead of waiting for the next live hit.
19+
20+
The principle (goal 0017's, now stated as the app-wide invariant):
21+
**a user must never need to reload Mill to see the current state of
22+
anything the app displays.** Every displayed collection/state either
23+
(a) subscribes to the entity events its data derives from, with every
24+
mutation path emitting them, (b) deliberately polls (the in-flight
25+
run detail's honest-only-path pattern), or (c) is provably immutable
26+
for the session. Anything else is a gap.
27+
28+
## Plan
29+
30+
1. **Inventory (delegated, read-only):** complete matrix of
31+
emitters (`dataevent.Emit` + other Go→frontend events), frontend
32+
`Events.On` subscribers, fetch-once-no-subscription components,
33+
and mutating service methods without emits.
34+
2. **Judgment pass (main session):** classify every candidate as
35+
real gap / deliberate poll / session-immutable, recorded in this
36+
file. Surfaces where the entity string doesn't exist yet get one
37+
named (the dataevent entity vocabulary is the contract).
38+
3. **Fix the real gaps** — emits at mutation chokepoints (the
39+
runs-panel fix's shape), subscriptions where a panel listens to a
40+
subset of its entities; each fix carries a TestHook-seam
41+
regression test per testing.md. Cluster into one PR if small,
42+
or per-surface PRs if not.
43+
4. **Prevention:** extend the goal-0017 per-service emit-test
44+
pattern to any mutating service that has none, so a future
45+
mutation path can't land emit-less unnoticed. No new framework —
46+
the dataevent seam already exists; this is coverage, not
47+
machinery.
48+
49+
## Acceptance (checkable)
50+
51+
- [ ] The inventory matrix (or a distilled gap table) is recorded in
52+
this file, every fetch-once surface classified as
53+
gap / deliberate-poll / session-immutable with a reason.
54+
- [ ] Every classified gap is either fixed (emit + subscription +
55+
regression test at the TestHook seam) or explicitly rejected
56+
with a reason recorded here.
57+
- [ ] Every mutating service package has emit coverage in its tests
58+
for the methods that mutate displayed state.
59+
- [ ] No surface in the app requires a reload to reflect a mutation
60+
Mill itself performed — spot-checked live on at least the
61+
surfaces the inventory flagged most suspicious.

docs/goals/BACKLOG.md

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,17 @@ accepted)**
5656
in the workflow"; generic without being engineer-only; run
5757
history already says step). UI copy sweep here; wire names land
5858
inside 0052 (sequenced before it so the contract never freezes
59-
the rejected word); internal identifiers untouched
60-
6. [ ] [0052 — Contract maturity: generated schema + versioned envelope](0052-contract-surface.md)
59+
the rejected word); internal identifiers untouched.
60+
IMPLEMENTED 2026-08-14 (PR #110 merged); box 3 (0052 wire names)
61+
stays open pending 0052
62+
6. [ ] [0057 — Live-sync audit: no reload, ever](0057-live-sync-audit.md)
63+
— owner-directed 2026-08-14 after the runs-panel staleness hit
64+
live ("why do we have to reload our app ever in any part");
65+
generalizes that bug class: inventory every emit/subscription/
66+
fetch-once surface, fix real gaps with TestHook-seam regression
67+
tests, emit-coverage tests per mutating service. Queue-jumped
68+
ahead of 0052 by the owner's ask
69+
7. [ ] [0052 — Contract maturity: generated schema + versioned envelope](0052-contract-surface.md)
6170
— owner-directed 2026-08-13 ("follow the mature pattern") after
6271
the far-side contact: schema-first discipline adopted as generated
6372
JSON Schema from Go types (protobuf/gRPC/OpenAPI rejected with
@@ -66,19 +75,19 @@ accepted)**
6675
coordinates schema-id evolution semantics with 0046's ADR.
6776
Sequenced directly after 0044 — the dry run sharpens what the
6877
contract must express
69-
7. [ ] [0054 — Step designer + declare-vs-code boundary](0054-step-designer.md)
78+
8. [ ] [0054 — Step designer + declare-vs-code boundary](0054-step-designer.md)
7079
— owner-directed 2026-08-13: declare new step types in-product
7180
(v1 = promote HTTPRequest operations / MCP tools / child
7281
workflows into named palette types, stored as data) + the ADR
7382
ratifying WHEN code is genuinely required (new engine) vs
7483
declaration suffices (naming/mapping over existing engines).
7584
After 0052 — declared types must be first-class in the generated
7685
contract from day one; benefits from 0047's palette facet
77-
8. [ ] [0055 — Canvas note block](0055-canvas-note-block.md)
86+
9. [ ] [0055 — Canvas note block](0055-canvas-note-block.md)
7887
— owner-raised 2026-08-14 (n8n sticky-note precedent): annotation
7988
in the authoring space; not a step (no ports/execution); rides
8089
the workflow envelope, so coordinates with 0052's schema
81-
9. [ ] [0056 — Workbench boundary definition](0056-workbench-boundary.md)
90+
10. [ ] [0056 — Workbench boundary definition](0056-workbench-boundary.md)
8291
— owner-raised 2026-08-14 ("we never truly defined what Mill
8392
boundary to be"): the POSITIVE product statement — capture lands
8493
somewhere useful, grouped, findable, transformable, every
@@ -87,14 +96,14 @@ accepted)**
8796
contacts/links differ only in schema+routing (one collections
8897
capability, never N hardcoded verticals — anti-goal recorded);
8998
build goals queue after its verdict
90-
10. [x] [0045 — v0.2.0 + release cadence](archive/0045-release-cadence.md)
99+
11. [x] [0045 — v0.2.0 + release cadence](archive/0045-release-cadence.md)
91100
— DELIVERED 2026-08-13: cadence rule LOCKED in SPEC §1.3
92101
(tag-on-capability-goal-archive; the asset is the launchable
93102
mill.app zip, clone-build stays the documented dev path); v0.2.0
94103
live and attestation-verified. The cut surfaced and fixed three
95104
more latent defects (raw-binary asset, release.yml invalid YAML —
96105
now gated by workflow-lint, GPL-3 setup-task action wrapper)
97-
11. [ ] [0051 — Run-analytics dashboard v2](0051-run-analytics-dashboard.md)
106+
12. [ ] [0051 — Run-analytics dashboard v2](0051-run-analytics-dashboard.md)
98107
— owner-directed 2026-08-13; research DELIVERED same day (n8n/
99108
Zapier/Make/Windmill/Temporal/Airflow/Power Automate survey): Home
100109
already covers most of the converged set; ships avg-duration KPI +
@@ -103,17 +112,17 @@ accepted)**
103112
Activity; two data-model gaps recorded as deferred (per-step
104113
timestamps, trigger fire-log). Slotted ahead of 0049/0050 per the
105114
UX-first tiebreak
106-
12. [ ] [0049 — Docs anti-rot mechanics](0049-docs-anti-rot.md)
115+
13. [ ] [0049 — Docs anti-rot mechanics](0049-docs-anti-rot.md)
107116
— owner-ratified 2026-08-13 from the two-agent docs survey: path-
108117
reference checker (lefthook+CI), generated ADR index with
109118
drift-fail, revive package-comments floor, AGENTS.md interop,
110119
README Spec-view fix; rejected list recorded in the goal file
111-
13. [ ] [0050 — Codebase structure audit](0050-codebase-structure-audit.md)
120+
14. [ ] [0050 — Codebase structure audit](0050-codebase-structure-audit.md)
112121
— owner-raised 2026-08-13 (OSS flat-structure critique): audit
113122
layout against official Go guidance + what OSS reviewers actually
114123
flag, verdict table + a citable layout ADR; only audit-justified
115124
moves, no conformance churn
116-
14. [ ] [0046 — Schema evolution](0046-schema-evolution.md)
125+
15. [ ] [0046 — Schema evolution](0046-schema-evolution.md)
117126
owner-raised from a real regulated-platform incident
118127
(rename-forbidden / retype-permanent / live-referenced decisions
119128
forcing a ~30-version manual cleanup); research delivered
@@ -123,7 +132,7 @@ accepted)**
123132
Mill's Configure entities are live-referenced (a pinned workflow
124133
still resolves TODAY's decision definition) and deletes have no
125134
reference-integrity check
126-
15. [ ] [0047 — Node audience/complexity facet](0047-node-audience-facet.md)
135+
16. [ ] [0047 — Node audience/complexity facet](0047-node-audience-facet.md)
127136
— owner-proposed; session recommendation recorded: function stays
128137
the primary palette grouping, audience/complexity becomes a
129138
NodeType metadata field + progressive-disclosure facet (not a

0 commit comments

Comments
 (0)