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:
- "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.
- "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_analysisandfinding_investigationmodes, and a 30→100 budget expansion. - "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¶
- v0.55.35 (cycle 220) —
#777ref eager-loading for list routes - Cycle 225 — DSL parser multi-line list support (
scenario.py:_parse_string_list) + 2 regression tests. Unblockeddefault_workspaceparsing for 3 apps. - Cycle 226 —
workspace_allowed_personashelper propagated to thews_nav_itemssecond builder atpage_routes.py:1115(retroactive completion of v0.55.34 #775's intent). - Cycle 227 — New
resolve_persona_workspace_routehelper +_root_redirectstructural cleanup + 11 regression tests. Fixed the fallback-to-workspaces[0] failure mode. - Cycle 228 — Bulk-action bar persona suppression at
page_routes.py:701, mirroring the existing Create-button pattern. - Cycle 229 — Substrate fix: new
form_submithelper action inplaywright_helper.pywith 250ms post-networkidle wait for HTMX swap. - Cycle 232 —
widget_hint = "picker"default for DATE/DATETIME fields intemplate_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_clickmulti-call pattern loses form state. FIXED in cycle 229 via newform_submitaction. - EX-044 — Widget-selection gap for
reffields. 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 (addempty:tofor <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_investigationstreak 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)¶
- 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.
- 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.
- EX-046 per-persona empty copy — small DSL grammar extension, ~20 min. Low stakes but frequently visible.
- 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_identityhelper design first. - 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¶
- 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.
- Dedicate a cycle to EX-044 (widget-selection ref structural fix). Highest-ROI pure-framework fix remaining.
- 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.
- 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_submithelper action inplaywright_helper.py) - 16 cycle log entries in
dev_docs/ux-log.mdwith full reasoning traces - 21 backlog row state transitions tracked in
dev_docs/ux-backlog.md
Everything is committed, pushed, and the worktree is clean.