Three structural bugs from Phase 3d caught by m's "doesn't work" report:
1. The chip-add <form class="chip-add" ...> was rendered INSIDE the outer
<form id="bulk-actions" ...> in bulk_section.tmpl. HTML forbids
nested forms — browsers silently flatten them, so the chip-add's
hx-trigger="submit" never fired and pressing Enter in any chip-add
input dispatched the outer Apply form instead. Replaced the inner
<form> with a <span class="chip-add"> wrapping an input that fires
hx-post directly on Enter (hx-trigger="keyup[key=='Enter']") plus an
explicit + button. No more nested forms. New TestBulkPageHasNoNested
Forms regression-guards via a substring check on the rendered HTML.
2. handleBulkApply 400'd on empty ids OR empty action via http.Error,
which HTMX swapped into #bulk-section as a plain-text error page —
the page chrome vanished and the user saw "no action chosen". Now
the handler validates inputs, sets a banner string, and falls through
to renderBulkList (the section re-renders with the banner inline).
Banner copy is task-specific so m can tell what he missed.
3. renderBulkList read filter values with r.FormValue, which returns
ONLY the first value for multi-value names. Multi-select tag/mgmt/
status filters dropped their 2nd+ values on every Apply round-trip.
Switched to r.Form["..."] + a new normaliseFormStrings helper that
dedupes / lowercases / trims the slice. TestBulkApplyRendersWithFilter
Preserved regression-guards.
All 3 bugs caught by tests written first (TestBulkPageHasNoNestedForms,
TestBulkApplyEmpty{Action,Ids}RendersInlineBanner, TestBulkApplyRenders
WithFilterPreserved). Existing 4 bulk tests still green; full test suite
green.