Skip to content

Resumed /ux-cycle Arc — Closing Retrospective (Cycles 220-235)

📜 Historical snapshot — not current docs

Captured 2026-04-15 during Dazzle's autonomous-improvement cycles. It records the framework as it was then and the gap being worked at the time; it may not describe current behaviour. Start from the documentation home, or see Project Evolution for how these fit together.

Arc dates: 2026-04-15 (~16 hours of continuous operation, self-paced cycles) Total cycles: 16 (220 through 235) Cycle types exercised: edge_cases (2), missing_contracts (1), framework_gap_analysis (3), finding_investigation (8), verification_sweep (1), housekeeping (1)


What the user asked for

Three distinct directional inputs over the course of the arc:

  1. "Continue exploratory work to give them the strongest foundation we can achieve" — the frontier users (Penny Dreadful, Aegismark, Cyfuture) will surface domain-breadth gaps through real use; the loop's job is to harden the substrate underneath.
  2. "Identify interesting framework-level gaps — relax budgets, allow deep exploration and analysis tasks" — pivot from mechanical edge_cases rotation to judgment-driven strategy selection, with new framework_gap_analysis and finding_investigation modes, and a 30→100 budget expansion.
  3. "Continue our local entropy reduction work as an autonomous process for the next dozen cycles or so. The endpoint is ambiguous; we're continuing to identify interesting problems."

The arc's job was to reduce local entropy in the framework layer so frontier users land on firmer ground.

Scoreboard

Rows closed

Type Count Rows
FIXED_LOCALLY (framework code) 7 EX-028, EX-035, EX-040, EX-042, EX-043 (substrate), UX-004, (cycle 232 EX-009 date-half)
FIXED (verification sweep) 5 EX-003, EX-004, EX-008, EX-014, EX-020
VERIFIED_FALSE_POSITIVE 5 EX-011, EX-021, EX-030, EX-037, EX-039
SUSPECTED_FALSE_POSITIVE 2 EX-018, EX-034
PARTIALLY_FIXED 1 EX-009 (date half shipped; ref half → EX-044)
BLOCKED_ON_other_row 1 EX-041 (→ EX-045)
Total closed or reclassified 21

Net backlog change

Before cycle 224: 41 OPEN rows. After cycle 235: 20 OPEN rows (26 after cycle 231 − 3 cycle 234 false positives − 3 net new (EX-043 fixed, EX-044/045/046 open)).

~51% reduction in the OPEN backlog in 16 cycles, averaging 1.3 rows closed per cycle.

