fix: plugin-gate s.law + fresh flag-off migrate (0276 gate, 0269 dedup, 0277 merge node)
Post-merge master testing (2026-09-22), both plugin flags + FRESH-DB migrate:
1. vote-history s.law dereference (flag-off runtime bug): the row-dict body dereferenced s.law ungated (field declared inside the model plugin gate) -> AttributeError at request time on plugin-less instances. Fixed with law_on = flag AND field-in-Meta; payload keys always emitted (None off-flag).
2. BUG B confirmed live (fresh flag-off migrate): 0276's unconditional AlterField(targetLaw) + AddField(titleRelatedLaw) crashed fresh flag-off instances with FieldDoesNotExist: ActionGroup has no field named 'targetLaw' — targetLaw enters state only via 0224's conditional AddField, and titleRelatedLaw sits inside the model's plugin gate too. Both ops now gated 0272/0224-style with the standard print notice.
3. Fresh-migrate duplicate column: 0269_import_fields (!36 (merged)) AND 0274 (!39 (merged)) both AddField(placeHemicycle) -> duplicate column name: placeHemicycle once both leaves run on one fresh DB. Dropped from 0269 (0274 owns the column); already-applied instances unaffected (Django tracks applied migrations by name); state converges both ways.
4. 0277_post_master_merges merge node added: required — master has two leaves (0269_representative_import_fields from !36 (merged) + 0276 from !43 (merged)); without it migrate / makemigrations --check fail with Conflicting migrations detected. (Lyra's identical 0277 on Sep 14 was reverted before !43 (merged) landed; post-!44 it's unavoidable.)
Verified: fresh DB flag OFF (exit 0, gated schema: no targetLaw/titleRelatedLaw, placeHemicycle+birth* present), fresh DB flag ON (targetLaw+titleRelatedLaw+scrutin.law all present), existing dev DB (migrate --plan clean, check exit 0).