Skip to content
INV-CORE-000: Core Invariants of Classroom Token Hub

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_id boundary they are not bound to.
  • No financial operation may be performed without explicit class_id scope.
  • All domain services must accept class_id as an explicit parameter. Services may accept join_code for convenience but must resolve it to class_id before any authority-sensitive operation.
  • No global settings, attributes, logs, or ledgers are allowed within the application.
  • Scoped data associated with a class_id must not survive its deletion unless explicitly re-scoped under a separate class_id context.

Prohibited Action

  • Any operation that accesses or mutates data across class_id boundaries 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 seats for 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_id scope 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_id boundaries 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_id scoped 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_id linked 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_id is 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 given class_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 alias join_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_id only.

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_id association 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 principal
  • seats.id — operational actor
  • classes.class_id — isolation boundary
  • seats.public_id — canonical deidentified public actor identity
  • identity_profiles — display-only identity

Identity resolution and seat-scope enforcement rules are defined in INV-ARC-008_IDENTITY_RESOLUTION_AND_SEAT_SCOPE.md.

Edit canonical source on GitHub

Last updated: 2026-10-19