Archival on delete when in use: DELETE /evaluations/\{id\} now archives the evaluation if submissions or active sessions exist, instead of failing with a raw FK/23503. The handler returns a structured 409 with counts and archived=true.
Usage visibility: Added GET /api/v1/evaluations/\{id\}/usage, returning { submissions, activeSessions, archived } so clients know why delete is blocked and can guide users.
Session gating: Delivery session creation is blocked for archived evaluations.
Result snapshots: Submissions now store a frozen version_snapshot (sections/items/questions/payloads) at submit time. Submission responses include this snapshot so result rendering can use the frozen state rather than live authoring.
Results endpoint: Added /api/v1/submissions/\{id\} to fetch a submission with its stored version_snapshot and submission_items in one response, keeping result views decoupled from live authoring data.
Feedback config endpoint: Added PATCH /api/v1/evaluations/\{evalId\}/versions/\{versionId\}/feedback to set feedbackTagKeys per evaluation version. On submission, the current keys are copied into the snapshot and feedbackTags are derived from structured tags so historical submissions keep their config. Admin views see full tags; candidate views use the frozen feedbackTags.
Delivery script parity: backend/tests/delivery_session.sh cleanup accepts archive-on-delete semantics; script runs end-to-end without failing on submissions.