You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
"title": "ui: toggle race during in-flight target-policy fetch on Links preview",
12
+
"description": "REWRITTEN 2026-05-02 with state-machine framing per ADR-020/ADR-021 planning session. Updated 2026-05-08 to encode prior-attempt failure mode (see review_block rationale).\n\nOriginal symptom (still valid): rapidly clicking the inline target-data toggle on the same row twice leaves the row expanded when the user expected it to collapse, because toggleLinkPreview marks expanded state ONLY after await ensureTargetPolicy resolves. Optimistic-expand fixes from earlier attempts collided with hx-92456dd2's failed-fetch sentinel cache pattern, regressing the retry-on-subsequent-toggle behavior (was tracked separately as axon-567eea01, now absorbed into THIS bead).\n\nSolution: replace ad-hoc booleans with an explicit state machine per row.\n\nStates: idle | loading | ready | failed\nTransitions:\n idle → loading on first toggle\n loading → ready on fetch success\n loading → failed on fetch error\n ready → idle on subsequent toggle (collapse)\n failed → loading on subsequent toggle (retry)\n loading → idle if user clicks again while in flight (cancel/collapse intent)\n\nJsonTree refuses to render against any state but ready. The loading state shows a spinner or skeleton, never raw JSON. The failed state shows an error chip.\n\nFiles: ui/src/routes/tenants/[tenant]/databases/[database]/collections/[name]/+page.svelte (toggleLinkPreview, expandedLinks state, JsonTree render branch). ui/tests/e2e/link-policy-retry.spec.ts (existing test suite). GraphQL operation name: AxonUiEffectivePolicy (defined in ui/src/lib/api.ts).\n\nThis bead absorbs axon-567eea01's acceptance criteria.\n\nPRIOR ATTEMPT FAILURE (result_rev cfb2cff8, blocked at review): The Playwright route handler in link-policy-retry.spec.ts stalled every AxonUiEffectivePolicy request, including the initial page-load fetch. The collection view never rendered and policy-enforcement.spec.ts failed. The intercept MUST be scoped to toggle-triggered requests only; page-load request(s) must resolve normally before faults are injected.",
13
+
"acceptance": "AC1. Rapid double-click on the toggle leaves the row collapsed (or in a visible loading state), not expanded with stale data. AC2. After a transient fetch failure, the next toggle retries the fetch (does not show stale [redacted] state). AC3. Both tests in ui/tests/e2e/link-policy-retry.spec.ts pass: 'retries policy fetch on subsequent toggle after transient failure' AND 'rapid double-click on link preview toggle leaves row collapsed while fetch is in flight'. AC4. policy-enforcement.spec.ts continues to pass unchanged. AC5. JsonTree never renders against an in-flight or failed cache entry. AC6. State machine has explicit type union (e.g. type LinkPreviewState = {status:'idle'} | {status:'loading'} | {status:'ready', cell:ImpactCell} | {status:'failed', error:Error}); no boolean+nullable combos. AC7. typecheck/lint clean. AC8. The Playwright route intercept in link-policy-retry.spec.ts targets only toggle-triggered AxonUiEffectivePolicy requests; the page-load policy fetch(es) must resolve normally so the collection view is fully rendered before toggle assertions begin. Implement with a request counter or staged route handler rather than a blanket stall on all matching requests.",
"body": "The UI toggle fix is present, but the new Playwright coverage is incorrect: it stalls every `AxonUiEffectivePolicy` GraphQL request, including the page-load policy fetch, so the collection view never loads and `policy-enforcement.spec.ts` cannot reliably pass.\nharness=codex\nmodel=gpt-5.4\ninput_bytes=85344\noutput_bytes=850\nelapsed_ms=92374",
76
+
"created_at": "2026-04-30T01:10:02.630906343Z",
77
+
"kind": "review",
78
+
"source": "ddx agent execute-loop",
79
+
"summary": "BLOCK"
80
+
},
81
+
{
82
+
"actor": "",
83
+
"body": "",
84
+
"created_at": "2026-04-30T01:10:02.805494379Z",
85
+
"kind": "reopen",
86
+
"source": "",
87
+
"summary": "review: BLOCK"
88
+
},
89
+
{
90
+
"actor": "erik",
91
+
"body": "post-merge review: BLOCK (flagged for human)\nThe UI toggle fix is present, but the new Playwright coverage is incorrect: it stalls every `AxonUiEffectivePolicy` GraphQL request, including the page-load policy fetch, so the collection view never loads and `policy-enforcement.spec.ts` cannot reliably pass.\nresult_rev=cfb2cff84b33ee457d4c55494f826ad89fa48237\nbase_rev=824eabceda2b32e64586d1ad4a50f967e83bc19e",
"body": "agent exited without a commit or no_changes_rationale.txt\nresult_rev=c01b98a13164f20beb1a0f868af6fbbfea6f2b5c\nbase_rev=c01b98a13164f20beb1a0f868af6fbbfea6f2b5c",
"body": "agent exited without a commit or no_changes_rationale.txt\nresult_rev=46769eb1881ef6fd2e4e668219ff9efdc303313e\nbase_rev=46769eb1881ef6fd2e4e668219ff9efdc303313e",
"body": "{\"rationale\":\"Bead has clear scope, well-defined state machine, and explicit file targets. The most recent prior attempt (review_block, result_rev cfb2cff8) reveals a concrete, durable failure mode: the Playwright route handler stalled every AxonUiEffectivePolicy request including the page-load fetch, so the collection view never rendered and policy-enforcement.spec.ts failed. This anti-pattern is unguarded in the current acceptance criteria. AC8 encodes the constraint so the next attempt cannot repeat the mistake. File-existence check confirms +page.server.ts does not exist (already hedged in description as 'if shared state needed'); all other paths and the GraphQL operation name are verified present. All preservation requirements carried through: ADR-020/ADR-021, hx-92456dd2, axon-567eea01, named test strings, file paths, AC1–AC7.\",\"changed_fields\":[\"description\",\"acceptance\"],\"before\":{\"description_bytes\":1561,\"acceptance_bytes\":833,\"description_sha256\":\"6816e52bd6d3968e6bc91133f2a2a25c9b3fc4165f18ab851d16ea68ca66f038\",\"acceptance_sha256\":\"42a1af5fe93d8a483136705df8f0362d0f863880511dfd37bc7ea52324a05887\"},\"after\":{\"description_bytes\":2008,\"acceptance_bytes\":1197,\"description_sha256\":\"d9bbbe2edc24b28d939b8b9ad2af77cb2472bdc6b81b14a98bf5c75d3fec30c7\",\"acceptance_sha256\":\"2122551eed2b41f5d6e805ba1f1ddfef3171044a44536e93062ebdfb7d745341\"},\"preservation_evidence\":[\"ADR-020\",\"ADR-021\"]}",
220
+
"created_at": "2026-05-08T07:26:52.458778386Z",
221
+
"kind": "intake-rewritten",
222
+
"source": "ddx agent execute-loop",
223
+
"summary": "description,acceptance"
224
+
},
225
+
{
226
+
"actor": "erik",
227
+
"body": "{\"rationale\":\"Well-formed bead with strong description and acceptance criteria. Title is specific and actionable. State-machine solution is clearly specified with explicit transitions. AC items are numbered, testable, and cover the prior-attempt failure mode (AC8). Deductions: (1) spec-id points to a source file rather than a spec/design document, weakening traceability to authoritative requirements (-5); (2) description mixes narrative history with normative spec — the prior-attempt failure block is useful but makes the normative state-machine spec harder to extract at a glance (-5); (3) no explicit 'effort' or 'priority' field, which limits queue scheduling (-4); (4) absorbed bead (axon-567eea01) is mentioned but not formally listed as a 'closes' or 'absorbs' reference field, so the link is prose-only and could be missed by tooling (-4).\",\"score\":82,\"suggested_fixes\":[\"Set spec-id to a spec or ADR document (e.g. docs/helix/... or ADR-020) rather than the implementation file; the implementation file belongs in the description.\",\"Add a structured 'absorbs' or 'closes' field listing axon-567eea01 so tooling can close it automatically rather than relying on prose mention.\",\"Add priority and/or effort fields to support queue ordering.\",\"Consider splitting description into 'Context/History' and 'Normative Spec' subsections so the state-machine definition is immediately extractable without reading failure narrative.\"],\"waivers_applied\":[]}",
0 commit comments