INV-CORE-000: Core Invariants of Classroom Token Hub
| Reference Number | Version | Effective Date | Supersedes | Authority Level |
|---|---|---|---|---|
| INV-CORE-000 | 2.2 | 2026-10-18 | 2.1 | Foundational |
Important
v2.2 (2026-10-18). §I no longer claims this document is the top-level authority from which all other authority derives. §II now states its precedence directly: within the INVARIANT family it outranks INV-ARC-* and INV-CORE-001. The title gains “of Classroom Token Hub”, and the document is reformatted for markdownlint. No invariant in §III changed.
I. Purpose
This document defines the core invariants, or underlying principles, that drives the design of this application. Any future development of this application must stay within the boundaries of these invariants.
For documentation writing standards, please see SOP-DOC-000 and SOP-DOC-001
II. Scope
The invariants in this document applies to:
- All services
- All routes
- All migrations
- All background jobs
- All domains, features, and visual elements
Within the INVARIANT family, this document has higher authority than those under INV-ARC-* and INV-CORE-001
III. Core Invariants
The following invariants shall be interpreted as hard boundaries that must be observed at all time. Invariants in this section are cumulative and non-negotiable. A valid implementation must satisfy all invariants simultaneously.
1. class_id Centric Isolation
Statement
All data access and mutation operations must be scoped to a single class_id. class_id defines the boundary in which actors operate. join_code is a human-facing alias for class_id and MUST resolve to class_id before any authority-sensitive operation. Within a class, seat_id anchors all actor-scoped state.
Constraints
- No actor may access a
class_idboundary they are not bound to. - No financial operation may be performed without explicit
class_idscope. - All domain services must accept
class_idas an explicit parameter. Services may acceptjoin_codefor convenience but must resolve it toclass_idbefore any authority-sensitive operation. - No global settings, attributes, logs, or ledgers are allowed within the application.
- Scoped data associated with a
class_idmust not survive its deletion unless explicitly re-scoped under a separateclass_idcontext.
Prohibited Action
-
Any operation that accesses or mutates data across
class_idboundaries not assigned to the actor explicitly. -
Any role or privilege that allows for cross-class action.
2. Minimal Use and Storage of PII
Statement
The system stores only the minimum personally identifiable information required for functional identity binding and in-app display. PII must never exist as plaintext at rest. Every stored PII field must be either HMAC-hashed (for lookup/matching) or symmetrically encrypted (for recoverable display), and the storage form must be the minimum sufficient for the field’s defined purpose.
Constraints
- No raw DOB storage of any kind.
- No contact method of any kind can be stored, processed, or requested.
- PII stored for display (e.g. first name, last name in
identity_profiles) must be encrypted at rest using the application’s symmetric encryption facility. Plaintext must never be written to disk or database. - PII stored for lookup or matching (e.g. name-matching hashes on
seatsfor roster claim) must be HMAC-hashed. The original value must not be recoverable from the stored form. - A single PII field may require both forms (hashed for lookup, encrypted for display) stored in separate columns. Both columns must be present where both purposes exist.
- PII fields must not appear in logs, request context, execution traces, error messages, URLs, or query parameters.
- PII must be deleted when the owning record is deleted. No PII may survive the deletion of its parent seat, user, or class.
Prohibited Action
- PII stored as plaintext at rest in any column, file, or cache.
- Retention of PII beyond the lifetime of its owning identity record.
- Storage of PII fields not required by an invariant-defined function (identity binding, display, or roster claim verification).
3. Deterministic and Traceable Financial Logic
Statement
All finance-related actions must be immutably logged and traceable. Financial outcomes must be deterministically reproducible from ledger state and configuration at time of execution.
Constraints
- Any edits of finance-related log entry must be visible to all actors within the class.
- Reversal action creates new counter-entry, not removal of previous action.
- Full financial history within the
class_idscope must be fully traceable. - Changes to financial configuration shall not retroactively alter prior ledger outcomes.
Prohibited Action
- Deletion or silent mutation of financial ledger entries.
4. Principal and Actor Authority
Statement
Authority is strictly scoped to defined principals and actors. The system distinguishes between the authentication principal (users.id), the operational actor (seats.id), and the isolation boundary (classes.class_id). No principal or actor may exercise cross-class or cross-domain privileges beyond its invariant-defined scope.
Constraints
- Teacher principals must only access
class_idboundaries they own. - Role transition must require explicit context change and re-authentication where applicable.
- System administrator must not be able to access or alter any
class_idscoped instances. - A demo seat must behave identically to a regular seat.
Prohibited Action
- Any mechanism that enables privilege escalation or hidden impersonation within the application domain.
5. Definite Class Lifecycle
Statement
class_id defines the boundary in which ledger entries, attendance records, and analytics reside. Destruction of a class must also destroy all data linked to that class_id.
Constraints
- No cross-class global ledger or historical archive retaining deleted class data is permitted within the application domain.
- Deletion of a class must also delete all linked data entries.
- Database backup and restoration must not be used to restore accounts.
- When a seat is deleted with its class, if the owning user has no remaining seats in any class, the user MUST be deleted from the system entirely.
- Classes are not classified as stale; class activity must not be inferred for retention.
- Deleting a teacher account destroys all of its owned class universes through the same terminal destruction mechanism.
- Deleting the last student Seat in a class destroys that class and its teacher Seat. If no other class Seat remains for the teacher, destroy the teacher User as well. The deletion confirmation must warn of the full class/account consequence before execution. Claimed and unclaimed student Seats both count; a newly created empty class is not automatically destroyed before roster provisioning.
- A teacher account with a recorded successful sign-in is automatically destroyed after 180 days without another successful sign-in. An account that has never signed in is destroyed 30 days after creation. Both use the manual account-destruction mechanism; routine activity and session refresh do not reset these clocks.
Prohibited Action
- Storage of
class_idlinked data or accounts after a deletion action has been completed. - Retention of recoverable financial history after class deletion.
6. Class Identity and Membership Model (Existence-Based)
Statement
Class and membership are existence-based, not lifecycle-based. A class_id either exists or does not exist. Membership represents existence within a class, not a state.
Constraints
class_idis the sole authority for class identity and boundary.- A class MUST NOT have lifecycle states such as “active”, “inactive”, or “archived”.
- Membership MUST NOT use lifecycle labels (e.g.,
status,is_active). Membership exists if and only if a seat record exists for a givenclass_id. - Seat state within a class is limited to:
unclaimed(teacher-provisioned placeholder)claimed(identity established via user binding)
- Labels such as
block,period,section, or display names are metadata only and MUST NOT be used for identity, scoping, grouping, or lifecycle decisions. - All settings, aggregates, and operations MUST be scoped by
class_id(or its public aliasjoin_code), not by labels.
Deletion Semantics
- Removing a seat from a class erases that seat from that class context entirely, as if they never existed in that class.
- If a user has no remaining seat associations in any class, the user MUST be deleted from the system entirely.
- Deletion logic MUST be driven by surviving seat associations under
class_idonly.
Prohibited Action
- Branching logic on class or membership lifecycle labels (e.g.,
if status == "active"). - Using labels (
block,period,section) as identifiers or join/filter keys for ownership or lifecycle. - Retaining seat or user records after their last
class_idassociation is removed. - Any cleanup or preservation rule based on labels or legacy identifiers instead of
class_id.
7. No Unnecessary Barriers to Supported Use
Statement
All supported functions within the system shall be accessible to intended users through readily available assistive technologies. Supported use must remain perceivable, understandable, navigable, and operable across the product’s interface, wording, theming, and support surfaces.
Constraints
- User-facing flows must prioritize functional clarity over local stylistic preference.
- Accessibility is part of the supported-function contract, not an optional enhancement.
- Visual design choices, theming, component styling, and interaction patterns must not introduce avoidable obstacles to reading, navigation, comprehension, focus, or task completion.
- Wording, labels, instructions, and documentation must be standardized enough to reduce avoidable ambiguity for intended users.
- Help, support, and operational guidance that the product depends on must not omit or obscure information required to perform supported functions.
- User-facing standardization may vary by audience or context only when the variation removes confusion rather than introducing it.
Prohibited Action
- Introducing interface, wording, documentation, or design decisions that create avoidable friction for intended users when the underlying function is supported.
- Treating accessibility, clarity, or support discoverability as optional polish rather than functional requirements.
- Using local visual or copy conventions that materially reduce usability, comprehension, or operability without an invariant-defined reason.
IV. Identity Model Reference
The canonical identity and ownership model is defined in
INV-ARC-019_IDENTITY_AND_OWNERSHIP_MODEL.md. The settled identity chain is:
users.id— authentication principalseats.id— operational actorclasses.class_id— isolation boundaryseats.public_id— canonical deidentified public actor identityidentity_profiles— display-only identity
Identity resolution and seat-scope enforcement rules are defined in
INV-ARC-008_IDENTITY_RESOLUTION_AND_SEAT_SCOPE.md.
Last updated: 2026-10-19