What
Two defects in openspec/specs/grid-layout/spec.md, both found while closing gate-16 (PR #100).
1. The "Placement key regeneration" scenario is stale and contradicts the code — deliberately
openspec/specs/grid-layout/spec.md:405-408:
#### Scenario: Placement key regeneration
- THEN the placement key MUST include the `updatedAt` timestamp and `styleConfig` hash
to force re-rendering via `getPlacementKey()`
Views.vue::placementItemKey() returns String(placement.id) and nothing else, on purpose. The comment in place records why: folding in updatedAt + a styleConfig dump made the key change on every persist, so Vue tore down and recreated the grid item's DOM node. Anything focused inside it lost focus, which breaks keyboard move/resize outright (WCAG 2.1 SC 2.1.1) — after one arrow-key move focus was thrown back to the document and a second move was impossible without re-navigating the whole grid.
Also note getPlacementKey(), the method the scenario names, no longer exists.
So the requirement as written mandates a WCAG 2.1.1 regression. The scenario needs correcting to describe the current contract (a key stable for the placement's lifetime; re-render comes from the store replacing placement objects wholesale, which updates the bound props).
⚠️ This is why placementItemKey is anchored to REQ-GRID-008 (Grid Accessibility) in PR #100 and not to this scenario. Anchoring it here would have claimed conformance to a requirement the code intentionally violates.
2. The scenario is filed under the wrong requirement
It sits inside REQ-GRID-010, whose title is "Grid Styling" ("The grid MUST apply consistent visual styling to all grid items"). A render-key contract is not styling. It should live under the grid-rendering or accessibility requirement.
3. Related — the spec's own status section is stale
spec.md:504 lists under Not yet implemented:
- REQ-GRID-008 (Grid Accessibility): No keyboard navigation, keyboard movement, or ARIA attributes.
Keyboard repositioning has since landed (openspec/changes/keyboard-accessible-widget-repositioning/), and the placementItemKey comment documents a keyboard-move regression that could only have been observed on a working implementation. The status list should be re-derived rather than trusted.
Why it matters beyond this file
An @e2e exclude or @spec anchor pointing at a stale scenario is scored as coverage, and a dangling or wrong anchor fails silently in this gate family. A scenario that mandates a WCAG regression is worse than an uncovered one: any future agent closing gate-19 honestly would either write a test that fails against correct code, or "fix" the code to match the spec and reintroduce the focus bug.
Not doing this in PR #100
PR #100 is scoped to gate-16 + gate-57 and deliberately edits no spec file. Editing grid-layout/spec.md would pull every scenario in it into gate-19's diff scope, which scopes by file — a separate, reviewable change.
What
Two defects in
openspec/specs/grid-layout/spec.md, both found while closing gate-16 (PR #100).1. The "Placement key regeneration" scenario is stale and contradicts the code — deliberately
openspec/specs/grid-layout/spec.md:405-408:Views.vue::placementItemKey()returnsString(placement.id)and nothing else, on purpose. The comment in place records why: folding inupdatedAt+ astyleConfigdump made the key change on every persist, so Vue tore down and recreated the grid item's DOM node. Anything focused inside it lost focus, which breaks keyboard move/resize outright (WCAG 2.1 SC 2.1.1) — after one arrow-key move focus was thrown back to the document and a second move was impossible without re-navigating the whole grid.Also note
getPlacementKey(), the method the scenario names, no longer exists.So the requirement as written mandates a WCAG 2.1.1 regression. The scenario needs correcting to describe the current contract (a key stable for the placement's lifetime; re-render comes from the store replacing placement objects wholesale, which updates the bound props).
placementItemKeyis anchored to REQ-GRID-008 (Grid Accessibility) in PR #100 and not to this scenario. Anchoring it here would have claimed conformance to a requirement the code intentionally violates.2. The scenario is filed under the wrong requirement
It sits inside REQ-GRID-010, whose title is "Grid Styling" ("The grid MUST apply consistent visual styling to all grid items"). A render-key contract is not styling. It should live under the grid-rendering or accessibility requirement.
3. Related — the spec's own status section is stale
spec.md:504lists under Not yet implemented:Keyboard repositioning has since landed (
openspec/changes/keyboard-accessible-widget-repositioning/), and theplacementItemKeycomment documents a keyboard-move regression that could only have been observed on a working implementation. The status list should be re-derived rather than trusted.Why it matters beyond this file
An
@e2e excludeor@specanchor pointing at a stale scenario is scored as coverage, and a dangling or wrong anchor fails silently in this gate family. A scenario that mandates a WCAG regression is worse than an uncovered one: any future agent closing gate-19 honestly would either write a test that fails against correct code, or "fix" the code to match the spec and reintroduce the focus bug.Not doing this in PR #100
PR #100 is scoped to gate-16 + gate-57 and deliberately edits no spec file. Editing
grid-layout/spec.mdwould pull every scenario in it into gate-19's diff scope, which scopes by file — a separate, reviewable change.