FEAT-PROD-002: Record Hall Pass Log
| Reference Number | Version | Effective Date | Supersedes | Authority Level |
|---|---|---|---|---|
| FEAT-PROD-002 | 1.1 | 2026-10-01 | 1.0 | Normative |
Revision 1.1 (2026-10-01; ratified by the owner 2026-10-01): adds §III.A, resolution of a pending hall-pass request (approve, reject, student cancel) held in pending_actions (DOM-STORE-001 5.3 §IX). §III is unchanged.
I. Purpose
This FEAT records approved hall-pass rows for the Productivity and Payroll domain.
It writes to hall_pass_logs and reads class-configuration-owned hall_pass_settings to determine whether the pass may be granted.
The row represents the approved hall-pass instruction and the entitlement-consumption event at the same time.
This FEAT uses CanonicalContext for live request authority and the canonical temporal resolver for request-time stamping.
II. Execution Context
1. Required Inputs
ctx:CanonicalContextdestination: teacher-prescribed hall-pass destinationrequested_by_seat_id: seat requesting the passapproved_by_seat_id: seat approving the passreference_time_utc: optional explicit timestamp for deterministic evaluation
2. Canonical Authority
ctx.class_idprovides the class boundaryctx.seat_idprovides the approving seat for live teacher actionsctx.actor_roleMUST be teacher or another lawful approving authority
The FEAT MUST not infer approval authority from the destination or hall-pass payload.
III. Canonical Write
record_hall_pass_log(...)
This is the only lawful mutation path for hall_pass_logs.
Typical use cases:
- teacher approves a hall pass request
- teacher issues a hall pass directly
Rules:
- MUST require
class_id,requested_by_seat_id,approved_by_seat_id, anddestination - MUST evaluate class-scoped
hall_pass_settingsbefore writing the approved pass - MUST NOT mutate
hall_pass_settings; mutation of that table belongs to Class Configuration - MUST fail closed if settings disable the requested destination
- MUST fail closed if queue or simultaneous limits are reached
- MUST record the request timestamp in class canonical time
- MUST represent approval and entitlement consumption together
- MUST set
hall_pass_logs.hall_pass_idto the consumed entitlement instanceentitlement_id - MUST set
hall_pass_logs.correlation_idto the consumed entitlement’s sourcecorrelation_id - MUST not record exit time
- MUST not record return time
- MUST not record hall-pass elapsed time
- MUST not derive attendance state from the hall-pass row
Execution steps:
- Resolve
CanonicalContextand confirm the approving actor is lawful for the class. - Resolve
CLEwithcanonical_temporal_resolver("CLE", primitive="current_time", canonical_execution_context=ctx, reference_time_utc=reference_time_utc). - Validate the requested seat, approving seat, and destination.
- Read Class Configuration’s
hall_pass_settingsfor the class and evaluate pass-type enablement plus queue/simultaneous limits. - Consume one available entitlement instance through the entitlement service.
- Record the approved hall-pass row in
hall_pass_logswith the consumed entitlement’sentitlement_idinhall_pass_idand its sourcecorrelation_id. - Return the approved hall-pass instruction as the lawful source for later attendance-session exit/return evidence.
Failure conditions:
- missing approval authority
- missing entitlement grant identity
- invalid class or seat boundary
- hall-pass settings prohibit the requested pass
- queue or simultaneous limits are reached
- attempt to backfill exit or return data into the hall-pass table
III.A Resolving a pending hall-pass request
A pending hall-pass request is a pending_actions row with authoritative_feat = FEAT-PROD-002 and payload kind hall_pass_request, submitted under FEAT-STOR-002 §X.A. This FEAT is its only resolver (DOM-STORE-001 §VII.B, §IX). Every resolution is scoped by ctx.class_id: a request in another class is not found.
Approve (teacher):
- Lock the request row with
SELECT ... FOR UPDATEand delete it. A concurrent resolution of the same request waits on that lock and, once this transaction commits, finds no row. Exactly one approval therefore succeeds; every other attempt fails as not found. The FEAT idempotency key is not relied on for this. - Record the pass through
record_hall_pass_log(...)(§III) with the payload’srequested_by_seat_idanddestination, the approving seat fromctx, and the entitlement consumption §III requires. - Commit the deletion, the
hall_pass_logsrow and the pass consumption atomically.
If any step is refused (for example, no pass is available, or the settings prohibit the destination), the transaction rolls back and the request stays pending, unchanged, with its original submitted_at (DOM-STORE-001 §VII.B: a failed resolution leaves the pending action intact).
Reject (teacher): lock and delete the row. Nothing else is written; no pass is consumed.
Cancel (student): lock and delete the row only when its seat_id is the student’s own seat in ctx. Any other request is not found. Nothing else is written.
Reads of pending requests (teacher queue, dashboard, student status) take no lock and write nothing.
IV. Temporal Rules
- Hall-pass request timestamps MUST be recorded in class canonical time.
- Exit and return timing remain attendance-session concerns and are not stored here.
- Any hall-pass display or comparison logic MUST use canonical temporal evaluation.
V. Invariants
- Hall-pass approval consumes entitlement.
hall_pass_idlinks the hall-pass log to the specific consumed entitlement instance.- The correlation ID links the hall-pass log to the entitlement source event.
- If the pass was purchased from Store, the upstream ledger entry uses the same correlation ID.
- The FEAT must fail closed if approval authority cannot be established.
hall_pass_settingsis a Class Configuration-owned input to the PROD grant decision and must be evaluated before writinghall_pass_logs.
VI. Dependencies
docs/DOMAIN/DOM-PROD-001_PRODUCTIVITY_AND_PAYROLL_DOMAIN.mddocs/FEATURE-EXECUTION/FEAT-CORE-000_FEATURE_EXECUTION_CONSTITUTIONAL_DIRECTIVE.mddocs/DOMAIN/DOM-OBL-001_OBLIGATIONS_DOMAIN.mdapp/services/context_resolver.pydocs/SPEC/SPEC-TIME-001_CANONICAL_TEMPORAL_RESOLVER.mdapp/utils/canonical_temporal_resolver.py
Last updated: 2026-10-01