The old matter field mixed two facts: whether a matter is adversarial and
which adversarial side the firm represents. That made
principal and opposing carry role labels that belong
on participants. Spike-2786 pinned the durable contract: the matter stores
only its posture, while a participant label carries the represented side.
| Value | Meaning |
|---|---|
adversarial | The matter has opposing sides. This field does not say which side the firm represents. |
advisory | There is no single adverse side, such as advisory, mediation, or in-house work. |
The Python enum, database CHECK constraint, server default, DTO descriptions, and OpenAPI schema all expose exactly these two values.
principal ─┐
├──> adversarial
opposing ─┘
advisory ────> advisory
There is no participant-label backfill. Spike-2786 confirmed that staging has no real clients, so the old directional distinction is disposable test data and both old values map straight through.
Migration 0202 drops the old CHECK, transforms rows, changes the default and
column comment, and installs the new CHECK. Existing RLS policies, grants,
indexes, and partial-index predicates stay unchanged; RLS is explicitly
reasserted. The downgrade maps adversarial to
principal, the valid old default, because the collapsed source
value cannot be reconstructed.
Contract tests pin the two enum members, ORM CHECK/default, legacy-row SQL, RLS statement, migration parent, and byte-identical column comment. The repository gate additionally runs the complete test suite, Ruff, changed- surface mypy, OpenAPI regeneration, Alembic upgrade/downgrade/upgrade, and the schema-drift check.
One sentence to remember: a matter now records only adversarial versus advisory posture, leaving the represented side to participant labels.