DOM-CORE-002: Canonical Schema Definition
| Reference Number | Version | Effective Date | Supersedes | Authority Level |
|---|---|---|---|---|
| DOM-CORE-002 | 1.17 | 2026-10-09 | 1.16 | Constitutional |
I. Purpose
To define the canonical runtime schema of the system as a direct expression of domain authority.
This document defines the only valid set of runtime tables, their responsibilities, and their structural constraints.
II. Scope
This document applies to all runtime tables supporting:
- Identity and class binding
- Economic activity and financial recording
- Attendance and mobility tracking
- Obligation lifecycle and entitlement issuance
- Store interaction and redemption
- Operational observability and audit
- Interpretation and analytics
- Support and communication systems
III. Authority
Foundational. Subordinate to INV-CORE-000, INV-CORE-001, and DOM-CORE-000.
Dependencies
docs/INVARIANT/CORE/INV-CORE-000_CORE_INVARIANTS.mddocs/INVARIANT/CORE/INV-CORE-001_CAPABILITY_BASED_ARCHITECTURE_AND_AUTHORITY_MODEL.mddocs/DOMAIN/DOM-CORE-000_DOMAIN_FOUNDATION.md
This document is the authoritative definition of the V2 runtime schema.
- The runtime schema consists exclusively of the tables defined in this document.
- Any deviation in implementation is considered non-compliant.
- The presence of additional tables in the database does not grant them validity.
IV. Global Schema Invariants
1. Seat-Scoped Isolation
All class-scoped state is anchored to:
seat_id(actor scope)class_id(universe boundary)
No table relies on indirect or inferred scope.
2. Domain Ownership
Each table has exactly one owning domain.
- Only the owning domain defines constraints and mutation authority
- Cross-domain access does not imply shared ownership
3. Event-Log Authority
Authoritative state is represented as:
- Immutable event records, or
- Explicit state tables derived from those events
No implicit state exists.
4. Domain Blindness (Ledger Constraint)
The Ledger domain does not encode business meaning.
- No policy identifiers
- No product abstractions
- No domain-specific classification beyond operational category
5. No Label-Based Authority
Fields such as:
blockperiod- any human-readable grouping label
are not used for:
- scoping
- uniqueness constraints
- identity resolution
Labels are metadata only.
6. Global Idempotency
All write operations include:
idempotency_key
The system guarantees:
- no duplicate side effects
- deterministic replay safety
7. Class Scope Resolution
join_code is a user-facing alias only.
- It is not used for internal scoping
- All internal relationships resolve through
class_id
V. Canonical Domain Tables
1. Identity & Class Binding (DOM-IDEN-001)
Purpose: Define global identity and class-local actor binding.
Tables:
users— global login principal;user_role ∈ {STUDENT, TEACHER, SYSADMIN}seats— class-local participant binding;role ∈ {STUDENT, TEACHER}classes— class universe anchor;class_id(UUID) is the canonical boundaryidentity_profiles— display identity; one-to-one withseats
Composition tables (EXTINCT TABLES - FOR REMOVAL):
user_invite_tokens— short-lived provisioning tokens for teacher account creation; CASCADE-deleted on first use
In V2, teacher self create accounts without invite code. This table is now obsolete.
user_recovery_tokens— time-limited credential recovery tokens; CASCADE-deleted on redemption
In V2, teacher account is recovered by student consensus model per DOM-IDEN-003_TEACHER_IDENTITY_ARCHITECTURE. Student account is recovered by teacher-issued recovery code per DOM-IDEN-002_STUDENT_IDENTITY_ARCHITECTURE. This table is now obsolete
Invariant: User.user_role = SYSADMIN is the sole expression of system-administrator
identity. No separate system_admins, admin_credentials, or
system_admin_credentials table may define identity authority.
Migration note: Legacy split credential tables such as teacher_credentials and
system_admin_credentials are migration artifacts only. They do not define runtime
authority in v2 and must not be treated as canonical schema surfaces.
Recovery, authentication and provisioning-staging tables (owned by DOM-IDEN-003):
recovery_requests— teacher credential recovery lifecycle; at most one pending per userstudent_recovery_codes— per-student verification codes; child ofrecovery_requests, CASCADE-deletedrecovery_class_challenges— per-class proof and confirmation state for one teacher recovery attempt; child ofrecovery_requests, CASCADE-deleted (DOM-IDEN-003 §IX)passkey_credentials— WebAuthn/FIDO2 credential bindings; owned byusers.idteacher_signup_attempts— encrypted, expiring staging record for initial teacher provisioning; grants no authority; consumed atomically by provisioning (DOM-IDEN-003 §V, §VII; registered in 1.10)
2. Class Configuration (DOM-CLASS-001)
Purpose: Define class-level directives, feature enablement, and class-owned configuration.
Tables:
class_featureseconomic_engine— class-level economic configuration and projection state; append-only versions, each with theeffective_atfrom which it governs (DOM-CLASS-003§VII; 1.12)feature_settings— per-class economy policy configuration that applies when a feature is enabled; enablement itself stays inclass_features(DOM-CLASS-001 §VI; DOM-POL-001A §IV; registered in 1.10)
Policy definition tables — rent_settings, payroll_settings, payroll_rewards, payroll_fines, hall_pass_settings, store_products, store_item_visibility, and insurance_policies — are not Class Configuration authority. They are stored in the Policies repository (DOM-POL-001) as immutable, append-only version rows. Policies does not originate mutations; the domain that initiates a change (Class Config UI submissions, insurance authoring, store curation, etc.) submits a new definition and Policies records it under a new policy_uuid. The consuming operational domain — DOM-OBL-001 for rent, DOM-PROD-001 for payroll and hall-pass, DOM-STORE-001 for store/entitlements, the Insurance operational flow for insurance — reads the current policy_uuid and owns only the operational facts that result (bill cycles, payroll events, hall-pass logs, entitlement events, etc.). See DOM-POL-001 §V and §X.
banking_settings (savings APY, overdraft fees, interest calculation, disbursement schedule) is not a policy repository concern. Its content is inherently Class Configuration → economic_engine business, governed by DOM-CLASS-001 (schema ownership) and DOM-CLASS-002 (economy governance: interest formulas, overdraft behavior). Class-level economic evolution is versioned by the economic_engine rows themselves (DOM-CLASS-003 §V), not through the Policies repository.
Prohibited: No persisted compute-result caches (e.g., payroll_cache). Computed values are derived on read from authoritative event tables or recomputed by services.
3. Productivity & Payroll (DOM-PROD-001)
Purpose: Record productivity participation facts, approved hall-pass consumption, and payroll business events.
Tables:
attendance_sessionsattendance_interval_invalidationhall_pass_logspayroll_eventpayroll_cycle_completion— the persistent completion anchor for a class-level payroll run, resolved before any work on replay so a replay returns the originalpayroll_cycle_id(DOM-PROD-001 §XV; FEAT-PROD-004; registered in 1.10)
Hall-pass consumption registration (1.17): hall_pass_logs.hall_pass_id, the used pass’s entitlement_id, is the only consumption record for a hall pass (FEAT-PROD-002 §III; DOM-STORE-001 §VIII.E.6; owner ruling 2026-10-09); using a pass writes no entitlement_events row. Unique partial index uq_hall_pass_logs_hall_pass_id on hall_pass_id where it is not null lets each pass be consumed at most once, the guarantee the one-terminal-event-per-lineage index gave while use also wrote CONSUMED. Logs for non-consuming destinations carry no hall_pass_id. Historical CONSUMED rows for hall passes stay as history; a pass is spent if either names it. No column or data change.
Interval correction schema contract (1.13):
attendance_interval_invalidation is the append-only terminal eligibility surface owned by PROD and authorized through FEAT-PROD-005. It requires id, class_id, actor_seat_id, target_seat_id, opening_event_id, closing_event_id, recorded_at (UTC), reason_code, idempotency_key, correlation_id, receipt_json (immutable nonmonetary accepted-command receipt), lineage_event_id, lineage_token (String(64)), and lineage_version (Integer). The audit triple starts all-null, initializes completely once in the creating transaction, and is excluded from its own protected payload. Application and deferred database guards enforce the creation protocol and permanently freeze committed business/linkage fields. Unique (class_id, target_seat_id, opening_event_id, closing_event_id) and (class_id, idempotency_key) enforce terminal decisions and FEAT-PROD-005 command replay. Reasons are INVALID_ATTENDANCE, NON_WORK_ACTIVITY, or DUPLICATE_PARTICIPATION; no free notes. Opening/closing references are within PROD; class/seat references use shared anchors. Target-seat/class destruction removes dependent business records, while actor provenance does not own another target’s records.
payroll_event additionally permits payroll_event_type = correction. Its protected summary_json carries original-event and correction-intent provenance and complete original settlement membership/pricing/allocation-version inputs, not monetary amounts. Original-payroll-event and invalidation IDs refer within PROD; Ledger and policy references are opaque non-FK locators. No persisted earnings cache or amount column is authorized. The incorporated SPEC-PROD-001 contract is enforced through owning PROD commands and declared FEAT orchestration, never DOM-to-DOM calls.
payroll_event carries nullable lineage_event_id, lineage_token (64 characters), and lineage_version metadata. The event ID is an opaque Operations locator, not an internal cross-domain FK. New rows begin with empty linkage and initialize all three fields exactly once through Operations within their creating FEAT transaction; committed business and linkage fields are permanently immutable (DOM-PROD-001 §XI.3, DOM-OPS-002 §6.1). Deferred database and application guards reject missing or mismatched creation evidence. Historical NULL linkage remains untouched and UNVERIFIED; no backfill is authorized.
The protected-row lineage_event_id linkage is mandated narrowly by INV-ARC-016 §V; it does not authorize arbitrary cross-domain internal-table FKs under INV-ARC-021 §V.7. This schema amendment does not execute migrations or imply runtime availability.
4. Obligations & Entitlements (DOM-OBL-001)
Purpose: Manage seat-scoped debt lifecycle and recurring reminder state.
Tables:
bill_cyclesassessment_eventsobligation_satisfactionobligation_command_reservation
obligation_command_reservation records bill-cycle succession command identity (DOM-OBL-001 §V.7): one row per executed schedule_next_bill_cycle command, scoped by class_id and command identity, carrying the request fingerprint it was accepted under and the bill_cycles row it produced. It is execution/replay state, not domain state; bill_cycles carries no command identity, so replay by command identity requires it (added in 1.10).
5. Ledger & Money (DOM-LED-001)
Purpose: Record all monetary movement.
Tables:
ledger_transactionledger_balance_snapshotledger_command_reservation
ledger_command_reservation is the physical representation currently in use for the Ledger command reservation defined in DOM-LED-001 §VII.1: identity (class_id, feat_code, idempotency_key), the replay fingerprint, and the effects it produced (ledger_transaction.command_reservation_id). DOM-LED-001 §VII.1 defers the choice of representation; this entry registers the one that exists and does not settle that choice (registered in 1.10).
Immutable reversal registration (1.16): ledger_transaction.original_transaction_id on a new REVERSAL effect identifies its exact original Ledger effect, with matching original correlation and class/seat/account scope. Unique partial index uq_ledger_exact_reversal_origin on original_transaction_id where type = 'REVERSAL' prevents duplicate exact reversals. Ledger owns admission/scope/cent validation and serialization. The retained reversal_transaction_id column is immutable historical material, not canonical reversal state; new commands leave it uninitialized and derive linkage through the new effect. Existing values/signatures are not backfilled, removed, or reinterpreted. No cross-domain FK or persistence surface is added.
Compensation field registration (1.13): ledger_transaction adds immutable Ledger-owned compensation_origin_locator (String(128), nullable, opaque original Ledger credit locator), compensation_amount_cents (Integer, nullable only on historical rows; new rows explicitly carry nonnegative attributable recovery, with protection/non-recovery legs zero), and correction_intent_locator (String(128), nullable, opaque originating intent). Positive recovery requires both locators, equals its exact debit cents and has unique (class_id, target_seat_id, compensation_origin_locator, correction_intent_locator) identity; zero-recovery effects carry neither locator. Ledger commands alone enforce the aggregate recovery cap and serialization. These locators encode no payroll business classification and introduce no FK into PROD internals. These are the three runtime compensation fields protected under Ledger signature version 3; version 2 retains its original sixteen-field registry. No historical field inference, lineage replacement or backfill is authorized.
Constraints:
- Anchored to
seat_id - Does not store
join_code - Enforces
idempotency_key - Remains domain-blind
6. Store & Redemption (DOM-STORE-001)
Purpose: Manage entitlement grant lineage, entitlement exercise lineage, pending entitlement actions, and insurance claims.
Tables:
entitlement_eventspending_actionsinsurance_claims— durable insurance claim truth: one claim filed under one insurance entitlement, never an entitlement event (DOM-STORE-001 §VII.C, §VIII.E.1; registered in 1.10)insurance_claim_productivity_dates— structured per-date evidence for a PRODUCTIVITY claim; child ofinsurance_claims, CASCADE-deleted (DOM-STORE-001 §VII.D; registered in 1.10)
7. Operations & Observability (DOM-OPS-001)
Purpose: Record system behavior, health, and audit trace.
Tables:
operational_eventsaudit_eventschain_headsincident_eventsincident_summaryalert_eventsinvariant_run_eventsjob_eventshealth_check_events
8. Interpretation (DOM-ITR-001)
Purpose: Derive descriptive observations and interpretive signals over completed economic cycles.
Tables:
interpretation_cycle_record— durable, immutable per-cycle materialization bound topayroll_cycle_id, self-describing via persisted economic reference values (DOM-ITR-001§IX). Materialized only as a declared side effect ofFEAT-PROD-004at payroll completion. Table built in the runtime schema via migrationb3d7f1a9c2e4(persistence surface implemented); theFEAT-PROD-004materialization writer that populates it is not yet built, so no rows exist yet.
The former interpretation_snapshots (cache) and interpretation_annotations tables are retired and superseded by interpretation_cycle_record per DOM-ITR-001 v1.4 §IX. Neither existed in the runtime schema.
Constraint:
- Read-only domain (Interpretation performs no source-domain mutation;
interpretation_cycle_recordrows are written only via theFEAT-PROD-004materialization side effect and are append-only and immutable thereafter).
9. Support & Communication (DOM-SUP-001)
Purpose: Manage issue lifecycle and system communication.
Tables:
issuesissue_status_historyissue_resolution_actionsticket_correlation_packactor_request_trace— short-lived request traces a correlation pack reads (DOM-SUP-001 §X). References its seat by public ID only, with no cross-domain foreign key (INV-ARC-021 §V.7); seat deletion deletes its traces explicitlyannouncementsissue_categories
10. Economic Policy (DOM-CLASS-003)
Purpose: Govern how economic policy evolves in its owning tables (DOM-CLASS-003 §V).
Tables: none. Economic policy history is held by the owning domains’ own tables listed in §2 (economic_engine) and §11.
Retired (operator ruling 2026-09-30; 1.12).
policy_versionsandpolicy_transitionswere never authorized by the owner as canonical. 1.11 marked them legacy; 1.12 removes their registration, and migrationdd52b19d48d8drops them together withassessment_events.policy_version_id. They MUST NOT be reintroduced (DOM-CLASS-003§V).
11. Policies (DOM-POL-001)
Purpose: Serve as an append-only, immutable repository of class-scoped policy definitions that other domains reference by policy_uuid. Policies is the newest domain in the list and does not own mutation flows — it stores the immutable version references that operational and configuration domains produce and consume. The act of “changing rent” lives in the domain that initiates it; Policies just records the resulting immutable definition row and hands back a stable policy_uuid.
Tables (per DOM-POL-001 §X boundary attribution):
rent_settings— rent policy definitions (rate, cycle length, effective boundaries) as append-only version rows; consumed byDOM-OBL-001payroll_settings,payroll_rewards,payroll_fines— payroll policy definitions (wage rate, frequency, reward/fine catalog);payroll_settings.pay_ratestores the normalized per-minute rate asNUMERIC(18,8)so conversions from teacher-entered hourly or daily rates retain sub-cent precision; consumed byDOM-PROD-001.payroll_settingsis append-only and effective-dated, keyed bypolicy_uuid, with exactly the columns inDOM-POL-001A§V.F (operator ruling 2026-09-30; 1.11). Itsrounding_modecolumn is retired historical data, not a supported settinghall_pass_settings— hall-pass policy definitions (allowed destinations, limits); consumed byDOM-PROD-001at grant timestore_products,store_item_visibility— purchasable / rent-linked entitlement offering definitions and per-class visibility; consumed byDOM-STORE-001.store_productsis the single versioned product table that replacedstore_itemsand the earlierstore_products(migrationb7c41e9a2f30); renamed here in 1.10insurance_policies— immutable insurance definition rows (DOM-POL-001§X “insurance definitions -> Policies”;DOM-POL-001A§D); consumed by the insurance entitlement lifecycle (DOM-STORE-001); named here in 1.10
Not in this repository:
banking_settings— Class Configuration →economic_engineconcern (interest, overdraft). SeeDOM-CLASS-001andDOM-CLASS-002.
Boundary notes:
- Policies does not originate mutations. Other domains submit definitions through Policies; each submission creates a new
policy_uuid(seeDOM-POL-001§VI, Insert and Availability Contract). - Rows are immutable after insert. Replacement is a new row, never an in-place edit. Mutable-singleton settings blobs are prohibited under
DOM-CLASS-003§V. - Downstream domains reference
policy_uuidas a non-FK provenance locator and freeze any terms they need for standalone executability (seeDOM-POL-001§V.A, §IX). - Rent example: Class Configuration owns the
rentfeature flag (class_features); Policies stores the immutablerent_settingsversion rows; Obligations (DOM-OBL-001) ownsbill_cyclesandassessment_events(the recurring act of charging rent) and references the current rentpolicy_uuidfor provenance. - Payroll example: Class Configuration owns the
payrollfeature flag; Policies stores effective-datedpayroll_settingsrows;DOM-PROD-001ownspayroll_eventand records thepolicy_uuidof the setting in force when each settled session closed (DOM-PROD-001§XV.3). - Hall-pass example: Class Configuration owns the
hall_passfeature flag; Policies storeshall_pass_settingsversion rows;DOM-PROD-001ownshall_pass_logsand reads the current hall-passpolicy_uuidat grant time to constrain what may be written.
VI. Explicit Prohibitions
The following do not exist in the V2 schema:
- Separate identity tables for roles (e.g.,
students,teachers) - Label-based scoping tables
- Cross-domain mutation through direct table access
- Business meaning encoded in the Ledger domain
- Duplicate authority paths for the same concept
- Internal scoping via
class_idonly;join_codeis ingress-only alias metadata
VII. Compliance
Only the tables defined in this document are valid within the V2 system.
No additional tables may be introduced without amendment to this document.
VIII. Amendment
Version 1.17 (2026-10-09) registers the hall-pass consumption record and its unique partial index (migration 35a9a0d3ab93). Source authority is FEAT-PROD-002 §III and DOM-STORE-001 §VIII.E.6, with the owner’s ruling that the hall-pass log is the only legal consumption reference.
Version 1.15 (2026-10-03) registers implemented invalidation linkage and Ledger compensation persistence under the existing domain/FEAT commands and versioned audit contracts.
Version 1.13 (2026-10-03) supersedes 1.12 for the explicit addition of interval invalidation, nonmonetary settlement/correction provenance, and Ledger compensation fields. Source authority is INV-CORE-000 §III.1–6, INV-CORE-001 §III/VIII, INV-ARC-006 §V, INV-ARC-016 §V/IX, and INV-ARC-021 §V/VII. Writer authority is declared in FEAT-PROD-003 and FEAT-PROD-005; no runtime implementation is part of this amendment.
Any modification to the canonical schema requires:
- Version increment
- Updated Effective Date
- Explicit justification tied to domain authority
Version 1.14 (2026-10-03) registers payroll creation lineage metadata and its narrow, atomic initialization protocol, superseding an unqualified UPDATE prohibition only before the creating transaction commits.
Last updated: 2026-10-09