diff --git a/docs/plans/2026-06-02-001-refactor-ssr-rendering-modernization-plan.md b/docs/plans/2026-06-02-001-refactor-ssr-rendering-modernization-plan.md
index 400b289e..2e0648a5 100644
--- a/docs/plans/2026-06-02-001-refactor-ssr-rendering-modernization-plan.md
+++ b/docs/plans/2026-06-02-001-refactor-ssr-rendering-modernization-plan.md
@@ -187,6 +187,38 @@ state:
(assoc attrs :key (str id "--" current-value))
```
+**Selector strategy for targeted swaps (a consideration, not a mandate).**
+Rules 2 and 4 above need a stable `hx-target`/`hx-select`. The obvious approach
+— a unique `id` on every swappable element — gets noisy in repeated structures
+(e.g. a table of financial accounts where choosing an account must swap *that
+row's* dropdown). When you reach those advanced cases, consider a more
+consistent scheme instead of hand-minting ids everywhere:
+
+- **Semantic markup + data-attributes** to craft a fine-grained selector without
+ per-element ids. For example, mark rows/cells with their identity and target
+ by attribute:
+ ```html
+
+
+
+
+
…
+
+ ```
+- **A `form-path -> id` (or `-> selector`) function**, derived the same way a
+ cursor path is, so the server and the markup agree on the target by
+ construction rather than by convention. A render fn at form-path
+ `[:accounts 0 :location]` would compute its own stable selector (id or
+ data-attribute query) from that path, mirroring §3.2's top-rooted cursor.
+
+The aim is *consistency and predictability* of swap targets in repeated/nested
+structures — pick whichever keeps targets unambiguous and easy to generate. Note
+this in `reference/swap-doctrine.md` and let the first modal that hits nested
+repeated swaps (Phase 5 / the wizards) settle on a convention for the cookbook.
+
### 3.2 Render functions: explicit data, or a top-rooted cursor
One function, data in, markup out. The data can arrive as a plain map or via a
@@ -367,7 +399,8 @@ convention, e.g. `.claude/skills/testing-conventions/SKILL.md`).
.claude/skills/ssr-form-migration/
SKILL.md # the playbook (§8): classify → migrate → verify → record
reference/
- swap-doctrine.md # §3.1 rules, focus invariant, OOB-vs-hoist, Alpine hardening
+ swap-doctrine.md # §3.1 rules, focus invariant, OOB-vs-hoist, Alpine hardening,
+ # target-selector strategy (semantic/data-attr/form-path->id)
render-functions.md # §3.2 explicit-data or top-rooted cursor; no faked positions
form-vs-wizard.md # §3.3 classification + the data-driven engine
selmer-conventions.md # §3.4 attr style, interop bridge, include/block patterns
@@ -585,6 +618,10 @@ apply it cold." Single-step form currently wearing a wizard costume.
cookbook entries from Phase 2.
- [ ] Add-row: a `POST` that appends a fresh row; totals re-render via the
sibling-`` swap, **not** OOB.
+- [ ] **Settle a target-selector convention** for repeated/nested rows (§3.1
+ "Selector strategy"): semantic data-attributes and/or a `form-path -> selector`
+ helper, rather than hand-minted ids per element. Record the chosen convention
+ in `reference/swap-doctrine.md` + `component-cookbook.md` so later wizards reuse it.
- [ ] Collapse 4 wizard routes → 3 (open, submit, add-row).
- [ ] Verify add/remove rows + totals + apply (assert DB) + full suite green.
- [ ] Feed the skill; append scorecard row.