fix(spec-builder): close delete, review, and i18n gaps - #5111
Conversation
Design Review (Fable 5) — ✅ PASSDesign-level review of The backend confirms the design contract: Design-Verdict: PASS Delete wires an existing identity-pinned endpoint correctly, the composer lift fixes the doubled-render root cause, and every claimed behavior has backing code. [DESIGN-REVIEWED] 8f4736a |
UX Review (Fable 5) — 🟡 CONCERNSUX-level review of UX-Verdict: CONCERNS The new remove-spec confirm quotes the raw spec name, not the display label the user sees everywhere else — at a destructive decision point. Watch
Suggestions
[UX-REVIEWED] 8f4736a |
GPT 5.6 Review — ✅ no blocking findingsGPT 5.6 completed its review of This comment is updated in place on each push. Review detailsNo findings. False positive or not applicable? A repository writer can comment: |
First Principles Review (Fable 5) — 🟡 CONCERNSPremise-level review of All checks are done. The delete UI wires a pre-existing zero-consumer First-Principles-Verdict: CONCERNS A What this change shipsIntent: let a spec be removed, reviewed, and read in any language without dead ends — mostly a FIX, carrying declared additions.
Watch
[FIRST-PRINCIPLES-REVIEWED] 8f4736a |
Opus 4.8 Review — ✅ no blocking findingsReviewed Review detailsNo findings. FINDING — website/src/apps/spec-builder/components/NewSpecView.tsx:93 — the preview [OPUS-REVIEWED] 8f4736a Verdict parsed from the review's SHA-scoped output markers for commit False positive or not applicable? A repository writer can comment: |
983b9e5 to
e867354
Compare
e867354 to
e563fe6
Compare
bolichen97
left a comment
There was a problem hiding this comment.
Approving per triage sweep: readiness passed, no blocking reviews, fix-type change. Auto-merge will be enabled; branch protection still gates.
bolichen97
left a comment
There was a problem hiding this comment.
Re-approved after conflict resolution against the latest main; focused validation passed.
|
🤖 Kiro Crew [operator: NicholasRBowers#a942f9ca] Review-ready ✅ — head
History this drive: rebased 926 commits onto main (bundle-size breach resolved by the rebase), fixed GPT's [BLOCK-MERGE] on delete-control clipping at 320px (static confirm label + Drive-to-green never merges — handing off to a human for final review/merge. |
Let a spec leave the builder without wiping project markdown, keep phase actions on the review overlay, and finish leftover English plus the overlay focus/double-pane bugs that made review feel stuck. A confirm click now removes the spec that was open, not a namesake that landed while the dialog sat up. Drive-to-green amendments (original work by Kyle Seaman): use the static "Remove this spec" label on the delete confirm button instead of interpolating the spec name, which clipped the dialog's controls at narrow viewports for long unbroken names; the name stays in the wrapping dialog body (now break-words). Drop the dead remove_spec key from all locales and the context file. Rebase onto main (2026-09-03): reconciled DocView.tsx with the #7891 last-paragraph selection fix — kept main's hoisted onSelectionSettled using containedSelectionRange plus this PR's exported Selection and lifted DocComposer; pointed main's two new #7891 tests at the Harness that supplies the now-required composer prop. Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Kiro Crew <noreply@kirodotdev.github.io>
a59eef4 to
8f4736a
Compare
|
🤖 Kiro Crew [operator: NicholasRBowers#a942f9ca] Conflict-resolution round — The PR went
Gates on the resolved tree: |
|
🤖 Kiro Crew [operator: NicholasRBowers#a942f9ca]
The observation is accurate: the collision retry (added for the "already exists" fallback) can create a suffixed name that differs from the previewed one. We are keeping the copy as-is because:
If maintainers prefer hedged phrasing, it is a clean one-string follow-up alongside the UX polish already tracked in #7662. |
|
🤖 Kiro Crew [operator: NicholasRBowers#a942f9ca] Review-ready again ✅ — head
Drive-to-green never merges — over to a human for final review/merge. |
Open PR relationship auditThis is a consolidated, point-in-time code-level audit note. It compares complete merge-base diffs and current/merged code; it does not treat a shared topic as duplication or partial coverage as completion. Relationship findings
No PR, Issue, label, branch, or review state was changed by the relationship-note portion of this audit. |
bolichen97
left a comment
There was a problem hiding this comment.
Re-approving after the conflict-resolution rebase. The twice-approved content is intact: removal is confirm-gated and calls the pre-existing specApi.remove, which leaves the project's markdown on disk; the fullscreen review overlay carries Approve/Start building/Pause and only one phaseActions() instance is in the tree; the #7891 last-paragraph selection fix is untouched (no duplicated or dropped hunk in DocView.tsx). All 12 new keys land in 13 catalogs. Two Low notes for a follow-up: 9 locales now use a second term for "spec" beside the existing one, and the overlay test asserts Approve -> Design without within(dialog) so it would pass on old code too.
Two UX gaps deferred out of PR #5111 by its UX Review lane: 1. A failed spec delete wrote its raw error to the page-top banner, which sits behind the confirm dialog's dimmed backdrop while focus is trapped inside the dialog — the user only saw the button revert from its busy state, inviting blind retries. The failure now renders inside the dialog through ErrorNotice: a translated what-happened + try-again lead plus the reason detail. No agent hand-off on this notice: the chat navigation unmounts the whole view, and SpecDetail can be holding stacked unsent review comments and an in-progress DocView draft — the hand-off would silently discard both. The mutation state resets when the dialog opens, so a dismissed failure does not greet the next attempt. 2. The rail's "no specs match that filter" empty state offered no recovery affordance. It now carries a one-click Clear-filter action (Issue Radar's HiddenByFilter convention) that empties the input and restores the full list. Both strings ship as catalog keys in all 13 locales; clear_filter reuses each locale's established components.ui.clear_filter wording. Tests: red-before-green proven — the four new/updated Vitest cases (in-dialog error + no banner call, fresh-dialog reset, empty-state action offered, click clears and restores) fail against the pre-fix components and pass after. Screenshots under temp-screenshots/spec-builder-7662/ are captured by the asserted-state harness (capture/spec-builder-7662.tsx + scripts/capture-spec-builder-7662.mjs), gateway-free. Closes #7662 Co-authored-by: Kiro Crew <noreply@kirodotdev.github.io>
Two UX gaps deferred out of PR #5111 by its UX Review lane: 1. A failed spec delete wrote its raw error to the page-top banner, which sits behind the confirm dialog's dimmed backdrop while focus is trapped inside the dialog — the user only saw the button revert from its busy state, inviting blind retries. The failure now renders inside the dialog through ErrorNotice: a translated what-happened + try-again lead plus the reason detail. No agent hand-off on this notice: the chat navigation unmounts the whole view, and SpecDetail can be holding stacked unsent review comments and an in-progress DocView draft — the hand-off would silently discard both. The mutation state resets when the dialog opens, so a dismissed failure does not greet the next attempt. 2. The rail's "no specs match that filter" empty state offered no recovery affordance. It now carries a one-click Clear-filter action (Issue Radar's HiddenByFilter convention) that empties the input and restores the full list. Both strings ship as catalog keys in all 13 locales; clear_filter reuses each locale's established components.ui.clear_filter wording. Tests: red-before-green proven — the four new/updated Vitest cases (in-dialog error + no banner call, fresh-dialog reset, empty-state action offered, click clears and restores) fail against the pre-fix components and pass after. Screenshots under temp-screenshots/spec-builder-7662/ are captured by the asserted-state harness (capture/spec-builder-7662.tsx + scripts/capture-spec-builder-7662.mjs), gateway-free. Closes #7662 Co-authored-by: Kiro Crew <noreply@kirodotdev.github.io>
Two UX gaps deferred out of PR #5111 by its UX Review lane: 1. A failed spec delete wrote its raw error to the page-top banner, which sits behind the confirm dialog's dimmed backdrop while focus is trapped inside the dialog — the user only saw the button revert from its busy state, inviting blind retries. The failure now renders inside the dialog through ErrorNotice: a translated what-happened + try-again lead plus the reason detail. No agent hand-off on this notice: the chat navigation unmounts the whole view, and SpecDetail can be holding stacked unsent review comments and an in-progress DocView draft — the hand-off would silently discard both. The mutation state resets when the dialog opens, so a dismissed failure does not greet the next attempt. 2. The rail's "no specs match that filter" empty state offered no recovery affordance. It now carries a one-click Clear-filter action (Issue Radar's HiddenByFilter convention) that empties the input and restores the full list. Both strings ship as catalog keys in all 13 locales; clear_filter reuses each locale's established components.ui.clear_filter wording. Tests: red-before-green proven — the four new/updated Vitest cases (in-dialog error + no banner call, fresh-dialog reset, empty-state action offered, click clears and restores) fail against the pre-fix components and pass after. Screenshots under temp-screenshots/spec-builder-7662/ are captured by the asserted-state harness (capture/spec-builder-7662.tsx + scripts/capture-spec-builder-7662.mjs), gateway-free. Closes #7662 Co-authored-by: Kiro Crew <noreply@kirodotdev.github.io>
Two UX gaps deferred out of PR #5111 by its UX Review lane: 1. A failed spec delete wrote its raw error to the page-top banner, which sits behind the confirm dialog's dimmed backdrop while focus is trapped inside the dialog — the user only saw the button revert from its busy state, inviting blind retries. The failure now renders inside the dialog through ErrorNotice: a translated what-happened + try-again lead plus the reason detail. No agent hand-off on this notice: the chat navigation unmounts the whole view, and SpecDetail can be holding stacked unsent review comments and an in-progress DocView draft — the hand-off would silently discard both. The mutation state resets when the dialog opens, so a dismissed failure does not greet the next attempt. 2. The rail's "no specs match that filter" empty state offered no recovery affordance. It now carries a one-click Clear-filter action (Issue Radar's HiddenByFilter convention) that empties the input and restores the full list. Both strings ship as catalog keys in all 13 locales; clear_filter reuses each locale's established components.ui.clear_filter wording. Tests: red-before-green proven — the four new/updated Vitest cases (in-dialog error + no banner call, fresh-dialog reset, empty-state action offered, click clears and restores) fail against the pre-fix components and pass after. Screenshots under temp-screenshots/spec-builder-7662/ are captured by the asserted-state harness (capture/spec-builder-7662.tsx + scripts/capture-spec-builder-7662.mjs), gateway-free. Closes #7662 Co-authored-by: Kiro Crew <noreply@kirodotdev.github.io>
Summary
ACTIVE, mashed-together decision names, overlay title), show the derived spec name and empty-filter state, and drop lucidesize={N}.size={N}→lucide-inlineon the four icons in edited lines.Why no screenshot: Shared Btn/Modal chrome and catalog copy; no new layout, theme, or component surface beyond the existing Spec Builder header and confirm dialog.
Test plan
.mdfiles stay on disk.ACTIVEgroup, decision option names, and overlay title.cd website && npx vitest run src/test/SpecBuilder src/i18n/style/koStyle.test.ts src/i18n/deadKeys.test.ts --reporter=dotcd website && npm run i18n:checkPattern harvest
Rule candidate: Never interpolate user-controlled names into fixed-width UI controls (buttons, dialog footers) — restate the name in wrapping body text and keep the control label static, so an unbroken long name cannot clip the dialog's actions at narrow viewports.