FEAT-IDEN-007 — Teacher Account Destruction
Contract
Terminal destruction of a teacher principal. The command destroys the users
row together with everything that principal owns: every class universe it holds
(ClassEconomy and all class-scoped records), the teacher-scoped settings,
activity, audit, rent, insurance, issue, store, and recovery/credential rows,
and any student seats left orphaned by those class teardowns.
Blast radius: HIGH. The operation is irreversible and removes otherwise
immutable economic history, which is lawful only under the terminal-destruction
lifecycle exception (INV-CORE-000 §III.5). The class-scope teardown sets
cth.class_universe_destroying for exactly that reason.
Manual destruction requires a canonical context and explicit correlation_id /
idempotency_key metadata. The principal destroyed is canonical_context.user_id
and nothing else. The scheduled lifecycle entry derives a principal-only target
from the locked retention-policy check below; it does not fabricate a logged-in
teacher session.
Authority resolution
Deletion authority comes from the canonical context alone (INV-CORE-000 §III.4). No display name, username, join code, public identifier, or any other form-supplied value participates in resolving the destruction target. Display values reaching this surface exist only to render the human-readable confirmation phrase; they never select, switch, or authorize a target.
Composition
One FEAT executes per request (INV-ARC-000 §VIII.2, INV-ARC-021 §V.2). This FEAT therefore composes domain commands, never other FEATs:
- per-class teardown calls the plain
_destroy_class_scope_rowscommand, not theFEAT-CLASS-006envelope_hard_delete_class_scope; - account-level teardown calls the
_delete_teacher_*commands anddelete_admin_account_rowsdirectly.
A single envelope covers the whole sequence, which is what makes account destruction atomic: a failure anywhere — including inside a class teardown — rolls back the entire account deletion rather than leaving a half-destroyed principal.
FEAT-CLASS-006 is the entry point for destroying one class while the
owning account survives. The two entry points are not interchangeable; a caller
already holding a context must use the domain command.
This designation named FEAT-CLASS-001 until 2026-09-17. That was wrong:
FEAT-CLASS-001 is class-boundary creation, its §III forbids executing
within a CanonicalContext, and its §X guarantees only that a boundary is
established. Destruction now has its own contract, FEAT-CLASS-006.
POST /admin/join-code/delete therefore dispatches between them. A class
teardown destroys that class’s seats, including the teacher’s administrative
one, and a principal holding no seat anywhere cannot exist — DOM-IDEN-005 §V.6
and §VI, which grant teachers no exception. So when the target class holds the
acting principal’s last seat, the request is not single-class destruction at
all: the route executes this FEAT instead, and the surviving-account
assurance on the confirmation surface must not be shown.
Boundary
Routes own the destruction gate (30-second countdown, exact typed phrase,
10-second press-and-hold) and the confirmation presentation. They must not
delete identity or class rows inline. Post-destruction session teardown and the
clearing of canonical pointers (User.last_active_class_id /
last_active_seat_id, INV-ARC-012 §V) are route concerns for the surviving
actor; a destroyed principal has no pointers left to clear.
Authority: INV-CORE-000 §III.4, §III.5; INV-ARC-012 §V; INV-ARC-021 §V.2; DOM-IDEN-001.
Automatic and roster-terminal entry points (amended 2026-09-17)
Roster deletion that removes a principal’s final student Seat in its final class
destroys the principal, so it is this FEAT, exactly as
POST /admin/join-code/delete is (see §Composition). The roster route dispatches
to it before any FEAT opens, and it composes the same plain account-destruction
domain command — never a nested FEAT. Roster deletion that empties a non-final
class is FEAT-CLASS-006; roster deletion that leaves the class standing is
FEAT-IDEN-006. The scheduled retention entry composes the same plain command
under this FEAT.
Because the dispatching preview holds no lock, the executor re-derives the deletion plan under the teacher and class locks and fails closed if the terminal scope has moved, so a narrower FEAT cannot destroy a principal (DOM-CLASS-001 §Terminal Roster Deletion).
Manual routes retain their confirmation gate. Final-student deletion must warn about class destruction and, when applicable, teacher-account destruction; it must require the corresponding stronger confirmation before executing.
Amended 2026-09-17. This section previously read “composed by the final-student
roster deletion FEAT”, which designated FEAT-IDEN-006 — “Provision Student Seat
in Existing Class”, blast radius MED — as the executing FEAT for principal
destruction. feat_code on audit rows and every FEAT-ENTRY record take their
value from the active FEAT, so the destruction was attributed to a provisioning
command. Nesting remains forbidden and atomicity is unchanged: the three roster
outcomes are mutually exclusive, so selecting the FEAT before it opens still
gives one envelope per request.
The scheduled entry locks/reloads the teacher User and requires either 180 days since the last successful sign-in or 30 days since creation if never signed in. Its authority derives directly from INV-CORE-000 §III.5 / DOM-IDEN-003, so it does not require a browser confirmation or sysadmin approval. Recheck after acquiring the same lock used by successful sign-in. One atomic account transaction performs all owned-class teardown, orphan handling, and principal destruction.
Last updated: 2026-09-17