Framework fixes shipped

  1. v0.55.35 (cycle 220)#777 ref eager-loading for list routes
  2. Cycle 225 — DSL parser multi-line list support (scenario.py:_parse_string_list) + 2 regression tests. Unblocked default_workspace parsing for 3 apps.
  3. Cycle 226workspace_allowed_personas helper propagated to the ws_nav_items second builder at page_routes.py:1115 (retroactive completion of v0.55.34 #775's intent).
  4. Cycle 227 — New resolve_persona_workspace_route helper + _root_redirect structural cleanup + 11 regression tests. Fixed the fallback-to-workspaces[0] failure mode.
  5. Cycle 228 — Bulk-action bar persona suppression at page_routes.py:701, mirroring the existing Create-button pattern.
  6. Cycle 229 — Substrate fix: new form_submit helper action in playwright_helper.py with 250ms post-networkidle wait for HTMX swap.
  7. Cycle 232widget_hint = "picker" default for DATE/DATETIME fields in template_compiler._build_form_fields.

Gap doc landscape

# Title Start of arc End of arc
1 silent-form-submit Open, 5 contributing rows SUPERSEDED by cycle 229 (substrate artifact; framework already correct)
2 persona-unaware-affordances Open, 8 contributing rows Partially Fixed — 3 of 4 axes closed (workspace nav via #775+226, bulk-action bars via 228, empty-state CTAs verified-false-positive via 234). 1 remaining: create-form field visibility (overlaps with EX-044)
3 workspace-region-naming-drift Open Open — still fully valid, 6 contributing items, unchanged
4 error-page-navigation-dead-end Open (1 high-pri row) SUPERSEDED by cycle 225 (real cause was parser bug, not HTMX intercept)
5 NEW widget-selection-gap Open — written in cycle 230, date-half addressed in cycle 232, ref-half is EX-044

2 of 5 gap docs superseded by investigation, 1 partially fixed, 2 still open, 1 new surfaced mid-arc. The loop's synthesis-then-investigation pattern is working as intended: bad hypotheses die fast without blocking progress.

New framework-gap rows surfaced (EX-043 through EX-046)

  • EX-043 — Substrate bug in playwright_helper.action_type + action_click multi-call pattern loses form state. FIXED in cycle 229 via new form_submit action.
  • EX-044 — Widget-selection gap for ref fields. Structural template work required. OPEN as a future cycle target.
  • EX-045 — Persona-to-entity binding is an unresolved framework concept. Three fix directions documented (A/B/C), recommendation is A (explicit DSL persona x: backed_by: Y, link_via: z). OPEN — requires design discussion before implementation.
  • EX-046 — DSL has no per-persona override for empty: copy on entity surfaces. Three fix directions documented, recommendation is A (add empty: to for <persona>: blocks). OPEN — ~20 minute dedicated cycle when prioritised.

The five most important discoveries

1. Dazzle's framework is more correct than it appears

4 of 6 recent finding_investigation cycles had the hypothesised framework fix turn out to be unnecessary or wrong. The observations were correct at the surface level, but the cause was consistently somewhere else than the observer thought — substrate, observer limitations, DSL copy, or a deeper structural question.

The practical consequence: cycles that immediately trust observations and start building framework infrastructure are high-risk of shipping wrong code. The /ux-cycle skill's new Heuristic 1 (try the raw layer first) is load-bearing for future productive work.

2. Heuristic 1 has a 67% "would have built the wrong thing" hit rate

Cycles 229, 232 (ref-half), 233, 234 all had Heuristic 1 catch the observation-vs-reality gap before any unnecessary framework code was written. Only cycles 225 (parser bug) and 226 (missed nav builder) had investigations that confirmed the original hypothesis and shipped the fix.

This is strong enough evidence to promote Heuristic 1 from "recommended" to "mandatory" in the skill (encoded this cycle).

3. Two novel cycle types worth formalising

  • verification_sweep (cycle 231 shape): batch-verify N OPEN rows that share a common hypothesis — typically "resolved by a shipped fix" — at the lowest reasonable layer. Closed 5 rows in ~5 minutes of active time (fastest row-closure ratio of the arc).
  • helper_audit (cycles 226/228 pattern): pick a single-source-of-truth helper, walk every spot in the codebase where the relevant decision is made, check whether the helper is called. Catches pre-observation drift before it becomes cross-cycle evidence.

Neither is yet a named strategy in the skill. Worth adding in a future skill update once a second example of each surfaces.

4. The subagent substrate is a fidelity liability

Cycle 229's finding — the action_type + action_click multi-call pattern silently loses in-page form state across subprocess boundaries — invalidated three cross-cycle observations (EX-018, EX-034, EX-039) that had been building pressure for a gap-doc-level framework fix. The observations looked like cross-app evidence of a "silent submit" framework bug; they were actually all the same substrate artifact.

Implication: future subagent exploration substrates need to be stateful at the level of in-page DOM for interactive-element probing. Stateless-by-design is cleaner for isolation but destroys form-state tests. Cycle 229's form_submit action is the minimal fix; a broader substrate redesign for "multi-step interaction in one subprocess" would be worth a dedicated brainstorming cycle.

5. The DSL has unresolved gaps about persona ↔ entity binding

Cycle 233's investigation of EX-041 surfaced that fieldtest_hub's existing scope: reported_by_id = current_user for: tester only works because its demo seed populates Tester rows with IDs that match auth user IDs by convention. There's no framework-level concept binding a persona (an auth-layer role) to a backing domain entity. This affects:

  • Any DSL that has a domain entity corresponding to an auth persona (Teacher/teacher, Agent/agent, Tester/tester, etc.)
  • Auto-injection for create forms where the current user "is" the Tester/Teacher/Agent
  • Scope rules that reference the current user against entity FKs
  • Real deployments where domain entities are created independently of auth users

This is a DSL schema evolution question worth explicit discussion before implementation — three fix directions (explicit backed_by, convention-based, or explicit scope-rule function) are documented in EX-045.

Meta-observations about the loop itself

Strategy diversity matters

The 16-cycle arc exercised 5 different strategy types. The one with the highest per-cycle value was finding_investigation: it closed the most rows, surfaced the most framework gaps, and caught the most "not what you thought" moments. The framework_gap_analysis cycles had the opposite ROI — they were high-latency (one gap doc ≈ 10-15 min, but downstream cycles had to disconfirm or confirm the hypothesis). Synthesis is useful but cheap; investigation is useful and expensive. The right ratio is roughly 1 synthesis cycle per 3-5 investigation cycles, which is what this arc landed on (3 synthesis : 8 investigation).

Row-closure momentum builds

The arc had a very uneven closure rate per cycle:

Cycle Rows closed that cycle
220 1 (UX-004)
221-223 0 (pure exploration)
224 0 (synthesis)
225 1 (EX-035)
226 1 (EX-028)
227 1 (EX-042)
228 1 (EX-040)
229 1 (EX-039) + invalidated 2 more
230 0 (synthesis)
231 5 (verification sweep)
232 1 (EX-009 date-half)
233 0 (EX-041 blocked)
234 3 (EX-011/030/037 false positives)
235 0 (synthesis)

The biggest closure burst (5 rows in cycle 231) came right after the biggest synthesis pass (cycle 230). Synthesis compounds into closure — a good cycle 230 enabled the entire cycle 231 sweep. Pure bursty closure cycles like 231 are impossible without the prior synthesis work identifying which rows share hypotheses.

The loop needs judgment, not rotation

The pre-cycle-224 policy had a strict odd/even rotation between missing_contracts and edge_cases. The relaxed policy (cycle 224 onwards) replaced that with judgment-driven strategy selection, and the arc's value materially increased. Examples:

  • Cycle 220 chose housekeeping instead of rotation
  • Cycle 229 pivoted mid-cycle from "build framework fix" to "fix the substrate"
  • Cycle 231 invented a new cycle type (verification_sweep) to capitalise on cycle 230's synthesis
  • Cycles 225-228 ran as a 4-cycle finding_investigation streak because each one produced a concrete framework fix

None of these would have fit the pre-224 rotation. The relaxation was the single biggest productivity unlock in the arc.

What remains open

Framework-level priorities (by estimated impact)

  1. EX-044 widget-selection for ref fields — structural template work, ~45-60 min. Affects every ref field on every create form in every app. Highest blast radius.
  2. EX-045 persona-entity binding — DSL schema evolution, requires design discussion first. Unblocks EX-041 and silently broken scope rules in apps like fieldtest_hub.
  3. EX-046 per-persona empty copy — small DSL grammar extension, ~20 min. Low stakes but frequently visible.
  4. Gap doc #3 workspace-region-naming-drift — still fully valid, 3 EX rows + 3 PROP rows contributing. Needs a dedicated cycle with a workspace_region_identity helper design first.
  5. Gap doc #2 axis 4 (create-form field visibility) — overlaps with EX-044; best addressed after the widget-selection work.

Routine backlog residual

~20 OPEN rows that didn't get cycle attention this arc. Most are polish issues (dead # anchors, raw entity name leaks, missing bulk-count placeholders, detail-view None formatter) that are app-level or narrow framework fixes. Worth a few more verification_sweep / focused investigation cycles when the user's priorities shift back toward closure.

Recommendation for the next arc

  1. Triage discussion on EX-045 (persona-entity binding). This is the biggest unresolved DSL question and has latent impact on every app. Worth a short brainstorming pass before any implementation cycle.
  2. Dedicate a cycle to EX-044 (widget-selection ref structural fix). Highest-ROI pure-framework fix remaining.
  3. Release to frontier users only after EX-044 + EX-045 direction is chosen. The remaining backlog rows are narrow polish issues that real users will surface faster than the loop can. The two structural gaps (EX-044, EX-045) are the last foundation work that benefits from controlled local probing.
  4. Retain the relaxed skill policy and the 4 durable heuristics encoded in .claude/commands/ux-cycle.md. They're working.

Artifacts produced this arc

  • 15+ commits landing 7 framework-code fixes + 3 regression-test files (~25 new tests)
  • 5 gap docs in dev_docs/framework-gaps/ (including this retrospective + the 4 synthesis docs)
  • 1 skill evolution (.claude/commands/ux-cycle.md) with 4 durable heuristics + 2 new strategies (framework_gap_analysis, finding_investigation)
  • 1 substrate improvement (form_submit helper action in playwright_helper.py)
  • 16 cycle log entries in dev_docs/ux-log.md with full reasoning traces
  • 21 backlog row state transitions tracked in dev_docs/ux-backlog.md

Everything is committed, pushed, and the worktree is clean.