# Phase 1 Authoritative Writer Inventory

Last reviewed against `origin/dev` at `f388b8a6acc46f39be9a75b1c7cfb20fbc1503cd`.

## Engine and schedule writers

| Writer | Phase 1 disposition |
|---|---|
| `kafka_consumer/tt_response.py::schedule` | Parse/validate before one atomic apply; deterministic locks, applied-response receipt, final replacement/tombstones, post-commit delivery, manual offset commit. |
| `kafka_consumer/tt_response.py::swap` | Uses the same receipt, lock, transaction, final-state tracker, and post-commit delivery rules. |
| `kafka_consumer/schedule_response.py` | Legacy entry point delegates to `tt_response.consume_forever`; no model writer remains. |
| `kafka_consumer/tt_response-backup.py` | Backup entry point delegates to the same consumer; no model writer remains. |
| `api/views/admin/simulate_schedule_response.py` | Routed test endpoint adapts input into the production atomic `schedule()` path. |
| `api/views/admin/schedule_request.py::manual_constraint_break` | Runs within the admin request transaction, tracks the whole affected variant family, rethrows processing failure, and defers external effects. Pre-schedule itself emits no allocation event. |
| `api/management/commands/20260705-manual-schedule-activity.py` | Expired direct writer disabled fail-closed. |
| `api/management/commands/import-manual-schedule-activity.py` | Expired direct writer disabled fail-closed. |
| `api/management/commands/20260629-schedule_for_import_data.py` | Produces an ordinary engine request only; final mutation returns through `tt_response`. |

## Admin and import writers

`AdminApiBase` establishes a request-scoped mutation change set inside `ATOMIC_REQUESTS`, captures before state using lifecycle/m2m signals, emits one final event per changed aggregate before commit, marks every 4xx/5xx mutation transaction for rollback, and defers Redis/WebSocket/Kafka effects. Explicit tracking covers queryset/bulk operations that do not emit Django model signals.

- Staff: create, update/queryset update, archive/status, delete, and bulk import.
- Location: create, update/queryset update, archive/status, delete, and bulk import.
- Allocation/activity: normal and bulk engine result, final drag/drop, manual constraint break, booking schedule, booking swap, engine swap, unschedule, current-resource replacement, requirement-driven replacement, duration/week/pattern edits, activity/booking delete, variant create/merge/delete, JTA create/split, activity/booking import, and department repair command.
- Cascades: activity-template, module, and academic-term collectors snapshot and tombstone affected activities through `pre_delete`; Staff/Location deletion also emits final activity replacements after relation removal; week-pattern deletion snapshots affected activities and emits the final null/custom pattern state.

## Guardrails

`api/tests/test_integration_writer_guard.py` prevents the legacy, backup, simulated, expired-command, and pre-schedule bypasses from returning. Static search found no direct SQL `INSERT`, `UPDATE`, or `DELETE` against `tt_activity`, `tt_staff`, or `tt_location`.

Any new authoritative queryset/bulk writer must call the shared tracker/change-set service in its active transaction. Any new ordinary `.save()`, m2m, or delete path under `AdminApiBase` is captured automatically, but reviewers must still verify resource-map parity and post-commit side effects.
