FEAT-PROD-001: Record Attendance Session
| Reference Number | Version | Effective Date | Supersedes | Authority Level |
|---|---|---|---|---|
| FEAT-PROD-001 | 1.5 | 2026-10-03 | 1.4 | Normative |
I. Purpose
This FEAT owns attendance ingress. FEAT-PROD-003/004 may compose only the due-system-closure PROD command authorized by DOM-PROD-001 §XV.7 inside their own atomic context.
It records attendance-session rows for the Productivity and Payroll domain and replaces any other FEAT or route path that would otherwise write to that table.
This FEAT uses CanonicalContext for live request authority and canonical_temporal_resolver("CLE", primitive="current_time", ...) from app/utils/canonical_temporal_resolver.py for class-local time evaluation.
II. Scope
Governs append-only attendance event creation. Terminal interval invalidation is a separate FEAT-PROD-005 operation; this FEAT does not write eligibility decisions or money.
III. Authority Level
Normative; subordinate to INV-CORE-000 §III.1–6, INV-CORE-001 §III, VIII, DOM-PROD-001 §VII–XI, and FEAT-CORE-000 §II–V. INV-ARC-006 §V, INV-ARC-007 §V, INV-ARC-009 §V, and INV-ARC-021 §V govern command-only mutation, pure reads, domain authority, and composition.
IV. Dependencies
-
docs/DOMAIN/DOM-PROD-001_PRODUCTIVITY_AND_PAYROLL_DOMAIN.md -
docs/FEATURE-EXECUTION/FEAT-CORE-000_FEATURE_EXECUTION_CONSTITUTIONAL_DIRECTIVE.md -
app/services/context_resolver.py -
docs/SPEC/SPEC-TIME-001_CANONICAL_TEMPORAL_RESOLVER.md -
app/utils/canonical_temporal_resolver.py
V. Execution Context
1. Required Inputs
ctx:CanonicalContextidempotency_key: when the caller requires replay protection for the writereference_time_utc: optional explicit timestamp for deterministic evaluationactor_seat_id: the seat performing the actiontarget_seat_id: the seat whose attendance state is being recordedmechanism:self,teacher, orsystem
2. Canonical Authority
ctx.class_idprovides the class boundaryctx.seat_idprovides the actor/target seat for live requestsctx.actor_roledetermines whether the action is a student or teacher attendance action
The FEAT MUST fail closed if ctx.class_id or ctx.seat_id cannot be established.
The FEAT MUST NOT infer authority from legacy identity sources.
The FEAT MUST NOT infer class or seat authority from any legacy identity source.
VI. Canonical Write
record_attendance_session(...)
Attendance ingress uses this FEAT; due system closure may be composed by FEAT-PROD-003/004 under DOM-PROD-001 §XV.7.
Canonical business actions:
- start work
- return from hall pass
- leave for hall pass
- end of day
- automatic session closure when a new active session opens
- automatic session closure at the time limit
- automatic session closure at end of day
Rules:
- MUST require
class_idandseat_id - MUST treat every written attendance row as immutable and permanent
- MUST require
actor_seat_id,target_seat_id, andmechanism - MUST use class-local canonical time for the timestamp
- MUST set
statustoactiveorinactive - MUST set
reason_codewhen writing aninactiverow - MUST set
hall_pass_idwhenreason_code = hall_pass - MUST set
mechanismtoself,teacher, orsystem - MUST set
actor_seat_idto the initiating seat - MUST set
target_seat_idto the seat whose attendance state changes - MUST NOT persist or select attendance by an authentication principal; target identity is
(class_id, target_seat_id) - MUST write
activewithreason_code = start_workfor start work and hall-pass return - MUST write
inactivewithreason_code = hall_passfor leaving for hall pass - MUST write
inactivewithreason_code = done_for_dayfor end-of-day closure - MUST write the automatic closure row(s) rather than mutating prior rows
- MUST append a new
activerow followed by aninactivedone_for_dayrow when a dangling hall pass is detected at end of day - MUST use the same timestamp for both rows in that dangling-hall-pass recovery sequence
- MUST not store current attendance state
- MUST not store accumulated daily minutes
- MUST not store hall-pass destination
- MUST not store payroll amount
- MUST NOT delete, soft-delete, edit, mark as deleted, hide, or correct an existing
attendance_sessionsrow (destruction of a seat’s rows with the seat, or of a class’s rows with the class, is lifecycle destruction outside this FEAT —DOM-PROD-001§VII.1.a) - MUST NOT provide a teacher-facing attendance-row deletion or correction endpoint
- MUST NOT use attendance-row mutation to correct a payroll outcome
Correction rule:
- A teacher invalidates a completed work interval through
FEAT-PROD-005, which appends a separate eligibility decision and any required payroll correction through domain commands.FEAT-PROD-003retains exact whole-event reversal and residual recovery authority. - The original attendance row remains part of the immutable productivity timeline.
Execution steps:
- Resolve
CanonicalContextand confirm the request is lawful for the seat and class. - Resolve
CLEwithcanonical_temporal_resolver("CLE", primitive="current_time", canonical_execution_context=ctx, reference_time_utc=reference_time_utc). - Derive the canonical request timestamp in class-local time and normalize it to UTC for persistence.
- Determine the correct canonical row shape for the requested attendance action.
- Populate
actor_seat_id,target_seat_id, andmechanism. - If the row is hall-pass-related, require
hall_pass_idto reference the consumed entitlement instance’sentitlement_id. - If end-of-day cleanup finds a dangling hall pass, emit
active/start_workand theninactive/done_for_dayat the same timestamp. - Persist the append-only row or row sequence to
attendance_sessions.
Failure conditions:
- missing class context
- missing seat context
- invalid hall-pass correlation
- attempt to mutate prior attendance state instead of appending a new row
- attempt to delete, soft-delete, mark-delete, or correct an existing attendance row
- attempt to write
attendance_sessionsoutside this FEAT
VII. Temporal Rules
- Attendance comparisons MUST use the canonical temporal resolver.
- Attendance rows are recorded in UTC and displayed in class canonical time.
- Any derived attendance duration MUST be computed from the attendance timeline, not stored on the row.
- End-of-day cleanup MUST respect the current class-local day boundary.
VIII. Write Authority
The PROD attendance command is the sole writer for attendance_sessions; FEAT-PROD-001 owns ingress and FEAT-PROD-003/004 may compose its narrow due-system-closure operation.
No other FEAT, route, background job, service, or migration logic may write to
attendance_sessions directly.
Other attendance writers MUST compose this domain command under the declared execution contract, never execute a nested FEAT (FEAT-CORE-000 §V.1). Interval eligibility is a separate domain surface and writes no attendance_sessions row.
IX. Invariants
- Attendance writes are append-only.
- Attendance rows are immutable after insertion and permanent for as long as their target seat exists; they are destroyed only with that seat or with the class (
DOM-PROD-001§VII.1.a,INV-CORE-000§III.6). - There is no delete, soft-delete, mark-deleted, or correction-in-place attendance path. Lifecycle destruction of the seat or class is not such a path.
- Interval invalidation and payroll recovery append separate records under
FEAT-PROD-005/FEAT-PROD-003; neither changes attendance. - Hall-pass attendance rows must carry the same consumed entitlement instance
entitlement_idrecorded ashall_pass_logs.hall_pass_id. - The FEAT must fail closed if
ctx.class_idorctx.seat_idcannot be established. - The FEAT must not mutate hall-pass entitlement state.
- All attendance writes use the PROD command under a declared FEAT coordinator; the system-closure exception is limited by DOM-PROD-001 §XV.7.
X. Amendment
Version 1.4 (2026-10-03) supersedes v1.3’s whole-payroll-only correction wording; it preserves attendance immutability and identifies the separate interval-invalidation contract. This amendment implements documentation authority only. Revisions must increment version/date, identify superseded rules, and preserve governing invariants.
Version 1.5: prospective provenance foundation (2026-10-03)
Supersedes 1.4’s exclusive writer wording only for canonical due system closure. Incorporates DOM-PROD-001 §XV.7–8 and SPEC-PROD-001
§VI: preserve pair IDs, freeze version-1 settlement inputs, protect complete payroll summaries, and expose pure evidence queries. Every attendance writer locks its class/target seat before selection. New payroll composes close_due_attendance_intervals within one FEAT transaction before pricing; class completion resolves completed-run replay first and locks eligible seats in stable order. Audit linkage initializes once within creation and cannot change after commit. No nested FEAT, historical backfill, or correction button is authorized by this foundation.
Last updated: 2026-10-03