refactor(placement): matching GET stages an outbox event and reuses chi…

Summary

Matching GET stages an outbox event and reuses child_id as a case_id placeholder

Evidence

search_matching (a read-only GET) opens a tx solely to stage placement.requested, passing query.child_id for BOTH case_id and child_id, with the Publisher extension extracted then discarded. The downstream-pollution rationale is REFUTED: the only consumer (craig-rules placement.requested arm) keys off placement_id (which this payload omits), not case_id, so the subject resolves to None and the event is effectively dead weight.

Locations

  • services/craig-placement/src/api/matching.rs:96-108
  • services/craig-placement/src/events.rs:105-119

Why it matters

A GET that performs a DB write is surprising and couples decision-support search to event infra; the wrong-typed id is a forward-looking risk (a future case_id-keying consumer), not current harm. Low.

Drop the event from the read path (the placements create endpoint owns a real case_id and placement_id), or make case_id Option and omit it; remove the unused Publisher extension.

Acceptance criteria

  • Drop the event from the read path (the placements create endpoint owns a real case_id and placement_id), or make case_id Option and omit it
  • remove the unused Publisher extension
  • Regression test added that reproduces the defect (fails before, passes after) — unless purely doc/dep
  • Any docs/comments describing this surface updated to match (J5)

References

  • Source: 2026-06-28 automated code-quality audit — finding placement-matching-get-writes-event (severity low, dimension KISS)
  • Backlog reconciliation: not-tracked — related: #614 (closed) (closed), #256 (closed) (closed)