Matter posture and the represented participant now agree
An adversarial matter cannot enter the backend without naming the participant label for the client-side us party, while an advisory matter cannot carry that adversarial label by mistake.
Why the request is checked as one unit
representingSide and the client-side participant label are individually valid fields, but their combination determines whether the request tells a coherent story. MatterCreateRequest therefore validates the relationship after all parties have been parsed.
representingSide
│
├── adversarial ── requires label id OR label name on role "us"
│
└── advisory ───── forbids a label on role "us"
Accepted and rejected combinations
| Posture | Client-side us label | Result |
|---|---|---|
adversarial | participantLabelId or participantLabelName | Accepted |
adversarial | Absent | 422: participant label is required |
advisory | Absent | Accepted |
advisory | Present | 422: participant label must not be set |
The existing two-value RepresentingSide enum remains unchanged, so legacy values such as principal and opposing are still rejected.
Acceptance evidence
| Negative paths | Focused DTO tests reject adversarial requests without a client label and advisory requests with one. |
|---|---|
| Happy paths | Tests accept adversarial labels supplied by either identifier or name, plus advisory requests with no client label. |
| Existing create coverage | Adversarial route, service, contract-fixture, and team fixtures now provide an explicit labeled us party. |
| Red-first proof | Both negative tests were observed failing before the model validator was added. |
Scope and staging sequence
This Story changes only the create request DTO, focused validation tests, and existing test fixtures. It adds no migration and no service or persistence behavior; persistence remains owned by Story-2792.
The client UI support is delivered by app Stories #2794 and #2795. Until those land, app-driven adversarial matter creation returns 422. This temporary staging sequence is accepted because there are no real clients.
Governing issue: pramaan-spec#2791.