ADR 0019: V1 State Deletion and Export Semantics
ADR 0019: V1 State Deletion and Export Semantics
Status: Accepted for architectural direction.
Date: 2026-05-11.
Context
Version 1 state access uses anonymous bearer tokens.
The backend stores sensitive academic planning state without accounts.
The backend exposes an export endpoint so token holders can preserve their own data.
The backend exposes a delete endpoint so token holders can remove stored state.
Earlier drafts left deletion behavior ambiguous.
That ambiguity would force the implementation to choose a privacy policy during coding.
HTTP GET requests are defined as safe when their requested semantics are essentially read-only: RFC 9110, section 9.2.1.
The export endpoint is specified as GET /api/v1/state/current/export.
Therefore export must not request a state mutation.
Decision
Version 1 state export is read-only.
GET /api/v1/state/current/export must:
- authenticate the bearer token;
- read the current active state;
- construct portable export JSON;
- return the export with
Cache-Control: no-store; - avoid writing export timestamps, export audit events, or equivalent state-event rows.
Export observability may use ordinary server logs or metrics when they do not contain raw tokens, token verifiers, full state payloads, grades, notes, or course histories.
If product requirements later need persistent export audit records, they must use an explicit mutating endpoint rather than changing GET semantics.
Version 1 state deletion is hard deletion.
DELETE /api/v1/state/current must:
- authenticate the bearer token;
- require explicit confirmation;
- remove or revoke token verifier records for the state;
- delete the state payload;
- delete associated migration preview rows when practical;
- leave no retained course history, grades, planned courses, credential targets, assumptions, notes, or UI preferences.
The backend may write a minimal deletion event or tombstone only if it contains no academic state content.
Permitted minimal deletion metadata:
state_id;- deletion timestamp;
- deletion mode
hard_delete; - state schema version;
- catalog version id.
The backend must not retain deleted state_json.
After deletion, later use of the same token must be indistinguishable from ordinary invalid-token use.
Invalid token, revoked token, deleted state, and unknown token all return 401 unauthorized for ordinary clients.
Consequences
V1 deletion behavior is privacy-forward and implementation-ready.
Users can export their state without changing server state.
GET export remains aligned with HTTP method semantics.
Deletion removes the data users are most likely to consider sensitive.
Aggregate debugging after deletion is limited to minimal non-content metadata.
The project can add retention, audit, or account recovery features later only with a new explicit decision.
Alternatives Considered
Alternative 1: Tombstone Delete by Default
The backend could keep a deleted state row with erased or minimal payload.
This can simplify diagnostics.
However, it leaves too much policy discretion in implementation and increases privacy risk if the erased payload boundary is not enforced perfectly.
This alternative is rejected for version 1.
Alternative 2: Export Writes a Persistent Audit Timestamp
The backend could persist a timestamp whenever a user exports state.
This is operationally convenient.
However, the endpoint is a GET and the user asked for a portable export, not an audit mutation.
This alternative is rejected for version 1.
Alternative 3: Keep Deleted Token Lookup Records
The backend could retain token verifier records to detect reuse of deleted tokens.
That can help security analysis.
However, retaining verifier records is unnecessary for v1 user value and complicates the invalid-token indistinguishability rule.
This alternative is rejected for version 1.
Follow-Up
If account recovery, abuse investigation, or legal retention requirements appear later, write a new ADR before changing v1 deletion guarantees.
If export auditing becomes a product requirement, specify a separate mutating endpoint and its retention policy.