Senior care family engagement platform

KinLoop

Care moments, privately shared

KinLoop is a secure family engagement app for tech-light assisted living caregivers and administrators. It turns everyday care into private, one-tap photo and voice-to-text updates, with automatic digests to approved families, ending phone tag and cutting inbound calls 60% while saving 45 minutes per shift. Auto-blur hides non-consenting faces, speeding handoffs and protecting dignity and compliance.

Subscribe to get amazing product ideas like this one delivered daily to your inbox!

KinLoop

Product Details

Explore this AI-generated product idea in detail. Each aspect has been thoughtfully created to inspire your next venture.

Vision & Mission

Vision
Keep families present and residents seen in every assisted living community, uniting caregivers and loved ones through effortless, private connection.
Long Term Goal
By 2028, power private family engagement in 5,000 assisted living communities, boosting family satisfaction 30% and cutting caregiver communication time by two hours per shift.
Impact
For assisted living caregivers and administrators, KinLoop cuts inbound family calls by 60% and saves 45 minutes per shift, while making shift handoffs 35% faster. Families engage quickly, with 82% opening digests within 6 hours, and residents receive 2.3x more documented positive moments.

Problem & Solution

Problem Statement
Assisted living caregivers and administrators can’t keep multiple families informed without constant phone tag and ad‑hoc texts; existing clinical portals demand heavy data entry and lack photo‑privacy safeguards, fueling missed updates, compliance risk, burnout, and anxious families.
Solution Overview
KinLoop ends phone tag by centralizing each resident’s updates into a private feed that auto-delivers to approved family. Caregivers share moments with one‑tap, voice‑to‑text posts; families receive automatic daily digests, reducing inbound calls and constant check-ins.

Details & Audience

Description
KinLoop is a secure family engagement platform that turns everyday care into private, timely updates for assisted living residents’ families. Built for administrators and caregivers who need tech‑light workflows. It ends phone tag and ad‑hoc texts with one‑tap posts and automatic digests, cutting inbound calls and saving 45 minutes per shift. Auto‑privacy photo blurring detects and hides non‑consenting faces, protecting dignity and compliance.
Target Audience
Assisted living caregivers and administrators (28-60) overwhelmed by family calls; tech-light communicators.
Inspiration
At noon in the dining room, a nurse cradled three ringing phones while soup cooled and residents ate in silence. A daughter rushed in, anxious after hearing nothing all week. Ten minutes later, I spotted her mother beaming in chair yoga, unseen beyond that room. The disconnect was painful and obvious: moments existed, but didn’t travel. KinLoop began as a one-tap, photo-and-note loop to carry them home.

User Personas

Detailed profiles of the target users who would benefit most from this product.

Product Features

Key capabilities that make this product valuable to its target users.

RoleSmart Mapping

Auto-assigns the correct role and unit on tap by combining badge identity with the day’s schedule and device location. Prevents permission mistakes for floaters, eliminates manual selection, and ensures the right access every shift without extra taps.

Requirements

Badge Identity Integration
"As a caregiver, I want to tap or scan my badge to sign in so that my role is recognized without manual selection."
Description

Integrate NFC/badge tap and camera barcode scan to capture a staff badge ID and securely map it to a KinLoop staff profile, with encrypted storage, tokenized identifiers, offline caching, and MDM-compatible configuration, ensuring reliable identification on shared, tech-light devices with minimal user effort.

Acceptance Criteria
NFC Badge Tap: One-Tap Identity Capture
Given a shared device with KinLoop open and NFC enabled When an authorized staff taps their NFC badge Then the app reads the badge UID and maps it to the correct KinLoop staff profile And issues a signed session token without additional taps And displays a success confirmation within 2 seconds And no on-screen exposure of full legal name until session is established
Camera Barcode Scan Fallback
Given NFC read fails 3 consecutive times or NFC is unavailable When the user selects Scan Badge and presents a Code 128 or QR staff badge Then the camera decodes and validates the badge ID within 2 seconds at 200 lux and above And maps it to the correct KinLoop staff profile And completes sign-in with no more than 2 taps total And provides haptic and audible confirmation on success
Secure Storage and Tokenization of Badge Identifiers
Given a badge ID is read by NFC or camera When persisting any identifier on device Then store only a tokenized identifier (irreversible salted hash) and never the raw badge ID And encrypt all persisted data using the platform keystore (AES-256-GCM) with hardware-backed keys And transmit any network calls over TLS 1.2+ with certificate pinning enabled And redact badge IDs in logs and analytics
Offline Caching and Deferred Sync
Given the device has no network connectivity When a known staff badge is tapped or scanned Then the app authenticates locally using a cached badge-to-profile token within 2 seconds And queues a reconciliation event for server sync And enforces a configurable offline cache TTL (default 7 days), refusing expired entries And on reconnect, syncs queued events successfully on first attempt 99% of the time
MDM Configuration and Managed App Settings
Given the app is installed under an MDM with Managed App Config When admin pushes configuration for badge types, API endpoints, certificate pins, token TTLs, and offline TTLs Then the app applies changes without reinstall or user intervention within 10 minutes of receipt And prevents operation on unmanaged devices unless a local override flag is present in config And wipes cached identity tokens upon receiving an MDM wipe/retire command
Error Handling, Revocation, and Audit Trail
Given a badge is unknown, malformed, expired, or revoked When the badge is tapped or scanned Then the app rejects the attempt, shows a clear non-technical message, and offers retry or help And does not create or reuse any session And records an audit event with timestamp, device ID, location, outcome, and a truncated badge hash (last 4 chars), with no PII And rate-limits repeated failures to 5 attempts per minute per device
Shared Device Session Boundaries and Fast User Switch
Given a staff member is signed in via badge When another staff taps or scans their badge Then the prior session is ended and the new session is established within 2 seconds without manual logout And all in-memory user data is cleared before new session start And the lock screen auto-appears after 5 minutes of inactivity And no data from the prior user is visible in recent screens or caches
Schedule Sync & Role Mapping
"As an administrator, I want the system to auto-map staff to units based on the live schedule so that floaters get the correct access every shift."
Description

Synchronize the day’s schedule and assignments from facility scheduling systems (e.g., Kronos/UKG, PointClickCare) on a near–real-time cadence, normalize data to KinLoop roles and units, resolve conflicts for floaters and split shifts, and cache results for resiliency, ensuring correct role/unit mapping even during vendor outages.

Acceptance Criteria
Near-Real-Time Schedule Synchronization
Given a schedule change in Kronos/UKG or PointClickCare for today, When a webhook event is received or a polling cycle completes, Then the updated assignment is available to RoleSmart mapping within 5 minutes (p95) and 10 minutes (p99). Given no webhook is available, When polling is used, Then the system polls vendor APIs at an interval of ≤3 minutes during operational hours. Given duplicate or out-of-order vendor events, When ingestion occurs, Then processing is idempotent and retains the most recent effective state only. Given a partial-day schedule update, When processed, Then only affected assignments are updated without overwriting unrelated entries.
Role and Unit Normalization to KinLoop Model
Given vendor role and unit codes exist in the configured mapping table, When normalization runs, Then 100% of those codes map deterministically to a single KinLoop role and unit. Given an unknown or unmapped code is encountered, When normalization runs, Then the assignment is quarantined as Unmapped with least-privilege access, an admin alert is generated within 2 minutes, and the case is visible in the admin console. Given a mapping table change is published, When deployed, Then normalization uses the new version within 2 minutes and supports rollback to the prior version within 2 minutes.
Floater and Split-Shift Conflict Resolution
Given a caregiver has overlapping assignments, When selecting the active mapping, Then prefer the assignment whose time window includes now; if multiple, prefer the unit whose geofence contains the device; if still multiple, prefer the earliest start time; if still tied, select by lexicographic unit name for determinism. Given a caregiver is floating between two units, When the device enters a different unit geofence and remains for ≥2 consecutive samples within 2 minutes, Then the active mapping switches to that unit. Given an assignment end time has passed, When 10 minutes elapse beyond the scheduled end, Then access granted by that assignment is revoked unless an extension appears in the schedule.
Location-Aware Selection and Performance
Given device location accuracy is ≤20 meters, When a mapping decision is requested, Then the decision completes in ≤300 ms (p95) and ≤500 ms (p99). Given GPS is unavailable, When Wi‑Fi or BLE location is available, Then it is used for geofence determination; if no location is available, Then the system uses schedule-only plus last-known unit (≤15 minutes old) or falls back to Unmapped least privilege. Given unit geofences are configured, When crossing boundaries, Then hysteresis prevents flapping by requiring a minimum dwell time of 30 seconds before switching units.
Resilient Caching During Vendor Outages
Given a vendor API outage occurs, When schedule sync attempts fail, Then the system serves mappings from the last known good cache for at least 24 hours and exposes staleness age on each decision. Given cached data age exceeds 24 hours, When a mapping is requested, Then the system defaults to least-privilege access and raises a critical alert to monitoring within 5 minutes. Given vendor connectivity is restored, When reconciliation runs, Then the cache reflects the current vendor schedule within 10 minutes without creating duplicate assignments.
Audit Logging and Traceability
Given any mapping decision completes, When logging, Then an audit record is stored with timestamp, hashed badge ID, schedule source and version, location basis, rule path taken, chosen role/unit, and decision latency. Given an admin requests export for a user and timeframe, When querying the last 90 days, Then results return within 30 seconds and redact PII per policy. Given a disputed access event, When filtering by user and time window, Then the decision trail is reconstructible end-to-end with deterministic inputs and outputs.
Access Scope Enforcement from Mapping
Given an active mapping result exists, When the user accesses KinLoop, Then permissions are limited strictly to the mapped role and unit; attempts to access other units or elevated roles return HTTP 403 within 200 ms. Given an Unmapped or quarantined assignment, When write operations are attempted, Then they are blocked and only base read access to permitted content is available. Given 10 minutes have passed after the scheduled shift end with no extension, When access is requested, Then elevated permissions are revoked automatically.
Geofenced Unit Detection
"As a caregiver, I want the device to detect my current unit so that my access matches where I am working."
Description

Determine the current unit/wing using privacy-preserving location signals (Bluetooth beacons, Wi‑Fi SSID mapping, and optional QR/NFC room beacons) with graceful degradation and offline fallback, avoiding continuous tracking while enabling precise, low-power, on-premise unit detection.

Acceptance Criteria
Bluetooth Beacon Unit Detection (Primary Path)
Given the device is within a unit equipped with calibrated BLE beacons and the app is in the foreground or has just resumed When a scan cycle is initiated Then the unit is resolved within 3 seconds with ≥95% accuracy across 100 test transitions per unit And the resolved unit ID is emitted to the app session without storing raw coordinates or beacon MACs longer than 24 hours (hashed in logs) And unit changes require a minimum 20-second dwell and a 6 dB RSSI advantage to prevent flapping between adjacent units
Wi‑Fi SSID/BSSID Mapping Fallback
Given BLE signal quality is below the configured threshold or no beacons are detected When the device can passively scan Wi‑Fi and a locally cached SSID/BSSID→unit map exists Then the unit is resolved within 5 seconds using the strongest mapped BSSID And if multiple mapped BSSIDs are present, tie-break by highest RSSI then lexicographic BSSID for determinism And no active association or location permission beyond scan is requested; only passive scan metadata is used And if the mapping is older than 30 days, detection still proceeds and a telemetry event flags the stale map for admin refresh
QR/NFC Room Beacon Override
Given a caregiver scans a KinLoop QR code or taps an NFC tag configured for a room When the code/tag is validated against a locally cached, signed whitelist Then the app sets the current unit to the room’s parent unit immediately (<1 second) And this explicit unit persists for 15 minutes or until a higher-priority explicit scan occurs, whichever comes first And unrecognized or unsigned codes are rejected with a non-blocking error and no unit change And an audit event is recorded with timestamp, anonymized code ID, and unit ID (no raw location) for compliance
Graceful Signal Fusion and Degradation
Given multiple location signals may be available with varying quality When resolving the current unit Then the engine applies the priority order: QR/NFC > BLE > Wi‑Fi > Last‑Known (≤30 minutes old with motion confirmation) And if all signals are insufficient, the unit remains Unknown and posting actions that require unit context are blocked with a single, dismissible banner suggesting moving to a beacon area or scanning a QR/NFC tag And when a sufficient signal reappears, the unit auto-resolves without app restart and the banner is cleared
Offline Fallback and Sync Resilience
Given the device has no internet connectivity When detecting unit via BLE, Wi‑Fi scan names, or QR/NFC Then unit resolution succeeds using locally cached configurations without remote calls And detections and audit events are queued locally and sync successfully within 60 seconds after connectivity is restored And no raw SSID lists or beacon frames are persisted beyond what is required for the cached map; any ephemeral scans are discarded after resolution
Privacy and Low‑Power Operation Constraints
Given the privacy-preserving requirement to avoid continuous tracking When the app is used during a caregiver’s shift Then GPS is never accessed; only BLE and passive Wi‑Fi scans are used And scan cadence is event-driven: on app foreground/resume, on shift start, on significant-motion events, and at most once every 10 minutes while foregrounded (2-second scan window) And the incremental battery impact attributable to detection is ≤3% over an 8-hour reference shift on supported devices (95% CI ±1%) And no per-room coordinates are stored; only resolved unit IDs and aggregated signal quality metrics are retained, with ephemeral raw signal data purged within 24 hours
RoleSmart Assignment Engine
"As a caregiver, I want my role and unit to be auto-assigned using my badge, schedule, and location so that I have the right permissions with zero extra taps."
Description

Implement a deterministic rules engine that fuses badge identity, schedule data, and current location to auto-assign a time-bounded role and unit, re-evaluates on state changes (location shift, schedule update, session timeout), and applies precedence policies to prevent permission mistakes without requiring extra taps.

Acceptance Criteria
Auto-Assign on Badge Tap at Shift Start
Given a valid staff badge is tapped on a device within a geofenced unit and a matching schedule entry exists for the current time When authentication succeeds Then the engine assigns the scheduled role and the detected unit within 2 seconds And the permission set matches the configured template for the assigned role And the assignment is created without any manual role or unit selection by the user And the assignment end time is set to the schedule end time
Precedence Policy Resolution for Conflicting Signals
Given a valid badge identity, a current schedule entry, and a detected device location When schedule and location indicate different units Then if the staff is marked as floater the detected unit is assigned And if the staff is not floater the scheduled unit is assigned And if location is unknown the scheduled unit is assigned And if no schedule exists access is denied and no role or unit is assigned And no manual selection UI is presented
Re-Evaluation on Unit Location Change (Geofence)
Given an active assignment and the staff is marked as floater When the device crosses into a different unit geofence and remains for at least 15 seconds Then the assigned unit updates to the new unit within 5 seconds without user input And the permission set updates to reflect the new unit scope And unit thrashing is prevented by not reassigning more than once per 60 seconds unless the schedule changes
Re-Evaluation on Schedule Change Mid-Shift
Given an active assignment for a staff member When the schedule system updates the staff role or unit for the current time window Then the engine applies the new role and unit within 30 seconds of receiving the update And any permission reductions take effect immediately And any permission increases take effect without requiring user input And the change is applied without requiring a new badge tap
Session Timeout Clears Assignment and Requires Re-Auth
Given an active assignment and no user interaction for 5 minutes When the session timeout elapses Then the assignment is cleared and all protected actions are blocked And the next access requires a badge tap to reassign role and unit And no residual permissions remain after timeout
Assignment Time-Bounding to Scheduled Window
Given a staff member is assigned a role and unit based on a schedule entry When the scheduled end time is reached Then the assignment automatically expires within 5 seconds And access to role-scoped functions is blocked until re-authentication And if the schedule is extended the assignment end time updates within 30 seconds of the change
Audit Logging and Explainability of Assignment Decisions
Given any assignment creation, update, expiration, or denial event When the event occurs Then an audit record is written containing timestamp, device identifier, pseudonymized badge identifier, schedule identifier and version, detected unit, applied precedence path, resulting role and unit, and decision latency in milliseconds And 100 percent of events produce an audit record And audit records are retrievable and filterable by badge, unit, and time range
One‑Tap Sign‑on & Confirmation UI
"As a caregiver, I want a one-tap confirmation screen so that I can quickly verify or correct my assignment at shift start."
Description

Provide a frictionless, accessible screen that displays detected role and unit immediately after badge read, with a single-tap confirm, a guarded optional override flow requiring a reason, clear timers for session duration, and haptic/visual feedback optimized for tech-light use and shared devices.

Acceptance Criteria
Immediate Role/Unit Display After Badge Tap
Given a valid staff badge is tapped on an online device When the badge UID is read and schedule/location data is retrieved Then the detected Role and Unit are displayed within 800 ms And a loading skeleton appears within 100 ms until data resolves And the caregiver display name and initials avatar are shown And no manual role/unit picker is visible by default
Single‑Tap Confirmation Navigates to Home
Given the detected Role and Unit are shown When the user taps the Confirm button Then the button provides haptic feedback within 50 ms And the session is created and stored securely within 400 ms And navigation transitions to the app home within 600 ms total And the Confirm button is disabled and shows a spinner during processing And the action is idempotent; repeated taps do not create multiple sessions
Guarded Override Requires Reason and Logs Audit
Given the detected Role and Unit are shown When the user selects Override Then a modal requires choosing an allowed Role/Unit per policy And a reason is mandatory via predefined list or free text of at least 10 characters And the Confirm control remains disabled until both fields are valid And upon confirmation, an audit entry is written containing userId, deviceId, previousRole, previousUnit, newRole, newUnit, reason, timestamp (ISO 8601), and device location (geohash) And if the requested Role/Unit exceeds the user’s permission cohort, the change is blocked and a compliant error is shown; no changes are persisted
Session Timer Visibility and Auto Sign‑Out
Given a session has started When the user is on any app screen Then a persistent timer badge shows remaining session time in mm:ss with 1‑second updates And at 2:00 remaining the timer turns amber and a non-blocking warning banner appears And at 0:30 remaining a subtle repeating haptic occurs every 10 seconds And at 0:00 the user is signed out, local tokens are cleared, and the device returns to the badge screen within 800 ms
Haptic and Visual Feedback for Success and Errors
Given sign‑on and override flows When sign‑in succeeds Then a success toast with a check icon appears for 1.5 s and a medium haptic is produced When an error occurs (e.g., unreadable badge, network failure, mapping conflict) Then an inline error in red with a plain‑language message ≤120 characters is shown And an error haptic is produced if supported And the message is exposed to assistive tech via ARIA role="alert"
Shared Device: Concurrent Badge Taps and Privacy
Given the device is at the badge sign‑on screen When two badges are tapped within 5 seconds Then only the most recent badge read is retained and the prior detection is dismissed with a brief notice And any unconfirmed detected Role/Unit auto‑clears to the idle screen after 30 seconds of inactivity And no personally identifying information remains visible after auto‑clear
Accessibility and Touch Target Compliance
Given the sign‑on and confirmation UI Then all interactive controls have a minimum 44×44 pt hit area And text contrast meets WCAG 2.1 AA (≥4.5:1 normal text; ≥3:1 large text) And focus order follows visual order; initial focus moves to the role/unit summary on detection And screen readers announce “Detected [Role] in [Unit]. Confirm?” upon detection And Dynamic Type up to 200% is supported without truncation or overlap
Audit & Compliance Logging
"As a compliance officer, I want detailed logs of role assignments and overrides so that I can demonstrate compliance and investigate issues."
Description

Capture an append-only audit trail of every assignment decision and override, including inputs (badge ID token, schedule version, location signal), rule outcomes, timestamps, device ID, and user attribution, with secure retention, export (CSV/JSON), and admin search to meet HIPAA and facility compliance requirements.

Acceptance Criteria
Append-Only Audit Trail Enforcement
Given a valid auto or manual role/unit assignment event occurs When the system persists the audit entry Then the entry is appended and assigned an immutable content_hash And any PUT/PATCH/DELETE request to modify the entry returns 405 Method Not Allowed and creates a mutation_attempt audit entry And subsequent GET by entry_id returns the identical content_hash for the life of the entry And the system’s verify endpoint for the last 1000 entries returns verified=true
Required Fields Captured for Each Assignment Event
Given any role/unit assignment decision is made (auto or manual) When the audit entry is written Then the entry contains non-null fields: event_id (UUIDv4), event_type (assignment|override), badge_token_hash, schedule_version_id, device_id, user_id, timestamp (ISO 8601 UTC, ms precision), schema_version, rule_outcome {role, unit, rule_id} And the entry includes location_signal {type ∈ [BLE,GPS,WiFi,Unknown], raw_value, accuracy_m nullable} And if any input value is unavailable, missing_inputs lists the field names while required fields remain present And if the audit write fails schema validation, the assignment is blocked and the user sees “Audit logging unavailable—please retry”
Manual Override Events Fully Logged
Given a user initiates a manual override of a computed role/unit When the override is confirmed Then two audit entries exist linked by correlation_id: the computed outcome and the override outcome And the override entry includes override=true, previous_outcome, new_outcome, reason (min 3 chars), operator_user_id, and approver_user_id if policy requires approval And both entries have ordered timestamps and are discoverable by correlation_id And searches filtering override=true return the override entry
Admin Search and Filtering of Audit Logs
Given an Admin or Compliance role is authenticated with MFA When they search audit logs using any combination of filters: date_range, badge_token_hash, user_id, device_id, unit, role, event_type, rule_id, override flag Then results return within 2 seconds for up to 10,000 matching records and are sorted by timestamp desc And results are paginated with total_count available And each search action is itself logged as an audit access event And non-privileged users receive 403 Forbidden
CSV/JSON Export with Integrity and Access Controls
Given a filtered audit result set of up to 1,000,000 rows When an Admin or Compliance user requests an export Then the system produces downloadable CSV and JSON exports with header/metadata including schema_version and export_timestamp (UTC) And the exported row count equals the reported total_count And a SHA-256 checksum file is provided; the download link expires within 1 hour And export attempts by unauthorized users return 403 and are audited
Retention, Encryption, and Access Security
Given the system retention policy is configured When entries exceed the retention window Then a retention job removes entries and writes a tombstone audit entry with counts and time range removed And audit data is encrypted at rest (AES-256) and in transit (TLS 1.2+) And only Admin/Compliance roles can view or export audit data; access requires MFA And backup and recovery objectives are met (RPO <= 24h, RTO <= 4h for audit data)
Write Reliability and Performance Boundaries
Given an assignment event is being processed When the system attempts to write the audit entry Then the assignment is only applied after the audit write is durably acknowledged And 95th percentile audit write latency is <= 200 ms and 99th percentile <= 300 ms under expected load And on write failure, the system retries 3 times with exponential backoff; after final failure the assignment is aborted and the user sees a clear error message And a real-time alert is sent to on-call when failure rate exceeds 1% over 5 minutes
Admin Policy Controls & Overrides
"As an administrator, I want to set policy rules and approve exceptions so that access stays accurate while accommodating real-world changes."
Description

Offer an admin console to configure rule precedence, unit/role catalogs, allowed override conditions, after-hours access windows, and temporary break-glass permissions with approval workflows and notifications, enabling governance while accommodating real-world staffing changes.

Acceptance Criteria
Configure Rule Precedence for RoleSmart Mapping
Given I am an admin with Policy Controls permission, When I reorder the precedence of identity sources (badge, schedule, device location) and select Save & Publish, Then the new precedence is versioned and becomes active across all devices within 60 seconds. Given a caregiver’s badge, schedule, and device location map to different units, When the caregiver starts a session, Then the assigned role and unit follow the configured precedence and display in the session header. Given a precedence configuration that would yield no resolvable unit, When I attempt to publish, Then publication is blocked and a validation error identifies the conflicting rules and required corrections. Given a previously published precedence version, When I select Rollback, Then the prior version becomes active within 60 seconds and an audit entry records who rolled back, when, and why.
Manage Role and Unit Catalogs
Given I create a new role or unit with required fields, When I save, Then it appears in the catalogs and is selectable in mapping and override rules within 30 seconds. Given a role or unit is in active use, When I attempt to deactivate it, Then the system prevents deactivation and lists dependent users, schedules, and rules with deep links to resolve. Given I edit a role or unit’s display name, When I save, Then all references update without breaking existing mappings and an audit record captures before/after values and editor identity. Given I click Export Catalog, When the export completes, Then a CSV downloads containing id, name, status, created_at, updated_at, and reference counts.
Define Allowed Override Conditions
Given I configure allowed override pairs (from-role → to-role) with max duration and required justification, When a caregiver initiates an override, Then only allowed target roles are selectable, justification text is mandatory, and duration cannot exceed the configured maximum. Given an override requires approval, When the request is submitted, Then no access change occurs until at least one approver approves, and the decision is recorded with approver identity and timestamp. Given an override is active, When its duration expires or an approver revokes it, Then the caregiver’s access reverts automatically and the caregiver receives an in-app notification within 30 seconds. Given overrides are disabled for a unit, When a caregiver attempts to request an override, Then the request action is unavailable and a policy message explains why.
Configure After-Hours Access Windows
Given I define after-hours windows by unit and role, When the current time is outside the allowed window, Then non-emergency access attempts are blocked or routed to the override flow according to policy, with a visible banner explaining the restriction. Given quiet-hours are configured, When an after-hours policy is triggered, Then notifications honor quiet-hours settings except for break-glass events which always notify approvers. Given a daylight savings or time zone change occurs, When the system crosses the change, Then after-hours windows apply correctly using the unit’s time zone without allowing unintended access. Given after-hours rules are changed and published, When publication completes, Then the new windows take effect within 60 seconds and the change is logged in the audit trail.
Temporary Break-Glass Permissions with Approval Workflow
Given break-glass is enabled for a unit, When a caregiver initiates break-glass, Then they must select a reason from a configured list and may add free-text notes before submitting. Given break-glass mode is set to pre-approval, When the request is submitted, Then access is not granted until an approver approves in the console or app; if denied, access is not granted and the caregiver sees the denial reason. Given break-glass mode is set to immediate grant, When the request is submitted, Then access is granted instantly for the configured duration, the session is labeled “Break-Glass”, and all approvers are notified. Given a break-glass session is active, When the configured duration elapses or an approver revokes it, Then elevated access terminates within 30 seconds and the caregiver is reverted to baseline permissions.
Notifications and Audit Trail for Policy Events
Given I am a configured approver, When an override or break-glass request is submitted, Then I receive a notification via the configured channels (push/email/SMS) within 15 seconds containing requester, unit, role, reason, and approve/deny actions. Given a request notification is not acknowledged within 2 minutes, When escalation rules exist, Then the request escalates to the next approver tier and a new notification is sent and logged. Given any policy change, override submission, approval/denial, grant/revoke, or break-glass action occurs, When it is completed, Then an immutable audit record is stored with timestamp, actor, device ID, location, before/after state, justification, and related request IDs, and is exportable as CSV. Given I filter the audit log by date range, unit, actor, or event type, When I apply filters, Then results return within 3 seconds for datasets up to 10,000 records.

TapSwitch

Instantly swaps the active user on a shared device with a new badge tap, parking any drafts and restoring the next user’s context. Stops stray logins during shift handoffs and keeps rounds moving with zero password friction.

Requirements

NFC Badge Tap Authentication Switch
"As a caregiver on a shared tablet, I want to switch to my account with a badge tap so that I can start charting immediately without typing passwords during busy rounds."
Description

Enable instant user switching on shared devices via NFC badge tap. The app listens for a badge-present event, validates the badge against a secure directory, and swaps the active session with no password entry. On recognition, it gracefully terminates the prior session (revoking tokens, clearing in-memory data, and sanitizing UI state) and activates the next user’s profile. Supports common NFC badge standards and provides configurable fallbacks (QR scan or PIN) when NFC is unavailable. Integrates with MDM for provisioning badge mappings and keys. Benefits include eliminating password friction at handoffs, reducing stray logins, and accelerating rounds while maintaining security and compliance.

Acceptance Criteria
Instant NFC Tap User Switch (Foreground)
- Given the device is unlocked and KinLoop is in the foreground with an active session, When a provisioned NFC badge is tapped, Then the current session is terminated and the next user’s session is activated without password entry within 1.5 seconds. - And a success haptic and visual banner confirm the switch within 100 ms of activation. - And an audit log entry records timestamp, device ID, outgoing user ID, incoming user ID, badge ID hash, and outcome.
Prior Session Termination and PHI Sanitization
- Given a user switch is initiated, When termination begins, Then all access tokens for the outgoing user are revoked with the auth server within 500 ms and local refresh tokens are deleted. - And in-memory caches and clipboard are cleared, and the UI is sanitized (no resident data visible) within 300 ms of switch start. - And background tasks tied to the outgoing user are canceled or re-scoped per policy before the incoming session is activated. - And attempts to navigate back reveal no data from the prior user.
Draft Parking and Context Restoration
- Given the outgoing user has in-progress drafts (notes, photos, voice-to-text), When a switch occurs, Then drafts are auto-saved to the outgoing user’s account as “Parked” with timestamp and device ID within 400 ms. - And the incoming user’s last-known context (filters, resident selection, navigation tab) is restored within 1 second of activation. - And no content authored by the outgoing user is visible to the incoming user. - And when the outgoing user returns within 24 hours on any device, their parked drafts are restored to edit state within 2 seconds of login.
Unknown or Unprovisioned Badge Handling
- Given an NFC badge is tapped that is not mapped to a user, When validation occurs, Then no session switch happens and a non-PHI error is shown within 1 second. - And after 3 consecutive unknown taps within 60 seconds, Then a soft lock imposes a 30-second cooldown and an audit event is recorded. - And users are offered the configured fallback methods without revealing sensitive details.
NFC Unavailable: Fallback to QR or PIN
- Given NFC hardware is off, unavailable, or directory validation times out after 2 seconds, When a user attempts to switch, Then the app prompts for fallback options: QR scan or PIN. - And QR scan completes within 3 seconds end-to-end and maps to a provisioned user; PIN entry supports 4–8 digits with rate limiting (max 5 attempts, 30-second cooldown), with no resident data displayed until authenticated. - And all switch security and logging behaviors mirror the NFC flow.
MDM Provisioning and Badge-Key Sync
- Given the device is enrolled in MDM, When badge-user mappings or cryptographic keys are updated in MDM, Then the app fetches and applies updates within 15 minutes or on next app launch, whichever is sooner. - And keys are stored in the platform secure keystore with hardware-backed protection and are never logged. - And stale mappings beyond 24 hours are flagged; switching uses last-known good cache only if signatures are valid, otherwise blocked with an admin notice. - And MDM-initiated remote wipe immediately invalidates locally cached mappings and keys.
Multi-standard Badge Support and Performance
- Given a supported badge is presented (ISO/IEC 14443 A/B or NFC-F/FeliCa), When tapped, Then the badge UID or cryptographic payload is read and validated per the configured profile. - And the end-to-end switch completes within 1.5 seconds for the 95th percentile and within 2.5 seconds worst-case under normal network conditions. - And if two badges are tapped within 1 second, Then the second tap is ignored until the first switch completes, with user feedback. - And the feature is disabled when device attestation fails or the device is rooted/jailbroken.
Session Handoff & Draft Parking
"As a caregiver, I want my unfinished updates to be saved as drafts when someone else taps in so that I don’t lose work and my notes remain private to me."
Description

Automatically park any in-progress notes, photos, or voice-to-text transcriptions under the outgoing user’s drafts when a switch occurs, ensuring no work is lost and no data leaks between users. Drafts are time-stamped, resident-linked, and visible only to their author. The handoff process is atomic and resilient to app closures or low connectivity, with clear UI cues indicating that the prior user’s drafts were saved. This preserves continuity, reduces rework, and prevents cross-user exposure of sensitive content.

Acceptance Criteria
TapSwitch Parks In-Progress Content
Given an outgoing user has in-progress items (a typed note, a photo capture pending save, and an active voice-to-text transcription) for a specific resident When a new caregiver taps their badge to initiate TapSwitch Then the app terminates the outgoing session within 1 second of the tap And all in-progress items are parked as drafts under the outgoing user's account And the number of parked drafts equals the number of in-progress items (1:1) And each draft is linked to the correct resident And each draft stores a created-at timestamp within 2 seconds of the switch event And no in-progress content remains visible in the incoming user's session
Draft Privacy and Access Control
Given User A's drafts exist on the device When User B becomes the active user via TapSwitch Then User B cannot view, search, open, edit, or receive notifications for User A's drafts in any screen or API And any direct access attempt to a User A draft returns an authorization error and is not rendered And User A's drafts do not appear in User B's local caches, recent lists, or attachments pickers
Atomic Handoff on App Closure
Given User A has at least one in-progress item and a TapSwitch is initiated And the app is force-closed or the device loses power during the handoff When the app restarts and either User A or User B authenticates Then all User A in-progress items reappear as drafts for User A with no duplicates and no partial saves And zero User A content is visible to User B And the handoff is recorded once with outcome "parked" and a single switch timestamp And no orphan temporary media files remain on the device
Offline Switch and Sync Recovery
Given the device has no network connectivity when TapSwitch occurs with in-progress items for User A When connectivity is restored Then all drafts created locally for User A sync to the server within 60 seconds of stable connectivity And the server records the original switch timestamp, not the sync time And no duplicate drafts are created after retries And drafts remain invisible to any user other than User A until sync completes
UI Confirmation of Saved Drafts
Given a TapSwitch completes When the incoming user session loads Then a non-intrusive banner states that the previous user's drafts were saved with a count (e.g., "3 drafts saved") within 2 seconds And the banner auto-dismisses after 5-10 seconds and is accessible in a notifications/history view And when the prior user next authenticates, they see a drafts count badge matching the number parked during the handoff
Draft Metadata Completeness
Given drafts are created by TapSwitch When viewing draft metadata via UI or API Then each draft includes: author userId, residentId, contentType (note|photo|transcription), status "Draft", createdAt (UTC), source "TapSwitch", and deviceId And createdAt is stored in UTC and displayed in the facility's local timezone in the UI And saving a draft without residentId, author userId, or createdAt is rejected and logged
Next User Context Restore Without Leakage
Given User B had an active context before their last logout (e.g., resident detail screen) When User B becomes active via TapSwitch after User A Then User B's last context is restored within 1 second And no compose fields are prefilled with User A's content And app-level clipboard, attachment buffers, and in-memory caches from User A are cleared before User B's UI renders
Context Restore & Task Resume
"As a caregiver, I want my previous filters and next task to load automatically after I tap in so that I can continue where I left off without hunting through menus."
Description

On successful tap-in, restore the incoming user’s last working context, including resident filters, unit assignments, camera mode, and open task lists. Provide a prominent Resume Last Task action that jumps directly to the next assigned resident or the user’s last draft. Integrates with assignments and scheduling services to preload context and reduce navigation. This shortens time-to-first-action and keeps rounds moving efficiently.

Acceptance Criteria
Tap-In Restores Last Working Context
Given a shared device is on the KinLoop TapSwitch screen and User B has a saved context (resident filters, unit assignments, camera mode, and open task lists) When User B successfully tap-authenticates Then the app switches to User B and renders the home screen with User B’s context restored within 2 seconds p95 and 4 seconds max And the resident filters, unit assignments, camera mode, and open task lists match User B’s last persisted values And any UI state from the previous user is cleared (no residual filters, camera session, or open tasks from User A) And a non-blocking confirmation banner "Context restored" is displayed for 2 seconds
Resume Last Task Directs to Next Work Item
Given User B’s context is restored after tap-in And a "Resume Last Task" primary action is visible without scrolling on the landing view When User B taps "Resume Last Task" Then if User B has at least one saved draft, the most recent draft opens in edit mode in under 2 seconds And if no draft exists, navigation opens the next assigned resident’s next due task per assignment ordering rules And the target resident and task match scheduling service data as of the last successful sync And accessibility: the action is focusable, has label "Resume Last Task", and supports screen readers
Drafts Are Parked and Isolated Across Users
Given User A has one or more in-progress drafts and ends their session by tap-out or inactivity timeout When User B tap-authenticates Then User A’s drafts remain saved under User A and are not visible, searchable, or openable by User B And any active camera or media session from User A is terminated before User B’s context loads And opening "My Drafts" under User B displays only drafts authored by User B And system audit log records the isolation event with user IDs and timestamps
Assignments and Scheduling Preload
Given the assignments/scheduling service has shift assignments for User B When User B tap-authenticates during an active shift Then the assigned units and residents are preloaded and reflected in filters and task lists within 3 seconds p95 And the "Resume Last Task" destination is computed from the preloaded assignments using business rules (priority: overdue tasks, then due-soon, then alphabetical resident) And if the service is unreachable, the app uses the last cached assignments and flags data freshness with a timestamp badge And no blocking spinner exceeds 1 second; content loads progressively
Time-to-First-Action (TTFA) Performance
Given a cold start or warm start When a valid tap-in occurs Then Time-to-First-Action (tap-in success to "Resume Last Task" tappable) is ≤ 2.0 seconds at p95 and ≤ 3.5 seconds max on supported hardware And performance telemetry events (tap_in_success, context_restored, ttfa_ms) are emitted with correlation IDs And if thresholds are exceeded, a non-fatal perf warning is logged; user flow is not blocked
Offline and Intermittent Connectivity Behavior
Given the device is offline or latency > 2 seconds to the scheduling service When User B tap-authenticates Then context restores from the last local snapshot for User B with a "Working offline" banner And "Resume Last Task" uses cached assignments; if none exist, it opens User B’s most recent draft or shows a guided empty state And when connectivity is restored, background sync updates assignments without interrupting the current screen; a discreet "Assignments updated" toast offers an optional refresh
Auto-Lock, Idle Timeout, and Proximity Lock
"As an administrator, I want devices to auto-lock quickly when unattended so that resident information isn’t exposed between users."
Description

Apply a configurable idle timeout that auto-locks the app and requires a badge tap to re-enter. Optionally use device sensors (e.g., accelerometer/proximity) to trigger immediate lock when the device is put down or pocketed. Admins can set policy by facility or unit. This prevents unattended access and stray logins during shift handoffs, maintaining privacy and compliance without adding password friction.

Acceptance Criteria
Idle Timeout Auto-Lock After Inactivity
Given an active KinLoop session on a shared device and facility policy sets idleTimeout to 120 seconds When there is no foreground user interaction for 120 consecutive seconds Then the app auto-locks within 1 second of the timeout And the lock screen shows only a badge-tap prompt with no PHI visible And any in-progress edits are parked as a draft tagged to the originating user
Re-entry by Badge Tap Only After Auto-Lock
Given the app is locked due to idle timeout When a user taps a valid badge Then re-entry completes within 2 seconds of a successful badge read And no password prompt is shown And the user’s last-known context (permissions, unit, resident list) is restored And if the badge belongs to a different user, the previous user’s session remains ended and their drafts remain inaccessible to the new user
Immediate Proximity/Put-Down Lock Using Device Sensors
Given facility policy enables proximityLock=true with proximityThreshold=2 seconds And a user session is active When the device is placed face-down or the proximity sensor is continuously covered for at least 2 seconds or the device becomes stationary for at least 2 seconds after motion as detected by the accelerometer Then the app locks within 1 second And the lock reason is recorded as proximityLock And re-entry requires a badge tap
Admin Policy Configuration by Facility and Unit
Given an authenticated Facility Admin is in the Admin Console When they configure idleTimeout to a value between 30 and 600 seconds inclusive (default 120), toggle proximityLock on/off, set proximityThreshold between 1 and 5 seconds inclusive, and apply scope to Facility or specific Units Then the policy saves with version, author, timestamp, and scope And Unit-level policies override Facility-level policies when both exist And the policy propagates to all devices in scope within 5 minutes And devices out of scope are unchanged And the UI prevents saving values outside allowed ranges And an audit log entry records old and new values
Draft Parking and Restoration on Lock/Re-Entry
Given a user is composing a photo or voice-to-text update When the app locks due to idle timeout or proximity lock Then the draft is saved with timestamp, author, resident context, and attachments And upon re-entry by the same user within 24 hours, the draft is restored automatically And upon re-entry by a different user, the draft is not visible and remains in the originating user’s drafts And media captured before lock is retained without data loss
Shift Handoff Stray Login Prevention with TapSwitch
Given User A’s session is active on a shared device When the device locks (by timeout or proximity) and User B taps their badge, or when User B taps their badge while User A is active Then User A’s session ends and protected content is hidden before User B’s context loads And no actions can be performed under User A’s identity after the lock/switch trigger And the handoff completes within 3 seconds end-to-end And an audit event records fromUser, toUser, reason, timestamp, and deviceId
Offline TapSwitch with Secure Queueing
"As a caregiver in a dead-zone, I want to tap in and keep working offline so that my rounds aren’t delayed by poor Wi‑Fi."
Description

Allow TapSwitch to function without network connectivity by using a cached, time-bounded allowlist for badge verification and encrypting minimal session metadata with device keys. Queue audit logs and state changes for reliable, ordered sync when the network returns. Draft parking and context restore must work offline with conflict detection on reconnection. This ensures uninterrupted rounds in low-connectivity environments while preserving security and data integrity.

Acceptance Criteria
Offline Badge Tap Switch Success
Given the device is offline and has a cached allowlist refreshed within the last 24 hours and User B's badge ID is on it And User A is currently active with unsent drafts open When User B taps their badge Then the app ends User A's session, parks all of User A's drafts with timestamps and IDs And sets User B as the active user with their last known context restored locally within 1 second And displays an offline indicator and a "Switch complete" confirmation within 2 seconds
Allowlist Staleness and Deny Handling
Given the device is offline and the cached allowlist is older than 24 hours or missing the tapped badge ID When a badge is tapped Then the switch is blocked and no session change occurs And the user sees "Network needed to verify badge" within 2 seconds And an offline denial audit event is queued with reason stale_cache or badge_not_found
Local Encryption of Session Metadata and Drafts
Given the device is offline When session metadata, parked drafts, and the offline queue are written to storage Then they are encrypted at rest using device-bound, hardware-backed keys and never written in plaintext And if device keys are invalidated (e.g., OS reset, MDM wipe), the data becomes irrecoverable and is purged on next app start And attempting to access the stored data from another device instance fails decryption
Reliable Ordered Sync on Reconnection
Given the device has queued audit logs and state changes with client-generated UUIDs and per-device sequence numbers And network connectivity is restored When sync begins Then events are transmitted in sequence order per device and acknowledged by the server And the client retries unacknowledged batches with exponential backoff up to 10 minutes without reordering And duplicate submissions are ignored server-side via idempotency keys And on partial failure, processing resumes from the last acknowledged sequence number And the UI shows "Sync complete" with total sent count when finished
Offline Draft Parking and Context Restore Integrity
Given User A has in-progress drafts (notes, photos, voice-to-text) while offline When a TapSwitch occurs to User B Then all of User A's drafts are parked with links to the correct resident/context and a local version ID And no draft data is visible to User B And when User A reauthenticates later (online or offline), their drafts are restored to edit state within 2 seconds
Conflict Detection on Reconnect
Given a draft was edited offline by User A and the same record was modified by another user while User A was offline When the device reconnects and attempts to sync the offline changes Then the client detects the conflict by comparing version IDs or timestamps And marks the draft as "Needs review" without overwriting the server version And presents a non-destructive resolution (diff or duplicated version) for user action And queues an audit event recording the conflict detection and chosen resolution
Queue Capacity and Offline Operation Limits
Given the device is offline and continues operations When the offline queue reaches 1,000 events or 500 MB of stored drafts, whichever occurs first Then the app warns the user that storage is nearly full And prevents additional TapSwitches and draft captures that would exceed limits to avoid data loss And never drops queued audit logs or drafts without explicit user confirmation And resumes normal operation automatically after successful sync frees space
Switch Event Audit Trail & Admin Controls
"As an administrator, I want a searchable log of user switches so that I can audit access and investigate incidents without exposing resident data."
Description

Capture immutable logs for every switch event, including anonymized user identifiers, device ID, timestamps, location (if permitted), trigger source (tap, timeout, manual), prior session duration, and count of drafts parked. Provide an admin console with filters, exports, retention policies, and anomaly alerts (e.g., rapid repeated switches). Logs exclude PHI and support compliance reviews and operational insights without compromising privacy.

Acceptance Criteria
Immutable Switch Event Logging
- Given a shared device with TapSwitch enabled and network connectivity When a user switch is initiated by tap Then an append-only log entry is created with fields: anon_user_id, device_id, timestamp_utc, trigger_source=tap, prior_session_duration_seconds, drafts_parked_count, location (only if permitted) - Given the device is offline When a switch occurs Then the log entry is written to the local append-only store within 200 ms and synced to the server within 5 seconds of connectivity restoration without loss or duplication - Given any stored switch event When an admin or system attempts to modify or delete the entry Then the system rejects the change and exposes a tamper-evident hash chain where each entry’s hash validates against its predecessor - Given two switches occur in the same millisecond When persisted Then timestamps include millisecond precision and a monotonically increasing sequence to guarantee ordering - Given clock skew on the device When events sync to the server Then server-received time and device-provided time are both recorded, and server time is used for ordering
PHI-Free, Anonymized Log Content
- Given any switch log payload When inspected Then it contains no PHI, media contents, note text, resident names, or identifiers beyond the specified fields - Given a user identity When logged Then the value is a non-reversible anonymized identifier with no ability to recover the original identity from the log alone - Given location permission is disabled by org policy or device OS When a switch is logged Then location fields are null and the entry explicitly records location_collected=false - Given location permission is enabled When a switch is logged Then location includes latitude, longitude, accuracy_meters, and method, and excludes any building/floor inference - Given drafts are parked When logging occurs Then only the drafts_parked_count is recorded and no draft contents, titles, or tags are persisted in the log
Admin Console Filtering & Search
- Given an admin is on the audit console When filtering by date/time range, device_id, anon_user_id, trigger_source, presence_of_location, and min/max drafts_parked_count Then the result set updates within 1 second for up to 100k events - Given a result set exceeds 10,000 rows When displayed Then pagination is available with page size controls (25/50/100) and accurate total count - Given filters are applied When the admin refreshes or shares the URL Then filter state is preserved via query parameters - Given an admin enters a partial device_id or user_id prefix When searching Then matching results are returned using prefix search within 1 second
Compliance Exports (CSV/JSON)
- Given a filtered result set ≤ 1,000,000 rows When an export is requested in CSV or JSON Then a downloadable, UTF-8 encoded file is generated with a header and exactly the filtered records in server-time order - Given an export is requested When generated Then all fields include: anon_user_id, device_id, timestamp_utc, server_received_timestamp_utc, trigger_source, prior_session_duration_seconds, drafts_parked_count, location_lat, location_lon, location_accuracy_m, location_method, location_collected, event_seq - Given an export job is running When monitored Then progress is shown and completes within 5 minutes for 1,000,000 rows, or surfaces a clear error with retry link - Given an export is produced When delivered Then the file is available via a signed URL that expires in 15 minutes and the export action is itself logged in the admin audit - Given timezones differ When viewed in CSV Then timestamps are normalized to UTC and the header row states "All timestamps UTC"
Retention Policies & Legal Hold
- Given a global retention policy in days is configured (e.g., 365) When the nightly retention job runs Then all events older than the policy are permanently purged from primary and replica stores while preserving hash-chain verifiability for remaining events - Given an org admin applies a legal hold to a date range or device_id When retention runs Then affected events are exempt from purge until the hold is removed and this exemption is logged - Given retention policy changes from 365 to 180 days When saved Then the new policy effective date/time is logged and future purges honor the new value without purging events that were previously under legal hold - Given a purge occurs When reviewed in the admin console Then a purge report shows counts purged by day and any failures with retry capability
Anomaly Alerts for Rapid Switches
- Given the default threshold is 5 switches per device within 2 minutes and alerts are enabled When the threshold is exceeded Then an anomaly alert is generated within 60 seconds containing device_id, time window, count, and sample events - Given repeated anomalies of the same type occur within 10 minutes When alerting Then alerts are de-duplicated into a single incident with incrementing occurrence count - Given an admin changes the threshold or window When saved Then the new settings take effect immediately and changes are logged with admin identity and timestamp - Given quiet hours are configured When anomalies occur within quiet hours Then alerts are suppressed or routed according to the configuration and the suppression is logged - Given an alert is generated When acknowledged in the console Then its status changes to Acknowledged and subsequent notifications stop for that incident
Role-Based Access & Audit of Admin Actions
- Given a user with Admin role When accessing the audit console Then the console loads and all controls are enabled; non-admin roles receive a 403 and no event metadata is leaked - Given an admin performs actions (view event details, export, change retention, change alert thresholds) When completed Then each action is recorded in an admin actions audit log with admin_id, action, parameters, timestamp, and outcome - Given SSO is configured with roles When a user signs in Then roles map to application permissions and access behaves as defined without local override - Given a terminated admin’s access is revoked in the identity provider When they attempt to access the console Then access is denied within 5 minutes of revocation - Given least-privilege is required When a Support role user accesses the console Then they can read events and export but cannot change retention or alert settings
Sub-Second Switch Performance SLA
"As a caregiver, I want the app to be ready almost instantly after I tap so that I can keep moving without delays during rounds."
Description

Set measurable performance targets for TapSwitch: 95th percentile time from badge tap to ready state ≤ 800 ms and 99th percentile ≤ 1.2 s. Implement lightweight session teardown, preloading of user context, and lazy-loading of non-critical components. Instrument telemetry and alerting for SLA breaches, and surface in admin reports. This ensures the experience remains instant under real-world load, preserving adoption and operational gains.

Acceptance Criteria
SLA P95/P99 from Tap to Ready
Given a shared device running KinLoop with TapSwitch enabled and a stable network connection And a warm app session with at least 100 successful switches in the measurement window When a caregiver taps a valid badge to switch users Then the elapsed time from NFC tap event timestamp to Ready state (user identity visible, input focus active, prior user's drafts parked) has P95 <= 800 ms and P99 <= 1200 ms across the window And fewer than 0.5% of switches exceed 1500 ms And the measurement is captured and written to telemetry with result=success
Load Resilience SLA
Given 20 shared devices at a site with background sync active and average device CPU < 70% And network RTT to the service <= 80 ms and packet loss < 1% When 200 user switches occur over 10 minutes (~20/min) distributed across devices Then P95 <= 800 ms and P99 <= 1200 ms for the site aggregate and for each device And switch failure rate <= 0.2% And no device exhibits sustained queueing delay > 100 ms at the badge scan service during the test
Draft Parking and Context Restore Overhead
Given User A has 1–3 in-progress drafts totaling <= 10 MB including attachments And User B is the next authenticated user on the device When User B taps to switch while User A's drafts are present Then User A's drafts are parked without data loss and User B's context is restored to their last-used screen And additional latency versus a baseline switch (no drafts) is <= 50 ms at median and <= 100 ms at P95 And no cross-user data is visible to User B at any point
Preloading and Lazy-Loading Critical Path
Given preloading of user context and lazy-loading of non-critical modules are enabled When a warm-path user switch occurs Then no network requests other than authentication/session handoff block the Ready state And non-critical modules begin loading only after the Ready state is reached And UI input remains responsive with 95th percentile first-interaction latency <= 100 ms for the first 5 seconds post-Ready
Telemetry Coverage and SLA Breach Alerting
Given the telemetry pipeline is operational When user switches occur on any device Then >= 99% of successful switches emit timing spans containing site_id, device_id, pseudonymous user_key, ready_state_ms, draft_count, cold_start_flag, and result And no PII (e.g., full names, raw badge IDs) is stored; badge identifiers are salted-hashed And rolling 5-minute windows (min 50 samples) compute P95 and P99 per site and per device And an alert is sent to on-call and the admin dashboard if P95 > 800 ms or P99 > 1200 ms for 3 consecutive windows
Admin Performance Reporting Visibility
Given an admin navigates to TapSwitch Performance Reports When selecting a site and a date range within the last 90 days Then the report displays per-day total switches, success rate, P50, P95, P99, max latency, and total breach minutes And the report uses the site's local timezone and can be exported to CSV And the report loads within 3 seconds for a 30-day range

BadgeGuard

One-tap “lost badge” lockdown from admin console with immediate revoke, alerts on attempted use, and a time-limited PIN/QR fallback. Reduces downtime and risk when badges go missing while preserving compliance for urgent access.

Requirements

One-Tap Badge Lockdown
"As a facility administrator, I want to lock down a lost badge with a single tap so that I can immediately reduce security risk and keep care operations moving."
Description

Provide a single-action control in the KinLoop admin console to mark a staff badge as "Lost" and instantly revoke its access across KinLoop sessions and connected access systems. The control should capture reason codes, the reporting source, timestamp, and affected staff member, then display a confirmation with the expected revocation window. The lockdown action must be resilient (idempotent), create a visible banner on the staff profile, and notify designated stakeholders (e.g., shift lead, security) within the app. This capability minimizes risk and downtime in assisted living environments by reducing the steps required to secure accounts and physical access when badges go missing.

Acceptance Criteria
Admin triggers one-tap badge lockdown
Given an admin with BadgeGuard permission is viewing the target staff profile in KinLoop Admin When the admin taps the Mark Badge as Lost control Then the system sets the staff badge state to Lost immediately And a confirmation is displayed showing the expected revocation window in seconds And the action captures reason code (from predefined list or default), reporting source (Admin Console), initiating admin ID, affected staff ID, and UTC timestamp And the control reflects Locked state to prevent repeat submissions until completion feedback is shown
Immediate revocation across KinLoop and connected systems
Given a badge is set to Lost When revocation is initiated Then all active KinLoop sessions for the staff member are terminated within 5 seconds And new authentication attempts using existing tokens are rejected immediately And revoke requests are sent to each connected access system within 5 seconds And the admin sees per-system status with an expected revocation window And systems that do not acknowledge within the window are shown as Pending with last attempt time
Idempotent lockdown with safe retries
Given the badge is already in Lost state When a duplicate lockdown request is received from UI or API Then no additional revocation calls are sent to connected systems And no duplicate stakeholder notifications are generated And the response includes the original event ID and timestamp indicating No-Op And the audit log contains a single lockdown event with subsequent retry attempts referenced
Profile banner communicates lost-badge status
Given the badge is in Lost state When any authorized user opens the staff profile in KinLoop Then a persistent banner is displayed at the top indicating Badge Locked (Lost) And the banner displays reason code and UTC timestamp And the banner links to the corresponding audit event And the banner is visible and accessible on both web and mobile layouts
Stakeholder notifications for lockdown event
Given shift lead and security are designated stakeholders for the staff's location When a badge is marked Lost Then in-app notifications are delivered to those stakeholders within 30 seconds And the notification includes staff name, reason code, reporting source, initiating admin, and timestamp And delivery failures are retried up to 3 times over 5 minutes And recipient acknowledgments are recorded in the audit log with timestamp and user
Alerts on attempted use of lost badge
Given a badge is in Lost state When an authentication attempt is made with that badge in KinLoop or a connected access system Then the attempt is blocked and access is denied And an alert event is recorded with time, source system or reader, and staff identifier And designated stakeholders receive an alert within 15 seconds And repeated attempts within 60 seconds are aggregated into a single alert with an attempts count
Time-limited PIN/QR fallback for urgent access
Given a badge is marked Lost and the admin selects Generate Fallback When a fallback PIN/QR is created Then the credential is valid only for a configurable duration between 5 and 60 minutes (default 20) And it grants least-privilege access defined by policy And it expires automatically at the end of its validity and cannot be reused And issuance, use, and expiration are recorded in the audit log And an admin can revoke the fallback early, taking effect immediately
Real-Time Revocation Propagation
"As a security officer, I want revocation to take effect across all systems within seconds so that a lost badge can’t be used anywhere on site or in KinLoop."
Description

Ensure badge revocation propagates within seconds to all relevant surfaces: KinLoop mobile/web sessions (force logout, token invalidation), API clients, and configured access control integrations. Support webhook- and polling-based connectors with retry/backoff, dead-letter queues, and out-of-order handling to guarantee eventual consistency. Display propagation status per integration (e.g., "Revoked at Door A: 12s") and alert if SLA is exceeded. Provide a fallback manual "Resend Revoke" action. This requirement guarantees that a lockdown effectively removes access everywhere, aligning with compliance and safety expectations.

Acceptance Criteria
Force Logout & Token Invalidation (KinLoop Sessions)
Given user U's badge is revoked at T0 from the admin console When U has active KinLoop mobile or web sessions Then all active sessions are terminated within 5 seconds of T0 And any subsequent request using prior session tokens returns HTTP 401 with error code "revoked_badge" And the client displays an "Access revoked" notice upon receiving the logout event And an audit entry records each terminated session with device ID and timestamp
API Client Access Token Revocation
Given third-party API clients hold OAuth2/OIDC access tokens for user U When U's badge is revoked at T0 Then token introspection for those tokens returns active=false within 5 seconds of T0 And any API call using those tokens after T0 returns HTTP 401 with error code "revoked_badge" and a trace ID And API gateway or cache respects a token validity TTL of ≤3 seconds And tokens for other users remain valid and unaffected
Webhook Connector Propagation with Retry/Backoff
Given a configured webhook integration W with endpoint E And E responds 2xx When U's badge is revoked at T0 Then a revoke payload (event_id, sequence, occurred_at) is POSTed to E within 10 seconds of T0 And delivery status records success with measured latency in seconds Given E returns 5xx or times out When the first delivery attempt fails Then the system retries with exponential backoff delays of 2s, 4s, 8s, 16s, 32s, 64s, 128s, 256s with ±10% jitter And each retry uses the same idempotency key (event_id) And after final failed attempt the event is placed in the dead-letter queue for W and status shows Failed—DLQ
Polling Connector Propagation and Ordering
Given a polling connector P calls GET /revocation-events?since=<watermark> every 30 seconds When U's badge is revoked at T0 Then the revoke event appears in the first poll window that includes T0 and no later than T0+45 seconds And the payload includes event_id, sequence, occurred_at and can be returned in overlapping polls without duplication at the consumer via idempotency keys And requesting with an earlier watermark returns the event exactly once And events remain retrievable for at least 24 hours after T0
Per-Integration Propagation Status UI
Given the admin views U's revocation detail after T0 When propagation is in progress Then a per-integration row displays state (Pending, Delivered, Failed), last update time, and latency in seconds since T0 And on success for integration "Door A" the UI displays "Revoked at Door A: <latency>s" And the status list auto-refreshes at least every 2 seconds without full page reload And timestamps are shown in the admin's local timezone with both absolute and relative times
SLA Breach Alerting
Given SLA thresholds: KinLoop sessions 5s, Webhooks 30s, Polling 60s When any integration has not confirmed revocation by its SLA threshold after T0 Then an alert is generated within 2 seconds of the breach to the configured channels and a console banner is displayed on the revocation detail And the per-integration row shows an "SLA exceeded" badge and retries continue where applicable And an audit log entry captures breach time, integration, attempt count, and last error
Manual Resend Revoke Fallback
Given an integration I shows Failed or has remained Pending for more than 15 seconds after T0 When an admin clicks "Resend Revoke" for I Then a new delivery attempt is enqueued within 2 seconds regardless of current backoff state And for webhook integrations the same event_id is reused and attempt_count increments by 1 And for polling integrations the event is marked visible for the next 5 minutes to ensure inclusion in the next poll And the UI reflects the new attempt immediately and logs the admin action with timestamp and admin user ID And "Resend Revoke" is rate-limited to one action per integration per 10 seconds
Attempted Use Alerting and Throttling
"As an on-call supervisor, I want real-time alerts on attempted use of a revoked badge so that I can respond quickly without being overwhelmed by duplicate notifications."
Description

Generate immediate alerts when a revoked badge is presented at a door, terminal, or within KinLoop authentication. Alerts should include time, location/device, staff identity, and outcome, and support push, SMS, and email with role-based routing and quiet hours. Implement intelligent throttling and aggregation to prevent alert storms (e.g., summarize multiple attempts within a time window). Provide acknowledgement and escalation workflows with audit of who responded and when. This equips teams to respond quickly to misuse while keeping noise manageable for on-call staff.

Acceptance Criteria
Immediate Alert on Revoked Badge at Door Reader
Given a badge is in revoked state And the badge is presented at a connected door reader with deviceId and location configured When the reader sends a denial event to BadgeGuard Then BadgeGuard generates an alert record within 2 seconds of event receipt And the alert payload includes timestamp (UTC, ISO 8601), deviceId, location, staffId, staffName, outcome="denied", reason="revoked" And the alert is routed to the Security On-Call role via push and SMS and to Facilities Admin via email according to routing rules And push notification is queued in-app immediately and SMS/email are handed off to providers within 5 seconds And the alert is visible in the admin console Alerts list within 3 seconds with status="Unacknowledged"
Revoked Badge Attempt at Terminal and KinLoop App Login
Given a staff member’s badge is revoked And the staff attempts to authenticate at a nurse-station terminal or within the KinLoop app When authentication is denied due to revoked status Then an alert is created per attempt with surfaceType = "terminal" or "app", and includes deviceId or appSessionId, location (if available), timestamp (UTC), staffId, staffName, outcome="denied" And routing follows the role map: Clinical On-Call via push, IT On-Call via email (configurable) And the alert reaches the intended channels within the same SLAs as door reader alerts
Role-Based Routing and Quiet Hours Enforcement
Given role-based routing is configured with role-to-channel mappings and active on-call assignees And organization quiet hours are configured (e.g., 22:00–06:00 local time) When an attempted use alert is generated during quiet hours Then BadgeGuard suppresses push and SMS for roles marked "suppress during quiet hours" and sends email only And BadgeGuard sends push/SMS for roles marked "override quiet hours" And if no active on-call assignee exists for a role, the alert falls back to the role’s default distribution list And all routing decisions and quiet-hours suppressions are recorded on the alert’s audit trail
Throttling and Aggregation of Repeated Attempts
Given a throttle window of 60 seconds and a summary threshold of 3 attempts are configured And a revoked badge is presented repeatedly at the same device within the window When the first attempt is received Then an immediate alert is sent and an incident is opened for the badge-device pair And subsequent attempts within the window do not generate new outbound alerts And the incident’s attemptCount and lastAttemptAt update within 2 seconds of each additional attempt And at window close, a summary update is sent with totalAttempts, firstAttemptAt, lastAttemptAt, deviceId, location, staffId And if attempts continue, a new window opens and summaries are sent at most once per window per badge-device pair
Acknowledgement and Escalation Workflow
Given an alert is Unacknowledged When a recipient taps "Acknowledge" in push, clicks the acknowledge link in email, or replies "ACK" by SMS within 120 seconds Then the alert status changes to Acknowledged and records acknowledgedBy (userId, role) and acknowledgedAt (UTC) And ownership of the incident is assigned to the acknowledger And further notifications for the same incident are suppressed for 10 minutes except for configured summaries And if no acknowledgement is received within 120 seconds, the alert escalates to the next role in the policy And if still unacknowledged 300 seconds after initial alert, the alert escalates to Facility Admin and severity is set to High And all acknowledgements and escalations are appended to the audit trail
Alert Audit Trail and Compliance Reporting
Given auditing is enabled by default When any alert is created, routed, acknowledged, escalated, suppressed, summarized, or closed Then an immutable audit entry is written with actionType, actor (system or userId), timestamp (UTC), channel, recipients, and payload checksum; include IP/device where applicable And audit entries are visible in the admin console within 5 seconds of the action and exportable to CSV within 1 minute And audit entries cannot be edited or deleted by non-Compliance Admin users; any modification attempts are logged as security events And audit data is retained for at least 7 years per policy
Time-Limited PIN/QR Emergency Access
"As a shift lead, I want to issue a temporary PIN/QR with strict limits so that staff can continue essential tasks without compromising security."
Description

Offer a secure fallback that generates a time-bound, scope-limited PIN and QR code tied to the affected staff member for emergency access when a badge is lost. Admins can configure duration, access scope (areas/features), and optional 2FA. Deliver credentials via secure in-app message or out-of-band channels with verification. Clearly display countdown timers and automatic expiry, and log every issuance and use. This preserves urgent access for care continuity while maintaining compliance and traceability.

Acceptance Criteria
Admin Configures Duration and Scope for Emergency Credentials
Given an admin selects a staff member with a reported lost badge And configures an emergency credential with a defined duration and specific access scope When the system generates the PIN and QR Then the credentials are valid only from issuance time until the configured expiry time And access attempts outside the configured scope are denied with reason code ACCESS_SCOPE_DENIED And access attempts after the expiry time are denied with reason code EXPIRED_CREDENTIAL And access attempts within the configured scope before expiry succeed
Secure Issuance Tied to Affected Staff Identity
Given an admin generates a time-limited PIN/QR for staff member S When the PIN or QR is presented for access Then the system associates the access session with staff member S’s identity and role And access is evaluated against S’s permissions and the configured emergency scope only And the credential cannot be reassigned to or used under a different staff identity
Optional Two-Factor Authentication (2FA) Enforcement on Use
Given an admin enables 2FA for the emergency credential issuance When the staff member enters the PIN or scans the QR Then the system requires a second factor as configured (e.g., OTP to a verified channel or authenticator approval) And access is denied with reason code SECOND_FACTOR_REQUIRED until the second factor is successfully completed And access is granted only after successful second-factor verification within the validity window
Secure Delivery via In-App and Out-of-Band with Verification
Given an admin chooses in-app delivery When the staff member receives the message Then viewing the PIN/QR requires authenticated app access for staff member S and acknowledgement And the message body does not display the full PIN/QR in push notifications or previews Given an admin chooses out-of-band delivery (SMS or email) When the message is sent Then the system verifies the destination belongs to staff member S before revealing the credentials (e.g., via verification link/code) And the full PIN/QR is only revealed after successful recipient verification And delivery and verification events are logged with timestamps and channels
Visible Countdown and Automatic Expiry
Given emergency credentials are issued When staff member S views the credentials in-app Then a countdown timer shows remaining validity to the second And when the countdown reaches zero, the UI marks the credentials as Expired and hides the PIN/QR And any terminal or feature guarded by the credentials rejects further use with reason code EXPIRED_CREDENTIAL And the server is the source of truth for expiry regardless of client clock skew
Comprehensive Audit Logging of Issuance and Use
Given emergency credentials are issued for staff member S Then the system records an issuance log including admin ID, staff ID, issuance timestamp, expiry timestamp, configured scope, delivery channel(s), and whether 2FA is required Given any attempt to use the credentials occurs Then the system logs an event with timestamp, staff ID, success/failure, reason code, resource/area accessed, device/location identifier when available, and remaining time at attempt And audit logs are available to admins with filter and export capabilities for issuance and use events
PIN/QR Security and Rate Limiting
Given emergency credentials are active When incorrect PINs are entered repeatedly or QR scans are invalid Then the system enforces organization-configured rate limiting (e.g., lockout per device/endpoint and per staff after threshold N within time window T) And blocked attempts during lockout are denied with reason code RATE_LIMITED and are logged And the QR token and PIN are unguessable (cryptographically random) and are not reused for the same staff within their active validity window
Role-Based Lockdown Permissions and Approvals
"As a compliance manager, I want lockdown and fallback issuance gated by roles and approvals so that security-sensitive actions meet our governance standards."
Description

Restrict the ability to initiate lockdowns and issue emergency credentials to specific roles (e.g., Facility Admin, Security Officer) with site-level policy controls. Support optional dual-approval for permanent deactivation or extended emergency access, capture justification notes, and enforce minimum/maximum fallback durations. Provide an audit-visible approver trail and deny reasons. This ensures BadgeGuard actions are controlled, transparent, and aligned with organizational governance.

Acceptance Criteria
Only Authorized Roles Can Initiate Lockdown
Given a signed-in user with role Facility Admin or Security Officer and site policy permits lockdown When they submit a lockdown on a badge Then the system accepts the request and returns a success reference ID and the badge status changes to Locked Given a signed-in user without a permitted role When they attempt to initiate a lockdown Then the action is blocked with 403 Forbidden and the UI displays "Insufficient permissions" and an audit entry records the denial reason Given an API call without valid authentication or required scope When a lockdown is attempted Then the request is rejected with 401 or 403 and no state change occurs
Dual-Approval Required for Permanent Deactivation
Given site policy has dual-approval enabled for permanent deactivation When a permitted requester submits a deactivation Then the request enters Pending Approval and cannot execute until two distinct approvers approve Given the first approver approves When a second eligible approver who is not the requester approves within the approval window Then the badge is permanently deactivated and both approvals are recorded with timestamps Given any approver denies When the request is still pending Then the request is closed as Denied with the deny reason captured and no deactivation occurs Given the approval window expires before second approval When the request is still pending Then the request auto-expires and must be resubmitted
Dual-Approval for Extended Emergency Access
Given site policy defines a threshold for extended emergency access When a requester issues an emergency fallback credential exceeding that threshold Then dual-approval is required before issuance Given both approvers approve within the approval window When the request is processed Then the credential is issued for the approved duration and becomes active at issuance time Given an approver denies or the window expires When the request is pending Then the credential is not issued and the denial or expiry is recorded in the audit trail Given the requested duration exceeds the site maximum When the requester submits the form Then submission is blocked with a validation error and no approval task is created
Emergency Fallback Duration Enforcement
Given site policy sets minimum and maximum fallback durations When issuing any emergency fallback Then the input enforces the range and blocks values outside with a clear validation message Given a fallback credential has been issued When its expiry time is reached Then the credential becomes invalid and any attempted use is rejected with reason "Expired" and logged Given site policy defines a default fallback duration When the issuance form loads Then the default duration is pre-populated to the policy default
Justification Notes Required for Sensitive Actions
Given site policy requires justification notes for permanent deactivation and extended emergency access When a requester submits such a request without notes of at least 10 characters Then submission is blocked with inline validation indicating notes are required Given a requester provides justification notes and submits When the request is created Then the notes are stored immutably and displayed to approvers and in the audit trail
Site-Level Policy Controls and Scope
Given a user with Site Owner permissions is in Policy Settings When they configure allowed roles, dual-approval settings, approval window, and default/min/max fallback durations and justification requirement Then the changes save successfully and take effect for that site only Given a user without Site Owner permissions When they attempt to modify policy settings Then access is denied and no changes are saved and the attempt is logged Given a tenant with multiple sites When policies differ between sites Then actions within each site adhere to that site's policy with no cross-site leakage
Audit Trail Visibility and Integrity
Given any BadgeGuard action or decision occurs (request, approval, denial, execution) When the event completes Then an audit record is created with actor identity, role, site, target badge ID, action type, prior and new status, timestamps in UTC, requester and approver identities, justification notes, and deny reasons Given a user with Audit Viewer permission When they open the audit log Then they can view the complete approver trail and denial reasons and records are read-only Given any attempt to modify or delete an audit record When performed by any user or service Then the system blocks the attempt and logs the event as a security violation
Audit Logging and Compliance Reporting
"As an administrator, I want comprehensive, exportable audit logs for all BadgeGuard actions so that I can satisfy audits and investigate incidents with confidence."
Description

Record a tamper-evident audit trail for all BadgeGuard events: lockdown initiation, propagation results, attempted uses, fallback issuance/usage, approvals, and reversals. Provide searchable filters (staff, time range, site, action), export to CSV/PDF, and scheduled reports for regulators and internal reviews. Support retention policies and integrity checks with hashed log chains. This delivers the evidence needed for incident reviews and regulatory compliance in assisted living settings.

Acceptance Criteria
Log Tamper-Evidence via Hashed Chain
Given an existing last_log_hash When a new BadgeGuard event is appended Then the record includes prev_hash=last_log_hash, hash=SHA-256(canonical_record), and timestamp in UTC ISO 8601 with millisecond precision And the append is rejected if prev_hash does not match the current chain tip And the record is immutable after write (no update/delete endpoints exist) Given an integrity check is initiated for a time range When the system recomputes hashes across the selected range Then it returns Pass with the terminal hash when all links validate And returns Fail with the first offending record_id and reason INTEGRITY_MISMATCH when any link is broken Given an integrity failure is detected When alerts are configured Then an audit alert entry is created and a notification is sent to the configured channel within 60 seconds
Capture and Classify All BadgeGuard Events
Rule: The system must log these event_types: LOCKDOWN_INITIATED, LOCKDOWN_PROPAGATION_RESULT, BADGE_USE_ATTEMPT, FALLBACK_ISSUED, FALLBACK_USED, APPROVAL_GRANTED, REVERSAL_PERFORMED, SCHEDULED_REPORT_RUN, EXPORT_GENERATED, RETENTION_PURGE Rule: Each record includes fields: event_id (UUIDv4), event_type, actor_id (nullable for system), actor_role, subject_badge_id (nullable), site_id (nullable for global), device_id (nullable), outcome (SUCCESS|FAIL) with failure_reason (nullable), timestamp_utc (ISO 8601 with ms), correlation_id (nullable), ip_addr (nullable), user_agent (nullable) Rule: LOCKDOWN_PROPAGATION_RESULT records one entry per target (site/device) with latency_ms and propagation_status (APPLIED|SKIPPED|FAILED) Rule: BADGE_USE_ATTEMPT includes access_point_id and policy_result (ALLOWED|DENIED) and reason Rule: FALLBACK_ISSUED and FALLBACK_USED include fallback_type (PIN|QR) and expiry_ts Rule: All writes occur within 200 ms of event occurrence on average, p95 <= 500 ms under normal load
Search and Filter Audit Logs
Given audit data exists across multiple sites and staff When a user applies filters for staff (actor_id), time range (start_ts, end_ts), site_id(s), and action (event_type) Then the result set includes only matching records And results are sortable by timestamp asc/desc and event_type And pagination supports limit and cursor/offset to retrieve the full result set And the first page (<=100 rows) returns within 2 seconds for queries scanning up to 200k records (p95) Given a search query is exported or viewed When no records match Then the UI/API returns an empty result with row_count=0 and no errors
Export Logs to CSV and PDF
Given a filtered audit result set When the user requests CSV export Then the CSV is generated using RFC 4180 rules (quoted fields, escaped quotes) with UTF-8 encoding and header row And the export contains exactly the rows matching the active filters and sort And the file name follows pattern audit_{yyyyMMddTHHmmssZ}_{rowcount}.csv And generation completes within 10 seconds for up to 50k rows (p95) Given a filtered audit result set When the user requests PDF export Then the PDF includes a cover header with generated_at (UTC), filters summary, and total row count And tabular pages include column headers and page numbers And generation completes within 15 seconds for up to 10k rows (p95) Given an export completes When the download is initiated Then an audit event EXPORT_GENERATED is logged with format, row_count, and filter hash
Scheduled Compliance Reports
Given an administrator configures a schedule When they specify format (CSV|PDF), filters (staff, time range relative, site, action), frequency (daily/weekly/monthly) and delivery time with time zone Then the schedule is saved and validated (no overlaps, cron valid) Given a schedule is active When the scheduled time arrives Then the report is generated with the saved parameters and stored in the reports archive And a notification is sent to the designated recipients with a download link And an audit event SCHEDULED_REPORT_RUN is logged with outcome (SUCCESS|FAIL) Given a scheduled run fails When a retriable error occurs Then the system retries up to 3 times with exponential backoff and logs failure_reason on final fail
Retention Policy Enforcement and Purge Audit
Given a retention policy in days is configured When the nightly retention job runs Then audit records older than the policy are purged And a RETENTION_PURGE event is appended including purged_from_ts, purged_to_ts, count, and terminal_hash_before and terminal_hash_after to maintain chain continuity Given records are purged When a search includes a time range fully within the purged window Then zero records are returned and no integrity errors occur Given retention settings are updated When a shorter retention is applied Then the next job purges accordingly and logs the change with previous_value, new_value, changed_by, and changed_at
Badge Recovery and Replacement Workflow
"As an operations coordinator, I want a clear recovery/replacement process so that lost badges are resolved quickly without leaving residual access risks."
Description

Offer a guided workflow to transition a badge through states (Lost → Found → Re-activated or Replaced → Destroyed), ensuring only one active credential per staff member. Automate notifications to HR/operations, schedule replacement issuance, and require confirmation of physical destruction or return. Prevent reactivation if risk conditions persist (e.g., repeated misuse attempts). This closes the loop after a lockdown, reducing administrative overhead and preventing credential sprawl.

Acceptance Criteria
Initiate Lost Badge Workflow from Admin Console
Given an authenticated admin views a staff member’s badge profile When the admin selects "Mark as Lost" and confirms Then the badge state changes to Lost within 2 seconds, all access tied to the badge is revoked immediately, a workflow stepper is displayed, and an audit entry is recorded with admin, time, and reason And HR and Operations receive notifications via email and in-app within 60 seconds containing staff name, badge ID, initiator, reason, and next steps And a replacement issuance task is created and assigned with a due date within 2 business days And a time-limited PIN/QR fallback credential is issued to the staff member for up to 24 hours (configurable) scoped to non-critical areas only
Found Badge Evaluation and Conditional Reactivation
Given a badge in Lost state is reported Found When the admin selects "Found" and submits finder, location, and timestamp Then the system runs a risk check using configured rules (e.g., misuse_attempts_last_24h >= 3) And if the risk check fails, reactivation is disabled, "Replace" is required, and the blocking reason is displayed to the admin And if the risk check passes, when the admin selects "Reactivate" and confirms Then the badge state changes to Active, any open replacement task is canceled, and HR/Operations and the staff member are notified within 60 seconds And all actions are recorded in the audit trail with who, when, and why
Replacement Issuance Scheduling and Handoff
Given a badge in Lost state requires replacement When the admin selects "Replace" Then the system proposes the next available issuance slot within 2 business days and assigns it to provisioning staff And calendar invites are sent to the staff member and assignee with time, location, and prerequisites And on issuance, the new badge ID must be scanned/entered, staff acknowledgment is captured, and supervisor approval is recorded And upon activation of the new badge, the old badge state is set to Destroyed (if destroyed) or Return Pending (if not present), and notifications are sent to HR/Operations and the staff member
Enforce Single Active Credential per Staff Member
Given a staff member already has an active credential When a new badge is activated for that staff member Then the system automatically deactivates any other active badge or digital credential for that staff member within 2 seconds And attempts to activate a second active credential are blocked with an error message and an audit log entry And if the old badge is later found, it cannot be reactivated while another badge is active; only Destroy or Return actions are available
Physical Return or Destruction Confirmation and Compliance Proof
Given a workflow requires closure after replacement or found-not-reactivated When the admin completes the "Confirm Return/Destruction" step Then the system requires selection of method (Returned intact or Destroyed), photo evidence or witness e-signature, device/location identifier, and timestamp And the workflow cannot be closed until confirmation is provided and validated And if confirmation is not provided within 7 days, daily escalations are sent to HR/Compliance until completion And evidence is retained for a configurable period (default 7 years) and is exportable with chain-of-custody metadata
Misuse Attempts Monitoring and Reactivation Prevention
Given a badge is in Lost state When an access attempt is made with that badge at any reader Then the attempt is denied, an alert is sent to the admin and HR within 60 seconds, and the misuse counter is incremented with reader, site, and timestamp And when the misuse counter reaches the configured threshold (default 3 attempts within 24 hours), the badge is flagged High Risk and reactivation is blocked for 72 hours or until dual-approval override is provided with a reason And when reactivation is attempted during a block, the system displays a blocking message with misuse details and requires dual approval; all overrides are logged And misuse logs are viewable and exportable by date range and staff member

Offline Tap Cache

Lets staff tap to sign in even when Wi‑Fi drops by securely caching recent badge credentials and role/unit mappings for a short window. Work continues uninterrupted in dead zones; all activity syncs and audits automatically once online.

Requirements

Encrypted Time-Bound Credential Cache
"As a security admin, I want cached credentials encrypted with a short expiry so that offline access stays secure and compliant."
Description

Securely cache a minimal set of recently validated staff badge credentials and associated role/unit mappings for a short, configurable window (e.g., 15–60 minutes). Store only non-PII identifiers and permission scopes using hardware-backed encryption and OS keystore, with per-device keys and periodic key rotation. Enforce strict TTL expiry, immediate purge on logout/policy change/device compromise signals, and eviction when cache limits are reached. Ensure offline validation uses hashed tokens and does not allow privilege elevation beyond the last known scope. Provide safeguards against replay and stale cache use while preserving rapid, one-tap performance.

Acceptance Criteria
TTL Expiry Blocks Offline Access After Configured Window
Given a device caches a credential at T0 and TTL is set to 30 minutes When the user taps offline at T0+29m Then access is granted And when the user taps at T0+30m+1s Then access is denied and the user is prompted to reconnect Given an admin changes TTL from 30 to 15 minutes while the device is online When the policy update is received Then any cache entries older than 15 minutes are immediately invalidated Given the system clock may be skewed by ±2 minutes When offline validation occurs Then TTL enforcement tolerates the skew without granting access beyond the configured window
Cache Stores Only Non‑PII Identifiers Under Hardware-Backed Encryption
Given a cached entry exists Then inspecting app storage reveals only non-PII identifiers (opaque user ID, hashed token, role/unit IDs) and no names, badge numbers, photos, or emails And cached blobs are encrypted at rest using a hardware-backed keystore (Android KeyInfo inside secure hardware = true or iOS Secure Enclave) Given the device is detected as rooted/jailbroken or attestation fails When offline validation is attempted Then decryption is refused and the cache is purged Given an offline tap is processed Then no plaintext credentials or PII are present in process memory dumps captured during the operation
Per-Device Keys and Periodic Key Rotation
Given two devices A and B used by the same user When A's encrypted cache is captured and moved to B Then B cannot decrypt it (keys are per-device) Given key rotation interval is set to 7 days When rotation occurs Then existing cache contents are re-encrypted with the new key without user impact And offline taps continue to succeed within 200ms p95 Given a keystore error occurs during rotation When rotation fails Then the cache is invalidated and offline access is disabled until the next successful online sign-in And an audit log event is recorded Given the app is reinstalled on the same device When it is launched Then previous keys are not reused and any old cache remains inaccessible
Immediate Purge on Logout, Policy Change, or Compromise
When the user logs out Then all cache entries are purged within 1 second And subsequent offline taps are denied When an admin revokes a user or reduces permissions while the device is online Then affected cache entries are purged within 5 seconds of receiving the policy update When an MDM wipe/compromise signal is received or OS attestation fails Then the cache is purged immediately and a tamper event is logged And offline access is disabled until the device is healthy Given a purge has occurred When the app restarts or the device reboots Then the cache remains empty (purge is durable)
Cache Size Limit and Eviction Policy
Given cache capacity is set to 50 entries When the 51st unique credential is validated Then the least-recently-used entry is evicted and cannot be used offline Given an entry has been evicted due to capacity When the device time is altered Then the evicted entry remains unavailable offline Given cache capacity is updated from 50 to 100 while online When the policy update is received Then the new limit applies within 60 seconds Given eviction or capacity changes occur Then an audit record is written with timestamp and non-PII entry identifiers
Offline Validation with Hashed Tokens and No Privilege Elevation
Given the user's last known scope is Role=Care Aide and Unit=West When offline Then taps authorize only actions within that scope And attempts outside the scope (e.g., Unit=East or Role=Charge Nurse) are denied Given tokens are stored as salted hashes with a per-entry nonce or counter When an attacker replays a previously captured tap payload Then validation fails (nonce already consumed or freshness window exceeded) Given the user's scope is reduced while the device is offline When the device reconnects Then the cache is reconciled and any elevated offline actions attempted are blocked from syncing and flagged for review Given an offline tap is processed Then no network calls are made and the operation completes within 150ms p50 and 300ms p95 on reference devices
Stale Cache Detection and Audit Sync on Reconnect
Given the device has been offline longer than the TTL When it reconnects Then any cached entries are marked expired and are not used And the user must re-authenticate online Given offline tap events were queued with signed timestamps When the network returns Then events sync in order with server acknowledgment And any event older than the server TTL is rejected and flagged Given cache operations occur (hits, misses, purges, evictions, rotations, replay rejections) Then an audit trail records each with device ID (non-PII) and timestamps
Offline Tap Authentication Flow
"As a caregiver, I want a clear offline sign-in that works with one tap so that I can keep working without troubleshooting Wi‑Fi."
Description

Implement a seamless offline sign-in pathway that automatically activates when connectivity is unavailable, allowing staff to authenticate with a single badge tap against the secure cache. Present clear offline state indicators, validate against cached tokens and role/unit scope, and unlock only capabilities permitted in offline mode. Support optional device biometric/PIN as a second factor per policy. Ensure sub-300ms tap-to-auth performance on supported devices and graceful fallback messaging if cache is missing or expired.

Acceptance Criteria
Offline mode auto-activation and indicator
Given the device has no internet connectivity at the sign-in screen And a valid cached badge credential exists for the staff member When the staff taps their NFC/RFID badge Then the app selects the offline authentication pathway without attempting any network request And an Offline banner and icon are displayed within 100 ms and persist for the session And the user is authenticated against the cached credential and cached role/unit mapping And a "Signed in (Offline)" state is shown in the header
Offline tap-to-auth performance
Given a supported device with a warm credential cache and screen awake When a staff badge is tapped in offline mode Then the time from tap detection to authenticated session ready is <= 300 ms at P95 over 100 consecutive attempts And <= 500 ms at P99 And no loading spinner is shown unless elapsed time exceeds 250 ms And performance metrics are recorded locally for later upload
Cached credential validation and TTL
Given OFFLINE_CACHE_TTL_HOURS is set to 12 and the cache was last refreshed 6 hours ago When the staff taps their badge in offline mode Then authentication succeeds only if the cached token signature is valid and unexpired And the staff member's role and unit scope match the cached mapping Given the cache was last refreshed 13 hours ago When the staff taps their badge in offline mode Then authentication is denied and a cache-expired message is shown And no session is created And cached credentials are stored encrypted using the OS keystore and cannot be decrypted after app uninstall or device wipe
Policy-driven second factor (biometric/PIN)
Given org policy Offline2FARequired = true and the device has a biometric enrolled When the staff completes badge tap offline Then the app prompts for biometric verification immediately And access is granted only after a successful biometric within 30 seconds Given biometric is unavailable or fails 3 times When prompted for second factor Then the app falls back to org-configured offline PIN entry And access is granted only after correct PIN within 5 attempts; otherwise the user is locked out for 60 seconds Given org policy Offline2FARequired = false When the staff completes badge tap offline Then no second factor is requested
Offline capability gating by role/unit
Given a user signs in offline with role Care Aide and unit Maple Wing When accessing features Then only offline-permitted features for that role/unit, as defined by OfflineCapabilities policy, are available And attempts to access restricted features show "Unavailable offline" and are prevented And UI controls for restricted features are disabled or hidden And any initiated action that requires network is queued and labeled "Pending sync"
Graceful fallback on missing/expired cache
Given no cached credential exists for the badge or the cache is expired When the staff taps their badge offline Then authentication is denied And the app displays "Offline sign-in unavailable: connect to Wi‑Fi or contact supervisor" with Try Again and Network Settings shortcuts And no user capabilities are unlocked And an audit event OfflineAuthDenied is recorded locally
Audit logging and post-reconnect sync
Given a successful offline sign-in occurred And the device regains connectivity When the app detects connectivity Then offline authentication audit events (badge hash, device ID, timestamp, cache age, outcome) are uploaded within 15 seconds And local logs are cleared only after server acknowledgment And if the user's role/unit changed since cache issuance, the session is refreshed to current permissions and an "Permissions updated" banner is shown
Role/Unit Snapshot and Access Scoping
"As a floor lead, I want my unit access to carry over when offline so that I can continue documenting care for my assigned residents only."
Description

Maintain a last-known-good snapshot of each user’s role(s) and unit assignments tied to their cached credentials, restricting offline access strictly to those scopes. Handle multiple roles with a clear default selection and visible scope indicator. Invalidate or narrow the snapshot on reconnection if roles change or are revoked, and prevent cross-unit access while offline. Update snapshots opportunistically whenever online authentication succeeds to keep caches fresh.

Acceptance Criteria
Offline Sign-In Within Cached Scope
Given the device holds a valid cached credential for user U and a last-known-good snapshot S of roles and unit assignments updated within TTL And the device is offline When U taps their badge to sign in Then the app signs U in offline without server calls And sets the current scope to S.default_role and its associated unit(s) And displays a visible scope indicator showing the active role and unit name(s) And records an audit entry with user ID, device ID, snapshot timestamp/version, and selected scope
Cache TTL Enforcement
Given configuration offline_cache_ttl_minutes = M And the device holds snapshot S last updated T minutes ago When user U attempts offline sign-in Then if T <= M, offline sign-in is allowed And if T > M, sign-in is blocked with the message "Offline sign-in unavailable. Reconnect to refresh access." And an audit entry is recorded for any blocked attempt with T, M, and user/device identifiers
Prevent Cross-Unit Access Offline
Given U is signed in offline under scope role R and unit set U_set from snapshot S When U attempts to view, search, or post an update to any unit not in U_set Then the action is blocked client-side with the message "Not available offline for this unit" And only content, residents, and shortcuts from U_set appear in lists and search results And an audit entry captures the blocked attempt with target unit and timestamp
Multiple Roles: Default Selection and Scope Indicator
Given snapshot S contains multiple roles {R1, R2, ...} with their unit scopes When U signs in offline for the first time after S is updated Then the app prompts U to select a default role from {R1, R2, ...} And persists the selection as S.default_role And shows the current role/unit indicator on all primary screens And allows switching offline only among roles present in S And logs each scope switch with from/to role, unit, user, device, and timestamp
Snapshot Refresh on Successful Reconnection
Given the device reconnects and U successfully authenticates online When the server returns updated role/unit assignments S_new Then the app replaces the local snapshot with S_new atomically And updates the snapshot timestamp to the server time And clears any cached roles/units no longer present And if the prior default role is no longer valid, U is prompted to choose a new default And an audit entry records the refresh with previous vs. new scope summary
Role Revocation and Session Narrowing on Reconnect
Given U is in an active offline session under scope (R_old, units_old) And upon reconnect the server indicates R_old and/or its unit scope has been reduced to units_new When the app processes the update Then the current session scope is narrowed to (R_old, units_new) if non-empty; otherwise U is signed out and offline mode is disabled And any queued actions targeting units not in units_new are submitted; if rejected by the server, they are marked failed with reason and U is notified And the scope indicator updates immediately to reflect the new scope And an audit entry records the change with previous and new scopes and any affected actions
Offline Activity Queue and Reliable Sync
"As an administrator, I want offline activity to sync automatically and accurately once online so that records and audits remain complete without manual intervention."
Description

Queue all offline sign-ins and subsequent care activities (e.g., photo/note metadata, voice-to-text entries, audit events) in an ordered, durable local event store with UUIDs, monotonic timestamps, and idempotency keys. On reconnection, perform automatic batched synchronization with exponential backoff, checksums, and resume support. Validate server-side permissions at sync time, resolve conflicts (e.g., revoked users) with clear error reporting, preserve per-resident event ordering, and mark items as synced with secure, policy-based local retention and purge.

Acceptance Criteria
Offline Sign-In and Care Activity Queuing
- Given the device has no network connectivity, When a caregiver signs in by tapping their badge, Then a SignIn event is queued with a UUID, idempotency key, monotonic timestamp, and role/unit snapshot, and the UI confirms within 1 second. - Given the device is offline, When the caregiver creates photo/note metadata or submits a voice-to-text entry, Then each action is queued as an event with a UUID, idempotency key, monotonic timestamp, resident ID, and care context reference, with no network calls attempted. - Given multiple offline events are created in sequence, When inspected via diagnostics, Then the pending queue count equals the number of events created and each event has a unique UUID and idempotency key.
Durable Local Event Store and Crash Recovery
- Given queued offline events exist, When the app is force-closed or the device reboots while still offline, Then all queued events persist with identical UUIDs, idempotency keys, and timestamps upon relaunch. - Given device system time is set backward while offline, When new events are created, Then their recorded monotonic timestamps do not decrease relative to prior local events. - Given the device is locked at rest, When attempting to access the on-disk event store without device unlock, Then event contents are unreadable, indicating encryption at rest bound to the OS keystore.
Automatic Batched Sync with Backoff and Resume
- Given pending events exist, When network connectivity is restored, Then synchronization starts automatically within 5 seconds without user action. - Given the number or size of pending events exceeds the configured batch limit, When syncing, Then events are sent in batches that respect the configured maximum, each batch includes a checksum, and the server acknowledges only after checksum verification. - Given a network interruption occurs mid-batch, When connectivity resumes, Then the client resumes from the last acknowledged event offset without duplicating already accepted events. - Given transient 5xx errors occur, When retrying, Then exponential backoff is applied starting at an initial delay and doubling up to a maximum of 5 minutes; Given a 4xx validation error occurs, Then the affected events are not retried and are marked Failed with the server-provided reason. - Given retries or resumes cause duplicate submissions, When the server receives events with previously used idempotency keys, Then no duplicate records are created and the client treats the response as success.
Permission Revalidation and Revoked User Handling
- Given a caregiver's access or unit mapping changed while offline, When their queued events are synced, Then server-side permission checks run per event and unauthorized events are rejected with explicit error codes and reasons. - Given some events are rejected for authorization, When processing the sync response, Then those events are marked Failed with the server reason, a non-blocking user-visible notice is shown, and syncing of authorized events continues. - Given the sign-in event itself is unauthorized at sync time (e.g., user revoked), When detected, Then the user is signed out immediately after sync, shown a message indicating access was revoked, and an audit event is recorded. - Given access tokens are expired at sync start, When re-authentication is requested, Then sync pauses until successful re-auth and then resumes; if re-auth fails, events remain pending with no data loss.
Per-Resident Event Ordering Preservation
- Given interleaved offline events exist for residents A, B, and C, When they are synced, Then for each resident the server stores events in the exact order they were created locally. - Given a partial sync completes and connectivity drops, When syncing resumes, Then per-resident ordering remains strictly increasing across batch boundaries with no reordering. - Given the device clock changes during offline capture, When determining order, Then the client uses monotonic timestamps or a logical sequence to ensure consistent per-resident ordering. - Given a condition would cause out-of-order acceptance for a resident, When detected, Then the client prevents submission that would violate order and marks affected events Failed with a conflict reason if ordering cannot be preserved.
Post-Sync Marking, Retention, and Secure Purge
- Given events are successfully synced, When the server acknowledges, Then the client marks the items as Synced with the server acknowledgment metadata and excludes them from further retry logic. - Given a retention window is configured, When the window elapses, Then synced items are securely purged via key erasure or equivalent mechanism, leaving no recoverable plaintext on device storage. - Given events fail to sync, When within the policy TTL, Then they are retained and retried according to the backoff policy; When the TTL expires, Then they are marked Expired and require manual resolution without being purged. - Given auditing requirements, When events are enqueued, synced (success/fail), and purged, Then corresponding audit events are recorded with timestamps, device identifier, and outcome.
Admin Policy Controls and Remote Actions
"As a compliance admin, I want to set and enforce offline access policies so that facilities balance continuity of care with security requirements."
Description

Provide console-level controls to configure offline cache TTL, maximum cached users, allowed offline features, and requirements for second-factor prompts. Support policy scoping per facility/unit and versioned distribution to devices. Enable remote wipe of offline caches for lost/stolen devices, temporary emergency offline overrides with auto-expiry, alerting on offline sign-ins, and reporting on cache usage and sync health. The app enforces the last-known policy and records the policy version used for each offline session.

Acceptance Criteria
Scoped Policy Versioning and Distribution
Given an admin with Policy Manager role, When they create a policy with TTL, max cached users, allowed offline features, and 2FA rules, and scope it to Facility A / Unit West, Then the console saves it as a new immutable version with a unique version ID and scope metadata. Given the policy is published, When a device assigned to Facility A / Unit West is online, Then it fetches the new policy within 5 minutes or on next app foreground, whichever occurs first, and stores the version ID. Given the policy is published, When a device not in the scope checks in, Then it does not download or apply the policy. Given a device has the new policy, When viewed in App Settings, Then it displays the active policy version ID and scope.
Offline Enforcement of Last-Known Policy and 2FA
Given a device is offline with a last-known policy, When a staff member attempts offline tap sign-in, Then the app enforces TTL validity, max cached users, and allowed offline features as defined by that policy. Given the policy requires a second factor for offline sign-in via device PIN/biometric, When the user signs in offline, Then the app prompts for and validates the second factor locally before granting access. Given the policy requires online-only second factor, When the device is offline, Then offline sign-in is blocked with an explanatory message and audit entry. Given the max cached users limit is reached, When a new user attempts offline sign-in, Then the app prevents caching and displays a message to sign in online or remove a cached user, and records the event. Then the session is tagged with the enforced policy version ID and written to the offline audit log for later sync.
Remote Wipe of Offline Cache on Lost/Stolen Device
Given an admin issues a remote wipe for a specific device, When the device receives the command via push or on next check-in, Then the app clears all cached badge credentials, role/unit mappings, and offline audit data, and signs out any active sessions. Then the device blocks offline sign-in until a fresh policy is fetched, displaying "Offline cache cleared by admin" and the wipe timestamp. Then the console shows the wipe status as Pending, In Progress, or Completed with last-seen time; upon completion it records a verifiable checksum of cleared cache and the device OS-level confirmation where available.
Time-Bound Emergency Offline Override with Auto-Expiry
Given an admin creates an emergency override for Facility A for 4 hours that extends TTL and enables offline photo notes, When published, Then in-scope devices receive and apply the override within 5 minutes or on next foreground. Then the app prominently displays "Emergency Offline Override" with remaining time, and all override-affected actions are flagged for audit. When the override reaches expiry or the admin revokes it, Then devices automatically revert to the baseline policy within 1 minute of detection and stop permitting override-only actions. Then all sessions during the override are tagged with override ID and policy version in audit logs.
Alerting on Offline Sign-Ins
Given alerting is enabled, When any offline sign-in occurs, Then the system sends an alert within 2 minutes to the configured channels (email and/or webhook) including user, device ID, facility/unit, timestamp, and policy version used. Given multiple offline sign-ins occur on the same device within 10 minutes, When alerts are sent, Then they are rate-limited according to the configured threshold (default 1 per 5 minutes) while preserving a count in the event payload. Then all alert deliveries (success/failure) are logged and visible in the console with retry outcomes.
Reporting on Cache Usage and Sync Health
Given an admin opens the reporting dashboard, When selecting a date range, Then the console displays per facility/unit and per device: cached users count vs max, cache TTL remaining distribution, last sync time, number of offline sign-ins, and failed sync attempts. Then the dashboard data freshness is within 15 minutes of each device’s last check-in; stale devices (no check-in > 24 hours) are flagged. When exporting to CSV, Then the file includes device ID, facility/unit, policy version most recently applied, counts and timestamps noted above, and a generated report ID for audit.
Security, Integrity, and Tamper Protections
"As a security officer, I want strong protections around offline caching and logging so that we reduce risk and meet privacy obligations."
Description

Implement device integrity checks (root/jailbreak/debug detection), hardware-backed key storage, anti-tamper defenses, and auto-purge after repeated failed attempts. Use hash-chained, append-only local audit logs with secure timestamps (monotonic clock with NTP reconciliation) to mitigate clock drift. Cache a recent revocation list and apply replay protections to prevent reuse of expired or revoked credentials. Minimize stored data to least necessary, and ensure controls align with privacy and regulatory needs.

Acceptance Criteria
Offline Tap Denied on Compromised Device
Given the device fails integrity checks (root/jailbreak/emulator/debugger detected) When a caregiver attempts an offline tap sign-in Then access to the Offline Tap Cache is blocked And the attempt is prevented without revealing cache contents And a local append-only audit entry is recorded with reason="integrity_failed" And the UI displays a non-disclosing error message with retry guidance And integrity checks are executed at app launch and before each offline tap attempt
Hardware-Backed Keys Only for Offline Cache
Given the device supports hardware-backed keystore (e.g., Secure Enclave/StrongBox/TPM) When the app creates or accesses the Offline Tap Cache encryption key Then the key is generated hardware-backed, marked non-exportable, and uses AES‑GCM 256 with unique per-record nonces And key attestation is validated at enrollment with certificate pinning And if hardware-backed storage is unavailable or attestation fails, the Offline Tap Cache feature is disabled and no cache is created And attempts to fallback to software-backed keys are rejected and audited
Runtime Tamper Detection and App Shutdown
Given runtime tamper indicators are present (e.g., code injection, Frida/ptrace, signature mismatch) When the app detects tampering during offline mode Then secrets and cache keys are zeroized in memory And offline functionality is immediately disabled for the session And a tamper event is appended to the local audit log and queued for server alert on next sync And the user is forced to re-authenticate after network reconnection and an admin unlock is required to re-enable offline mode
Auto-Purge After Repeated Failed Offline Badge Attempts
Given the caregiver enters an invalid badge or PIN When there are 5 failed attempts within a rolling 10-minute window (or 1 attempt with a revoked/expired credential) Then the Offline Tap Cache is purged (encrypted cache files deleted, keys invalidated) without exposing contents And offline sign-in is locked for 30 minutes And an audit entry is appended including counts, timestamps, and purge=true And on next connectivity, a purge-and-lock event is sent to the server and confirmed
Append-Only Hash-Chained Audit Log with Secure Timestamps
Given any offline authentication or cache operation occurs When an audit record is written Then the record includes: monotonic timestamp, wall-clock timestamp, operation type, outcome, and previous-hash And the record’s hash (H(prev_hash || payload)) is stored to create an append-only chain And on sync the server verifies chain continuity and signature, and flags any breaks or missing sequence numbers And clock drift is corrected using NTP offset; entries with drift > ±120s are marked suspect and require review
Offline Revocation List and Anti-Replay Enforcement
Given a cached credential revocation list (CRL) with a TTL of 24 hours is stored locally When a caregiver attempts an offline tap Then the credential is denied if listed in the CRL or expired And offline mode is disabled if the CRL is older than 24 hours until refreshed And a device-scoped, hardware-protected counter is included in each offline proof to prevent replay; any repeated counter value is rejected and audited And nonces and proofs expire after 5 minutes from creation
Data Minimization and Time-Bound Cache Retention
Given the app caches recent badge credentials and role/unit mappings When evaluating stored data Then no personally identifiable information (names, photos, contact info) is stored; only HMAC(badge_id), role_code, unit_code, expiry, and minimal metadata And the cache holds at most 200 active records and each record expires and is deleted within 24 hours (whichever comes first: TTL or LRU) And all cached data is encrypted at rest with the hardware-backed key; debug logs contain no secret or PII values And on feature disable or sign-out, all cache material and derived keys are wiped and wipe is auditable
Offline UX Indicators and Diagnostics
"As a caregiver, I want clear indicators and guidance while offline so that I know what I can do and when I need to reconnect."
Description

Provide clear offline/online banners, a visible countdown to cache expiry, and scoped access chips showing the active role/unit. Offer friendly guidance when caches are stale or policies prohibit offline use. Include a diagnostics panel for support showing policy version, cache status, pending queue size, last sync attempt, and exportable redacted logs. Ensure accessibility, localization, and haptic feedback. Target responsive interactions and low battery impact while offline.

Acceptance Criteria
Offline/Online State Banners
- Given connectivity changes, when the device goes offline, then an "Offline" banner appears within 1 second and remains visible until connectivity is restored. - Given connectivity changes, when the device returns online, then an "Online" banner appears within 1 second for ≤3 seconds or until dismissed. - The banners are distinguishable without color reliance (icon + text) and meet WCAG 2.1 AA contrast. - Screen readers announce the state change exactly once; announcements are throttled to not repeat more than once per 30 seconds. - Haptic feedback: a single light haptic is issued on state change (if supported) and is suppressed when system Reduce Haptics/Accessibility settings are enabled. - Localization: banner text uses the current locale and adapts line breaks without truncation on small devices.
Cache Expiry Countdown and Enforcement
- A countdown chip shows time remaining until offline cache expiry (mm:ss when <60 minutes, hh:mm otherwise) and updates every second. - Visual state changes at thresholds: warning at <5 minutes (amber) and critical at <1 minute (red + subtle haptic once). - When countdown reaches 0, offline sign-ins and unit/role switching actions are blocked with a clear "Cache expired" message and a CTA to reconnect. - After expiry, no cached data is accessible until a successful policy+credential refresh occurs. - Countdown time is derived from policy TTL and last successful cache refresh timestamp; device clock drift >2 minutes triggers a warning tooltip. - All behaviors function without noticeable jank (frame drops ≤5% on reference devices).
Scoped Access Chips for Active Role/Unit
- The main header displays chips for Active Role and Active Unit derived from cached mappings; format: "Role: {role}" and "Unit: {unit}". - Changing role/unit (when permitted offline) updates chips within 500 ms and logs the change for later sync. - If role/unit mapping is missing or stale beyond policy TTL, chips show a strikethrough state and tapping reveals guidance; offline actions requiring scope are disabled. - Chips are keyboard-focusable, VoiceOver/TalkBack announce labels and values, and hit areas are ≥44x44 dp/pt. - Localization: role and unit labels are translated; long values truncate with middle-ellipsis and have full-value tooltips. - No PII beyond role/unit names is displayed on lock screen or system screenshots (verified by secure flag on Android where applicable).
Stale Cache and Policy Prohibition Guidance
- When policy marks offline use as prohibited, attempting offline sign-in shows a non-dismissible sheet stating prohibition reason and next steps; offline sign-in remains disabled until policy allows and a refresh succeeds. - When cache age > policy TTL, a guidance dialog explains that cache is stale and provides actions: Retry Sync, View Diagnostics, and Contact Support. - Guidance text is localized, plain-language, and passes readability at or below Grade 8. - Accessibility: dialogs are focus-trapped, screen-reader labeled, and dismissible with system back/escape where appropriate. - No repeated alerts: identical prohibition/stale messages are not shown more than once per 10 minutes per session. - All attempts are logged to diagnostics with timestamps and reasons (no resident identifiers or full badge IDs).
Diagnostics Panel Content and Export
- The Diagnostics panel is reachable from Settings > Support within 2 taps and opens within 1 second on reference devices. - Panel displays: Policy Version (semantic version string), Cache Status (age and time-to-expiry), Pending Queue Size (integer count), and Last Sync Attempt (timestamp, result, error code when applicable). - A Refresh button triggers an immediate sync attempt and updates fields in-panel upon completion. - Export Logs produces a shareable file ≤5 MB containing the last 7 days of app events relevant to offline/cache, with PII redacted: resident names replaced with [REDACTED], phone numbers masked (XXX-XXX-1234), badge IDs hashed, media payloads omitted, and geolocation removed. - Export includes app version, device model, OS version, locale, timezone, and anonymized installation ID. - Logs are stored only ephemerally for export; export is disabled when device is unmanaged and policy requires it. - Screen readers announce all field labels; values are copyable where appropriate.
Accessibility and Localization Compliance for Offline Indicators
- All offline/online banners, countdowns, chips, and dialogs meet WCAG 2.1 AA for contrast and focus visibility. - Dynamic Type/Font Scale up to 200% does not clip critical content; interactive elements reflow without overlap. - VoiceOver/TalkBack read concise, localized announcements for state changes; no duplicate announcements occur. - Right-to-left locales render layouts correctly, including chip order and icon mirroring. - Date/time values (countdowns, timestamps) respect locale formats and 12/24h settings. - Haptics and motion effects respect system accessibility settings (Reduce Motion/Haptics).
Offline Performance and Battery Impact
- UI interactions in offline mode respond within 150 ms on reference devices; connectivity banner updates occur within 1 second of state change. - Background retry scheduler while offline performs at most one wake-up per 5 minutes with exponential backoff and jitter; no busy loops. - Average CPU utilization while idle offline is ≤3% over a 10-minute profiling window; no high-frequency timers (>1 Hz). - Additional battery drain attributable to offline indicators/background work is ≤0.5% per hour on the device matrix baseline over a 2-hour idle offline test. - No sensors (GPS, camera, microphone) are accessed in offline idle; network scans are disabled except for OS connectivity callbacks. - Memory footprint of diagnostics and logs remains ≤10 MB while offline.

TapTrail Audit

Creates a tamper-evident log of every tap event—who, when, where, and which device—with anomaly flags for suspicious patterns (e.g., one badge on two devices). Speeds HIPAA-style audits and gives Privacy Stewards clear, exportable evidence.

Requirements

Tamper-Evident Event Ledger
"As a Privacy Steward, I want every caregiver tap recorded in an immutable, verifiable ledger so that I can prove what happened, when, where, and on which device during audits."
Description

Implement an append-only, cryptographically chained ledger that records every caregiver tap with immutable metadata (caregiver badge ID, user role, device ID, app version, timestamp, geofence location, event type, consent snapshot ID, network state). Each event includes a previous-hash reference and a digital signature to detect edits or deletions. Support offline capture to an encrypted local queue with sequence numbers and verify integrity on sync. Store only PHI-minimized references (tokenized resident IDs) and provide server-side verification endpoints for chain validation across devices and facilities.

Acceptance Criteria
On-Device Append-Only Hash Chain
Given a caregiver is authenticated on a device When they record a tap event Then the event includes previous_hash (SHA-256 of the prior event payload) and a digital signature over the serialized event payload plus previous_hash using the device’s ledger private key Given any persisted event in the local ledger When an update or delete is attempted through app APIs Then the operation is rejected and a tamper-attempt audit record is created Given the local ledger is verified end-to-end When any stored event is externally altered or removed Then verification fails at that position and returns first_bad_index and expected_hash vs actual_hash Given a device with no prior events When the first event is saved Then previous_hash equals the device-specific genesis hash
Metadata Completeness and Format Validation
Given a tap event is saved When validation runs Then the event contains caregiver_badge_id (non-empty, matches active session), user_role, device_id, app_version, timestamp_utc (ISO 8601, millisecond precision), geofence_id, event_type, consent_snapshot_id, network_state in {online, offline}, and resident_id_token And any missing or malformed required field causes the save to fail with a specific validation error code And all recorded fields are included in the signed payload used for the digital signature
Offline Capture and Encrypted Queue Integrity
Given the device has no network connectivity When N tap events are recorded Then each event is appended to an encrypted local queue using AES-256-GCM with a device-bound key and unique nonces, and assigned a monotonically increasing sequence_number per device And attempts to read or modify the queue without the key result in decryption/MAC failure Given connectivity is restored When the device syncs the queued events Then events are transmitted in strict sequence_number order and the first offline event links previous_hash to the last known on-server event for that device And the server rejects out-of-order or duplicate sequence_numbers and returns explicit error details And after successful sync and server verification, local queued entries are securely deleted
Server-Side Chain Verification API
Given an authorized client calls POST /ledger/verify with facility_id, device_id, and a range (start_seq, end_seq) When the server processes the request Then it returns 200 with a summary including chain_continuous (boolean), signature_valid (boolean), missing_sequences (array), duplicate_sequences (array), first_bad_index (nullable), and request_id And the endpoint requires OAuth2 scope ledger.verify, returning 401 for unauthenticated and 403 for insufficient scope And verification of up to 10,000 events completes within 5 seconds at p95 And when only facility_id is provided, results are returned per device with pagination via next_cursor
PHI Minimization via Tokenized References
Given an event is persisted When the stored record is inspected Then no raw PHI (e.g., resident name, photo, DOB) is present; only resident_id_token and consent_snapshot_id references are stored And application and server logs redact resident_id_token values and never emit raw PHI fields And any attempt to persist additional PHI fields is rejected by schema validation with an explicit error code and the event is not stored
Ingest Signature and Hash Verification with Quarantine
Given a device submits a batch of events during sync When the server ingests the batch Then for each event the server verifies the digital signature against the registered device public key and validates previous_hash continuity (including genesis) And if any event fails verification, the failing event and all subsequent dependent events in that batch are rejected, placed in a quarantine queue with reason codes, and the response returns per-event statuses to the device And successful events from the batch are committed atomically in order
Real-time Anomaly Flagging
"As an Administrator, I want the system to flag suspicious tap patterns as they occur so that I can intervene quickly and prevent misuse or errors."
Description

Create a rules engine that continuously evaluates the event stream to detect suspicious patterns such as one badge used on two devices concurrently, impossible travel between distant geofences, abnormal tap velocity, activity by deactivated users, after-hours access, device clock drift, and hash-chain gaps. Generate risk-ranked alerts with clear rationales, link to impacted events, and support routing to Privacy Stewards via in-app notifications and email. Allow rule tuning per facility and suppression/whitelisting with expiry for known exceptions.

Acceptance Criteria
Concurrent Badge Use Detection
Given a valid badge ID produces tap events from Device A and Device B within a facility-configurable concurrency window (default 120s) And the device IDs and session tokens are different When the rules engine processes the second event in real time Then a "Concurrent Badge Use" anomaly alert is created within 5s And the alert includes badge ID, device IDs, event timestamps, and facility ID And the alert includes a risk_score (0–100) >= 70 and risk_level = "High" And the alert rationale references the rule name and both event IDs And no alert is created if both taps originate from the same device within the window
Impossible Travel Between Geofences
Given geofences F1 and F2 with centroids distance D And a badge’s last tap at F1 at time T1 and next tap at F2 at time T2 And computed speed = D / (T2 − T1) > facility-configurable max_staff_speed_kmh (default 30 km/h) When the second event arrives Then an "Impossible Travel" anomaly alert is created within 5s And the alert includes D, T1, T2, computed speed, threshold, and impacted event IDs And the risk_level is at least "Medium" with risk_score >= 60 And no alert is created if computed speed ≤ threshold
Abnormal Tap Velocity Thresholding
Given a rolling 5-minute window of taps for a badge within a facility And the tap rate exceeds the facility-configurable threshold (default: > max(μ+3σ, 60 taps/5min)) When the threshold is crossed Then an "Abnormal Tap Velocity" anomaly alert is created within 5s And the alert includes observed rate, threshold, window size, and impacted event IDs And risk_level is "Medium" when exceedance < 2x threshold, else "High" And no alert is created if the badge is in a facility-approved speed-run whitelist active during the window
Unauthorized or After-Hours Activity Detection
Given a tap event is attributed to a deactivated/suspended user OR occurs outside facility-configured allowed hours When the event is processed Then an anomaly alert is created within 5s with type "Unauthorized Activity" (for deactivated) or "After-Hours Access" (for time-based) And the alert includes user/badge ID, account status or schedule rule ID, facility ID, and event ID And risk_level is "High" for deactivated/suspended and at least "Medium" for after-hours And no alert is created if a time-bound exception exists for that user/facility and is unexpired
Time Integrity and Evidence Chain Anomaly Detection
Given an event’s device_timestamp differs from server_received_at by more than the facility-configurable drift_threshold (default 120s) When processed Then a "Device Clock Drift" anomaly alert is created within 5s including observed drift and threshold And given any event has prev_hash that does not match the actual hash of the previous event or a sequence ID gap is detected in a contiguous segment When processed Then a "Hash-Chain Gap" anomaly alert is created within 5s including affected range (start_event_id, end_event_id) and first invalid link And both alerts include impacted event IDs and facility ID And no hash-chain alert is created if the gap corresponds to a documented maintenance window with an active suppression
Real-time Alert Generation with Risk Ranking, Rationale, and Event Linking
Given any anomaly rule fires When the alert is generated Then the alert record contains: id, rule_name, type, facility_id, risk_level ∈ {Low, Medium, High}, risk_score (0–100), rationale (<=250 chars), impacted_event_ids (>=1), first_seen_at, last_seen_at And the alert is created within 5s of the triggering event And risk_level and risk_score are computed per a configurable rules table and stored with the alert And the rationale includes rule parameters (e.g., speed=120km/h > 30km/h) And impacted_event_ids link to viewable TapTrail Audit entries in-app and via API
Notification Routing, Facility Rule Tuning, and Exception Suppression
Given a new alert with risk_level ∈ {Medium, High} When created Then in-app notifications are delivered to all users with role=Privacy Steward for the facility within 10s and an email is sent to the facility’s steward group including alert id, type, risk, rationale, and deep link And given a new alert with risk_level=Low When created Then an in-app notification is delivered within 10s and no email is sent And given a facility admin updates a rule parameter (e.g., max_staff_speed_kmh) When saved Then the new value is applied to evaluations within 60s and an admin-action audit record is written with actor, old_value, new_value, timestamp And given a steward creates a suppression for (rule, scope: user|device|facility, reason, expires_at) When active Then matching anomalies are not routed but are logged with suppression_id and appear in audit exports; routing resumes automatically after expires_at And attempts to create a suppression without expires_at or with expires_at > 30 days are rejected with validation errors
Audit Console & Evidence Explorer
"As a Privacy Steward, I want an audit console to filter, review, and annotate tap logs so that I can conduct HIPAA-style audits efficiently."
Description

Provide a role-gated web/mobile console to search, filter, and visualize tap events by time range, caregiver, device, facility, location geofence, event type, and anomaly status. Display hash-chain integrity indicators, event detail drill-down, and related media/consent references without exposing PHI. Enable annotations, assignment, and resolution workflow for anomalies with full history. Include saved views, export shortcuts, and performance-optimized pagination to handle large datasets.

Acceptance Criteria
Role-Gated Access with PHI-Safe Display
Given a user with the Privacy Steward or Admin role is authenticated When they navigate to the Audit Console Then the console is accessible and all views load without PHI fields (e.g., resident names, unblurred faces, voice-to-text content) Given a user with the Caregiver role and no audit permission When they attempt to access the Audit Console or related APIs Then access is denied with HTTP 403 and a user-facing message indicating insufficient permissions, and the attempt is logged with user, timestamp, and IP/device Given any event list or detail view is rendered When fields related to residents or media are displayed Then only non-PHI identifiers are shown (e.g., resident_uid hash, media_id, consent_record_id) and no inline media or transcript content is visible Given an authorized user views event metadata When they copy or export from the console Then exports and copy buffers exclude PHI and include only allowed fields
Multi-Filter Search Across Dimensions
Given the Audit Console has at least 100,000 events across multiple facilities, caregivers, devices, geofences, event types, and anomaly statuses When a user applies a combined filter (time range, caregiver, device, facility, geofence, event type, anomaly status) Then the result set reflects the intersection of all active filters and the total count updates accordingly Given a time range is applied in the console When results are displayed Then timestamps are interpreted and shown in the facility’s configured time zone and boundaries are inclusive of start and end times Given a geofence filter is applied (e.g., "South Wing") When results are displayed Then only events with coordinates within the defined polygon for that geofence are returned (0 outside) Given a user modifies or clears any filter When they apply changes Then results update within 2 seconds P95 for a 50-row page and no PHI fields appear in the grid
Hash-Chain Integrity Visualization
Given the event list is visible When each row renders Then a hash-chain integrity indicator is shown per event (Intact=green, Broken=red, Unknown=gray) Given a user opens the integrity details for an event When the details panel is expanded Then current_hash, previous_hash, hash_algorithm, and chain_position are displayed and recomputation locally matches stored values for Intact events Given an event has been tampered or the chain is discontinuous When integrity is recalculated Then the indicator shows Broken and a tooltip/reason code explains the failure (e.g., prev_hash_mismatch) Given the first event in a chain (genesis) is selected When details are displayed Then previous_hash is null and labeled as Genesis
Event Detail Drill-Down with Media/Consent References
Given a user selects an event from the list When the detail view opens Then metadata shown includes timestamp, caregiver_id, device_id, facility_id, geofence_name, event_type, anomaly_flags, current_hash, previous_hash, and PHI-safe resident_uid hash only Given media and consent are associated to the event When details render Then only reference metadata is shown (media_id, mime_type, size, consent_record_id, consent_status) and no inline media playback, image thumbnails, or transcript text is displayed Given a user attempts to fetch media content from the detail view When the request is made without explicit media-view permission Then the request is blocked with HTTP 403 and the attempt is logged Given an event reference link is clicked When navigation occurs Then the user is taken to the appropriate PHI-safe reference screen or tooltip without exposing underlying PHI content
Anomaly Workflow: Annotate, Assign, Resolve with Full History
Given an event flagged with an anomaly is open in the console When a user adds an annotation Then a non-empty text note (min 3 characters) is required and saved with actor_id, timestamp (ISO 8601), and immutable history entry Given an anomaly requires follow-up When a user assigns it to one or more steward users Then assignees are stored and visible on the event, and the action is recorded in history Given workflow states {New, In Review, Resolved, Reopened} When transitions occur Then rules are enforced: New->In Review requires at least one assignee; In Review->Resolved requires a resolution note (min 10 characters); Resolved->Reopened requires a reason; all transitions capture actor_id, timestamp, and previous->new state Given two users attempt to update the same anomaly concurrently When the second save occurs with a stale version Then the system rejects the save with a version conflict message and no history is lost or overwritten
Saved Views and Export Shortcuts
Given a user configures filters, sort, and visible columns When they save the configuration as a named view Then the view is persisted, can be set as default, and can be shared with users by role (Private, Team, Org) Given a saved view exists When the user applies it Then the console reproduces the same results, sort order, and columns as when the view was saved Given a filtered result set is visible When the user selects Export Current Page or Export All Filtered (max 100k rows) Then a CSV and JSON option are available, exports exclude PHI fields, include hash integrity fields, and the file name follows the pattern kinloop_audit_{facility}_{yyyy-mm-ddTHHMMssZ}_{filter_summary}.{ext} Given an export of 50,000 rows is requested When the export runs Then the file is generated within 60 seconds P95 and a completion notification/toast is shown with a download link
Large Dataset Pagination Performance
Given the result set exceeds 1,000,000 events When the user pages through results with page size 50 Then page fetch and render complete within 1.5 seconds P95 and 3.0 seconds P99 on a stable broadband connection Given pagination controls are displayed When a user changes page size (25, 50, 100) or navigates to next/previous/specific page Then the correct slice of data is shown with no duplicates or gaps and the total count remains accurate Given new events arrive while a user is browsing When the dataset changes Then the current page remains stable and a non-intrusive banner offers to refresh to include new results
Signed Export & Chain-of-Custody Package
"As a Compliance Officer, I want to generate signed, tamper-evident exports of audit data so that external auditors can independently verify integrity."
Description

Enable secure export of selected events and anomaly investigations as a tamper-evident bundle containing machine-readable JSON, optional CSV, and a human-readable PDF summary. Sign the package with a tenant-scoped private key and include chain hashes, checksums, export metadata (time, requester, scope), and verification instructions with a public-key signature. Deliver via expiring, access-logged links and record export actions in the ledger to preserve chain of custody.

Acceptance Criteria
Export Package Composition & Metadata
Given a Privacy Steward in tenant T selects a time range, event IDs, and anomaly case IDs and chooses JSON and PDF outputs (CSV optional) When they request an export Then the system produces a single bundle (e.g., ZIP) identified by export_id and timestamp And the bundle contains data.json (machine-readable), summary.pdf (human-readable), verification_instructions.txt, manifest.json, and data.csv only if CSV was selected And manifest.json includes tenant_id, requester_user_id, requester_role, export_id, export_timestamp (ISO 8601 UTC), scope (time range and filters), event_count, anomaly_count, app_version/build, and signature_fingerprint And event_count and anomaly_count in manifest.json match the counts in data.json
Tenant-Scoped Digital Signature & Tamper Evidence
Given the export bundle is created for tenant T When the system signs the bundle Then a detached signature file (export.sig) is produced and referenced in manifest.json along with the signature algorithm (Ed25519 or ECDSA P-256) and public key fingerprint And verifying the signature with tenant T’s published public key succeeds for the unmodified bundle And any single-byte modification to any bundled file causes signature verification to fail using the provided instructions
Chain Hashes and Checksums Integrity Verification
Given data.json contains exported events and anomaly investigations with recorded chain_hash and prev_hash values When a validator recomputes the chain for all included records Then each record’s prev_hash equals the previous record’s chain_hash within the export scope And per-file SHA-256 checksums and a bundle-level checksum recomputed by the validator match the values in manifest.json And any mismatch is reported as a failed integrity check
Expiring, Access-Logged Download Link
Given an export completes for tenant T When the system generates a download link with a configurable TTL (1–14 days; default 7) Then the link requires an authenticated tenant user with Export permission to access And each access attempt is logged with export_id, user_id, timestamp (UTC), IP, user_agent, and outcome (success/denied) And after TTL expiry the link returns HTTP 410 Gone and no bytes are served And all access log entries reference the export_id for audit correlation
Ledger Chain-of-Custody Recording
Given an export is requested, processed, completed, accessed, and expired When each of these lifecycle events occurs Then an immutable ledger entry is appended within 5 seconds containing export_id, actor (system/user), action, timestamp (UTC), and for completion the bundle content hash and signature fingerprint And each ledger entry includes a prev_entry_hash linking it to the prior entry for the same export_id And querying the ledger by export_id returns a complete ordered chain with no gaps And attempts to alter or delete ledger entries are rejected and generate an audit alert
Optional CSV Inclusion and Schema Consistency
Given the requester selects CSV output When the export completes Then data.csv is present and its row count equals the number of exported events And CSV headers match the documented schema referenced by manifest.json (schema_version and schema_url) And if CSV is not selected, data.csv is not present And data.json validates against the referenced JSON schema; summary.pdf totals match the counts in data.json
Time and Location Integrity Safeguards
"As a Security Engineer, I want timestamps and locations to be trustworthy so that audit conclusions are defensible."
Description

Enhance trust in timestamps and locations by enforcing periodic NTP sync with monotonic clock fallback, drift detection, and capture of timezone/offset. Validate presence within facility geofences using multi-signal checks (GPS, Wi‑Fi/BLE) and detect spoofing or low-confidence readings. Attach integrity and confidence scores to events and auto-flag out-of-policy captures for review.

Acceptance Criteria
Periodic NTP Sync with Monotonic Fallback
Given the device is online and the time sync interval is set to 6 hours When the last successful NTP sync exceeds 6 hours or drift > 2 seconds is detected Then the app attempts NTP sync within 30 seconds and logs server, offset (ms), and result Given the NTP server is unreachable for 3 consecutive attempts over 5 minutes When timestamps are generated for events Then monotonic clock deltas are used to preserve ordering and ntpSyncStatus="degraded" is recorded on events Given a successful NTP sync occurs When the sync completes Then the measured device offset vs NTP (ms) and ntpSyncStatus="ok" are stored and visible in diagnostics Given the device was offline When connectivity resumes Then the app performs NTP sync within 60 seconds and records syncRecoveredAt with outcome
Clock Drift Detection and Handling
Given the device time diverges from NTP by > 60 seconds When drift is detected Then the app blocks new event capture until the user acknowledges a Clock Drift warning and retries sync or proceeds in degraded mode with required justification text Given drift is between 2 seconds and 60 seconds When an event is captured Then the event is allowed but includes timeIntegrity="warn" with measured driftMs Given drift is ≤ 2 seconds When an event is captured Then timeIntegrity="ok" is attached to the event Given the device clock is manually changed by > 30 seconds while the app is foregrounded When the change is detected Then the app logs a systemClockChange event and re-attempts NTP sync within 30 seconds
Timezone and Offset Capture on Event
Given any event is captured When the timestamp is persisted Then the IANA timezone ID, UTC offset at event time (minutes, including DST), and locale are stored with the UTC timestamp Given the device timezone changes between events When the next event is captured Then the change is logged with previous and new TZ IDs and offsets Given an audit export is generated When events are serialized to CSV/JSON Then each event includes UTC time, local time, and UTC offset
Geofence Presence Validation with Multi-Signal
Given a facility geofence polygon and approved SSIDs/BLE beacons are configured When a user attempts to capture an event Then at least two corroborating signals (GPS-in-polygon, approved Wi‑Fi present, approved BLE proximity) are required unless a single signal has accuracy < 20 meters; all signals used are logged Given GPS accuracy is > 50 meters or unavailable When location validation runs Then Wi‑Fi/BLE signals are weighted higher and the computed locationConfidence reflects signal quality and count Given the user is > 100 meters outside any facility geofence When event capture is attempted Then capture is blocked or forced into an out-of-facility flow requiring supervisor override; the attempt is logged Given the device is indoors within the geofence and GPS is weak When approved Wi‑Fi or BLE beacons are present Then the event is permitted with locationConfidence ≥ 70 and sources recorded
Spoofing and Low-Confidence Detection
Given Android mock location is enabled or a known spoofing provider is detected When a location fix is obtained Then locationSpoofed=true is set, capture is blocked, and an alert is logged with provider details Given two consecutive location fixes jump > 500 meters within 10 seconds without matching speed/heading continuity When an event capture is attempted Then locationConfidence < 40 is set and the event is auto-flagged locationAnomaly Given only a single location signal is available with reported accuracy > 80 meters When event capture is attempted Then the user is prompted to improve signal or connect to approved Wi‑Fi/BLE; if declined, capture requires supervisor PIN and the event is flagged lowConfidence Given device location services are disabled When the user opens capture Then the app requests enablement; if denied, capture is disabled and the denial reason is recorded
Integrity and Confidence Scoring on Events
Given an event is captured When integrity assessment runs Then timeIntegrityScore (0–100) and locationConfidenceScore (0–100) are computed using documented weights and attached to the event payload Given inputs ntpStatus, driftMs, monotonicFallbackUsed, signalsUsed, accuracyMeters, geofenceDistance, spoofingIndicators When scores are computed Then the scoring function is deterministic and covered by unit tests with published test vectors Given timeIntegrityScore < 60 or locationConfidenceScore < 60 When the event is saved Then integrityStatus="warn" with a reason code is included; if any score < 30, capture is blocked unless supervisor override is provided Given administrators export audit data When events are exported Then scores, contributing inputs, and reason codes are included per event
Auto-Flag Out-of-Policy Captures for Review
Given policy thresholds (unsynced > 24h, outside geofence, spoofed signal, single-signal with low accuracy) When an event violates any threshold Then the event is auto-flagged, added to the Privacy Steward review queue within 1 minute, and a notification is sent to designated stewards Given an auto-flagged event exists When a steward marks it reviewed with a disposition Then the event stores reviewer ID, reviewedAt, disposition, and optional notes; flags are cleared or upheld accordingly Given ≥ 3 violations by the same badge or device within 24 hours When the condition is met Then an anomaly record (e.g., badgeDeviceMismatch or repeatedPolicyBreach) is created and escalated to the admin distribution list Given flagged events are included in an export When exports are generated Then each flagged event includes flag type, firstDetectedAt, clearedAt (if any), reviewer, and policy codes
Retention, Access Control, and Legal Hold
"As a Data Protection Officer, I want strict retention and access controls around TapTrail data so that we meet regulatory obligations and protect resident privacy."
Description

Implement per-tenant retention policies (e.g., 7-year WORM) with encryption in transit and at rest, least-privilege RBAC for audit features, granular scoping by facility and role, and comprehensive audit-of-audit logs for views, searches, and exports. Support legal holds to suspend deletions, and enforce data minimization by storing tokenized resident identifiers and consent snapshot references rather than PHI content.

Acceptance Criteria
Tenant WORM Retention Enforcement
Given a tenant-level WORM retention policy of 7 years is configured and active When a new TapTrail audit event is persisted with timestamp T Then the system stores retention_end = T + 7 years and marks the record immutable until retention_end Given any user or system attempts to modify or delete an immutable audit record before retention_end When the request is evaluated Then the operation is blocked with 403 Forbidden and a WORM enforcement entry is added to the audit-of-audit log Given retention_end has been reached and no legal hold applies When the scheduled retention job executes Then the record and related indexes are permanently deleted, and a deletion summary (count, time, id hash) is written to the audit-of-audit log
Legal Hold Suspends Deletion
Given a Privacy Steward creates a legal hold with name, reason, owner, scope (tenant/facility/resident/token range), and start/end times When the hold is saved Then all matching audit records are flagged "On Legal Hold" and excluded from deletion regardless of retention_end Given retention_end occurs for records under an active legal hold When the retention job runs Then no deletions occur for held records and the job report lists the held counts by scope Given a hold is released by an authorized user When the release is confirmed Then held records are eligible for deletion on the next retention cycle and the release action is logged with user, time, and scope
Least-Privilege RBAC for Audit Features
Given RBAC roles are defined and only users with the AuditViewer privilege have access to audit logs When a user without AuditViewer attempts to view, search, or export audit logs Then access is denied with 403 Forbidden and the attempt is recorded in the audit-of-audit log Given a user with AuditViewer is assigned a facility scope When they view, search, or export Then results and exports are limited strictly to their assigned scope and queries outside the scope return no data with a "Scoped" indicator Given a tenant admin updates a user's roles or scope When the change is applied Then the new permissions take effect on the next request and are reflected in access decisions and audit-of-audit entries
Granular Facility and Multi-Tenant Isolation
Given a tenant operates multiple facilities and users have assigned facility scopes When a scoped user queries or exports audit data Then only events from the assigned facilities are returned and cross-facility access is not possible Given two tenants exist with overlapping resident token formats When users from Tenant A search by token Then no records from Tenant B are returned and the isolation is verifiable by tenant_id in audit-of-audit entries
Audit-of-Audit Coverage for Views, Searches, and Exports
Given any user performs an audit-log view, search, or export When the action completes Then an immutable audit-of-audit record is written capturing user id, role, device id, IP, timestamp, action type, query/filter parameters (normalized), result count, and export artifact checksum (if any) Given an audit-of-audit record is queried When its integrity is checked Then its content hash matches the stored hash chain and any tampering breaks verification and raises an anomaly flag Given an export is generated When the file is downloaded Then the audit-of-audit includes the download event and the export can be reproduced from audit parameters to yield identical content checksum
Encryption in Transit and At Rest
Given any client-server or service-to-service connection handling audit data When a connection is established Then TLS 1.2+ is enforced, weak ciphers are rejected, and plaintext requests are refused with 400 and logged Given audit data is stored in databases, object storage, or backups When data at rest is inspected Then AES-256 (or stronger) encryption at rest is enabled and keys are managed by a KMS with access policies restricting use to the audit services Given a key is rotated When rotation completes Then data remains readable by authorized services, no plaintext exposure occurs, and the rotation event is logged with key alias and time
Data Minimization via Tokenization and Consent References
Given a tap event is transformed into an audit record When the record is persisted Then resident identifiers are stored as tokens, and consent is stored as a reference to a snapshot id; no PHI content is persisted in the audit record Given an export of audit records is created When the export is inspected Then only tokens and consent snapshot references appear; any PHI fields are absent or redacted and a data minimization statement is present in the manifest Given a user attempts to include PHI in a custom field When the record validation runs Then the write is rejected and a data-minimization violation is logged in the audit-of-audit

DuoTap Approvals

Requires two distinct badge taps for sensitive actions like consent overrides or role escalation. Builds in a simple, compliant co‑sign process that prevents errors and protects resident dignity without adding passwords.

Requirements

Dual-Badge Co-Sign Core
"As a caregiver, I want sensitive actions to require a colleague’s tap in addition to mine so that approvals are accurate, compliant, and protected from single-person mistakes."
Description

Require two distinct NFC badge taps from separate authenticated users to authorize sensitive actions such as consent overrides, role escalation, and PHI-related updates. Enforce uniqueness (the same badge cannot fulfill both taps) and a configurable time window (e.g., 90 seconds) between taps. Lock the pending action until the second tap is received and both users’ roles are validated against KinLoop’s directory. Operate tap-only without introducing passwords or PINs. Ensure the flow works on caregiver Android devices with built-in NFC, validates device trust status, and gracefully handles cancellations or timeouts without committing the action.

Acceptance Criteria
Consent Override Approved with Two Distinct Badges Within Time Window
Given a caregiver initiates a consent override requiring co-sign And the device is trusted and NFC is enabled And the co-sign window is set to 90 seconds When User A taps their NFC badge And within 90 seconds User B (a different user with a different badge) taps their NFC badge Then the system validates both users against KinLoop’s directory And confirms both roles are authorized for consent overrides per policy And authorizes and commits the consent override And records an audit entry with action ID, both user IDs, device ID, timestamps, and outcome Success And displays a success confirmation to the initiator
Rejection of Same Badge Used Twice for Co-Sign
Given a pending co-sign exists after the first valid tap by User A When the same badge is presented again for the second tap Then the second tap is rejected with a message requiring a distinct co-signer And the pending action remains locked until a different user taps or the request times out And no partial data is committed and no role changes or overrides occur
Pending Action Timeout and Cancellation Without Commit
Given a pending co-sign exists after the first valid tap And the time window is 90 seconds When no valid second tap is received within 90 seconds or the initiator cancels Then the pending action is canceled and the lock is released And no changes are committed to the sensitive action And an audit entry is recorded with outcome Timed Out or Canceled and includes timestamps And the UI returns to its pre-approval state
Device Trust and NFC Availability Gate DuoTap Flow
Given the caregiver device is not trusted per KinLoop device attestation or NFC is disabled When a sensitive action requiring co-sign is initiated Then the DuoTap flow is blocked before the first tap And a descriptive error indicates the device trust or NFC issue And an audit entry "Blocked - Device Trust/NFC" is recorded with device ID and reason And no sensitive data is committed and no partial state is left locked
Admin-Configurable Co-Sign Time Window Enforcement
Given an admin updates the co-sign time window to 30 seconds in KinLoop settings When a co-sign is initiated thereafter on any caregiver Android device Then the system enforces a 30-second limit for the second tap And the new value applies without app reinstall or logout and persists across app restarts And audit entries for the co-sign include the configured window value used
Role Validation Blocks Unauthorized Co-Sign Attempts
Given a co-sign is requested for role escalation When either tapped user lacks the required permission per KinLoop directory policy Then the co-sign is denied and the lock is cleared And the denial message indicates insufficient privileges without exposing PHI And an audit entry "Denied - Role" is recorded including which user failed validation And no role escalation or sensitive update is committed
Tap-Only UX Without Passwords or PINs
Given a co-sign flow is in progress on a caregiver Android device with NFC When users complete the two required taps Then no password or PIN prompts are presented at any point in the flow And all interactions are completed via NFC taps and on-screen confirmations only And the UI shows a clear pending status with a cancel option until the second tap is received
Sensitive Action Policy Rules
"As an administrator, I want to configure which actions and contexts require DuoTap so that compliance is enforced consistently without slowing routine work."
Description

Provide a configurable policy engine that defines when DuoTap is required based on action type, resident consent state, user role, shift, location, and time-of-day. Allow administrators to manage rules per facility and program with versioning and staged rollout. Support defaults that require DuoTap for consent overrides and role escalations while allowing exceptions for routine updates. For emergencies, permit the action to proceed as “pending co-sign” with constrained distribution until a second tap is captured within a policy-defined SLA. Surface rule rationale in-app to improve transparency and training.

Acceptance Criteria
Default DuoTap Enforcement for Sensitive Actions
Given the action type is Consent Override or Role Escalation and the user submits the action, When policy evaluation occurs, Then the system requires two distinct badge taps from two different user IDs within 60 seconds before the action is finalized. Given the same badge is presented twice or two badges map to the same user ID, When approval is attempted, Then the system blocks completion and displays “Second approver must be a different user,” and logs the rejection. Given the action type is Routine Update and the resident consent state is Consenting with no escalation, When the user submits the update, Then DuoTap is not required and the action completes normally. Given facility has no custom policy, When any sensitive action is attempted, Then platform defaults apply requiring DuoTap for Consent Overrides and Role Escalations.
Rule Evaluation Across Policy Factors
Given active policy rules include conditions on action_type, consent_state, user_role, shift, location, and time_of_day, When an action is evaluated, Then the decision (Require DuoTap / Not Required / Emergency Pending Co‑Sign) is derived from the highest-priority matching rule with deterministic outcomes for identical inputs. Given two or more rules match, When priority is equal, Then the most recently published rule (latest publish timestamp) is applied as tiebreaker. Given a decision is produced, When telemetry is captured, Then the policy engine logs matched_rule_id, policy_version, evaluated_factors with values, and decision outcome. Given normal operating conditions, When evaluating policies, Then p95 decision latency is ≤150 ms and p99 ≤300 ms measured over 10,000 evaluations.
Facility and Program Scoped Policy Management with Versioning
Given an administrator with Policy:Manage permission, When creating or editing a policy, Then they can scope it to one or more Facilities and Programs and save as Draft. Given a Draft policy with version auto-incremented (major.minor), When Published with an effective start time, Then it becomes Active for the targeted scope at that time and the previously Active version becomes Deprecated. Given an Active policy is causing issues, When the admin selects Rollback, Then the prior Active version is restored within 60 seconds and all subsequent decisions use the restored version. Given any create, publish, rollback, or delete action, When the action completes, Then an immutable audit entry records actor, timestamp, scope, version, and change summary.
Staged Rollout and Targeting Controls
Given an Active policy version scheduled with a 10% rollout to Facility A / Program B, When the start time is reached, Then exactly 10%±1% of eligible users are bucketed via stable hashing and receive the new policy while others remain on the prior version. Given the admin adjusts rollout from 10% to 50%, When saved, Then targeting updates propagate and take effect within 2 minutes. Given the admin triggers an Emergency Stop for the rollout, When confirmed, Then all users revert to the last stable version within 2 minutes and the halted version is set to Paused. Given staged rollout is in progress, When metrics are viewed, Then decisions, DuoTap prompts, and emergency bypass counts are reported per version and scope.
Emergency Pending Co‑Sign Flow with SLA and Constrained Distribution
Given Emergency Bypass is enabled by policy and a user invokes it for a sensitive action, When the action is submitted, Then the action proceeds with status Pending Co‑Sign and content distribution is constrained to staff-only; family digests and external notifications are suppressed. Given the action is Pending Co‑Sign, When a second distinct badge is tapped by an eligible co‑signer within the SLA (e.g., 2 hours, configurable per policy), Then the action finalizes and normal distribution rules apply; the audit log captures both approvers and timestamps. Given the SLA expires without a valid second tap, When the timer elapses, Then the action is auto-quarantined (hidden from external recipients), an alert is sent to administrators, and release requires an admin override recorded in the audit trail. Given any Emergency Bypass occurs, When daily summaries are generated, Then a report lists all pending, completed, and expired bypasses for the last 24 hours.
In‑App Rule Rationale Transparency
Given a DuoTap decision is presented to a user, When the user taps Why? on the prompt or decision banner, Then within 1 second the app shows: decision type, matched rule name/ID, policy version, and factor values (action type, consent state, role, shift, location, time-of-day) that led to the decision. Given the rationale view is displayed, When rendering sensitive data, Then no PHI beyond resident initials and room number is shown. Given a decision is made, When logs are written, Then the rationale payload is stored in the audit trail for 30 days and is exportable by administrators as CSV/JSON.
DuoTap Co‑Sign Integrity and Auditability
Given a DuoTap sequence starts, When two badges are read, Then the system verifies the user IDs are distinct, both users hold a policy-permitted co‑sign role, and both are within their shift window (±15 minutes grace) for the facility; otherwise the approval is denied unless Emergency Bypass is invoked. Given a DuoTap is in progress, When the second badge is not presented within 60 seconds on the same device session, Then the approval request times out and must be restarted. Given any DuoTap attempt (success, rejection, or timeout), When audit entries are created, Then they include initiator user ID, co‑signer user ID (if any), timestamps, facility, location zone, device ID, policy version, matched rule ID, decision, and rationale hash, stored immutably and queryable by administrators. Given a single co‑signer approves more than 3 pending items from the same initiator within 10 minutes, When the fourth approval is attempted, Then a soft warning is displayed and an admin dashboard flag is raised for review.
Offline DuoTap with Deferred Verification
"As a caregiver working in low-connectivity areas, I want DuoTap to work offline so that my work continues without delays while still meeting approval requirements."
Description

Enable DuoTap to function without network connectivity by capturing both badge tap events locally, signing them with a device key, and queuing them for server validation. Execute the local action as pending and block any outbound family distribution or record changes that depend on the approval until the backend confirms both identities and policy compliance. Provide clear offline and sync states, automatic retry, and conflict resolution if user status or policy changed while offline.

Acceptance Criteria
Offline capture and pending execution of DuoTap approval
Given the device has no network connectivity And a caregiver initiates a sensitive action requiring DuoTap When the first badge is tapped Then the app records Tap 1 locally with badge ID, timestamp, device ID, and action ID And when a second, distinct badge is tapped within 60 seconds Then the app records Tap 2 locally and verifies it is not the same badge as Tap 1; if same, the attempt is canceled and the user is prompted to retry And then the app marks the sensitive action as Pending Approval (Offline) And then no family-facing distribution, EMR export, or policy-protected record mutation becomes visible externally until backend confirmation And the UI shows a clear "Pending—Offline" status and the action appears in the pending queue
Deferred server verification on reconnect and commit or reject
Given one or more pending offline DuoTap approvals are queued And network connectivity is restored When the client initiates sync Then each queued approval payload (including both tap events and signatures) is sent to the server in FIFO order And then the server validates both identities, role/permission, consent policies, and time window And if validation passes Then the server returns Approved and the client commits the sensitive action, triggers any allowed family distribution, and updates local state to Approved—Synced And if validation fails Then the server returns Rejected with a reason code and the client marks the item Rejected—Policy/Identity without committing any external changes
Automatic retry and manual sync controls
Given there are pending approvals and the last sync attempt failed due to a transient error When automatic retry is enabled Then the client retries with exponential backoff (initial 5s, doubling to a max of 5m) with jitter, for up to 24h or until success And when a user taps "Sync Now" Then the client immediately attempts sync regardless of backoff And when an error is terminal (e.g., invalid signature) Then the client stops auto-retries for that item and surfaces the failure reason to the user
Conflict resolution when identities/policies changed offline
Given a queued approval references a cosigner or initiator whose role, employment status, or consent policy changed while offline When the server evaluates the queued approval Then the server returns a Conflict reason code if the approval no longer complies And then the client reverts any provisional local UI state for the action, marks it Rejected—Conflict, and prevents distribution And then the client offers a guided re-attempt that requires a fresh DuoTap under current policy (online) And the event is logged for audit with the conflict details
Device key signing and server-side tamper verification
Given the device has a provisioned asymmetric keypair stored in secure hardware or OS keystore When each tap event is recorded locally Then the app packages device ID, action ID, badge ID (hashed), timestamps, and a monotonic sequence number and signs the payload with the device private key And when syncing Then the server verifies signature validity, sequence ordering, and timestamp freshness; unsigned or invalid-signature items are rejected with reason InvalidSignature And the client prevents editing or deleting the contents of queued items; attempted modification is blocked and logged locally
Local queue durability and capacity limits
Given pending approvals exist When the app is force-closed or the device reboots Then all queued approvals persist and are available on next launch with their original data and status And when the queue exceeds 500 items or local storage used by the queue exceeds 10 MB (whichever comes first) Then the app blocks creation of new pending approvals, informs the user to sync, and does not delete existing queued items And when space is freed by successful sync or manual clearing of failed items Then creation of new pending approvals is re-enabled
Immutable Audit Logging & Export
"As a compliance officer, I want a complete, tamper-evident record of DuoTap approvals so that audits and investigations can be completed quickly and confidently."
Description

Record every DuoTap event in an append-only audit trail including action type, resident identifier (pseudonymized where required), initiator and co-signer IDs and roles, timestamps, device ID, location (if enabled), policy version, and outcome. Chain log entries with tamper-evident hashing, enforce retention policies, and support redaction rules for privacy. Provide filtered search, on-screen review, and export to CSV/PDF and webhook/SIEM destinations. Generate alerts for anomalies such as repeated timeouts, attempted self co-sign, or high-frequency overrides on a resident.

Acceptance Criteria
Record DuoTap Approval Event to Immutable Audit Log
Given a user completes a DuoTap action (e.g., consent override or role escalation) When both distinct badges are tapped and the action outcome is determined Then an append-only audit entry is written with fields: action_type, resident_identifier (pseudonymized when policy requires), initiator_id, initiator_role, cosigner_id, cosigner_role, timestamp_utc, device_id, location (if enabled), policy_version, outcome, reason_code (if fail/timeout/cancel), correlation_id, entry_hash, previous_entry_hash And the entry is immutable via UI/API (no update/delete endpoints) and stored in write-once class storage And validation failures are logged as outcome=fail with reason_code, without creating any partial/alterable records And attempts where the same badge is used twice are recorded with outcome=fail and reason_code=self_cosign_attempt
Tamper-Evident Hash Chain Integrity Verification
Given an existing audit log with chained entries When an integrity check runs on demand or nightly Then entry_hash = SHA-256(canonical_payload || previous_entry_hash) for every entry And any mismatch sets tamper_flag=true, records an integrity_alert event, and notifies the configured security channel And integrity checks span partitions/rotations using a persisted genesis hash and inter-file anchor records And the integrity verification result is included in exports and on-screen reports
Retention Enforcement and Privacy Redaction Compliance
Given organizational retention and redaction policies are configured When an entry exceeds its retention period Then its content is redacted per policy while preserving headers (timestamps, action_type, hash pointers) and inserting a non-editable tombstone marker And the redaction action itself is logged with actor=system and linked to the original entry And the hash-chain continuity remains valid after redaction When a resident privacy rule requires pseudonymization or late-stage redaction Then resident identifiers are pseudonymized or redacted within 30 minutes and excluded from exports unless permitted by role
Filtered Search and On-Screen Audit Review
Given an authorized admin opens the Audit console When they filter by date range, action_type, resident, initiator_id, cosigner_id, outcome, device_id, location, policy_version, and anomaly flags Then the results reflect all filters, return the first page (<=50 entries) sorted by timestamp desc, and display a total count And the detail view shows all non-redacted fields including entry_hash and previous_entry_hash, provides copy controls, and offers no edit/delete actions And permission rules restrict visibility to facilities and residents allowed by the user’s role; redacted fields never render
Export to CSV/PDF and Streaming to Webhook/SIEM
Given a user with export permission selects a filtered set of audit entries When Export CSV is requested Then the system generates a UTF-8 CSV with header row, escaped values, ISO 8601 UTC timestamps, and pseudonymized identifiers per policy, and logs the export event When Export PDF is requested Then the PDF includes a tabular report and an integrity summary (genesis hash, last hash, verification status) and is digitally signed When a webhook/SIEM destination is configured and enabled Then matching events stream in near real time over HTTPS (TLS 1.2+), signed with an HMAC secret, include idempotency keys, retry with exponential backoff, and dead-letter after the configured retry limit And all exports/streams exclude redacted fields and include outcome and reason_code
Anomaly Detection and Alerting for Risky Patterns
Given anomaly thresholds are configured When >=3 DuoTap timeouts by the same initiator occur within 10 minutes Then an alert with category=excessive_timeouts is generated, sent to configured channels, and logged When a user attempts self co-sign Then an alert with category=self_cosign_attempt is generated, the action is blocked, and the attempt is logged When >5 overrides on the same resident occur within 24 hours Then an alert with category=high_frequency_overrides is generated and included in exports and SIEM streams And alerts include links to related entries and are de-duplicated within a 5-minute window
Offline Capture and Idempotent Sync of Audit Events
Given a device is offline during a DuoTap action When the action completes locally Then an encrypted local queue stores the pending audit record with client_id and idempotency_key When connectivity is restored Then the server ingests the record exactly once, preserves original event timestamps and device_id, assigns server sequence and hash chaining, and prevents duplicates via idempotency_key And if sync fails, the device retries with exponential backoff and shows a warning until sync succeeds And server-side ingestion applies redaction/pseudonymization rules before the entry becomes searchable or exportable
DuoTap UI & Accessibility
"As a caregiver in a busy environment, I want a simple, accessible approval flow so that I can complete co-signs quickly without confusion or errors."
Description

Deliver a clear, low-friction UI that guides users through first and second taps with large touch targets, progress states, haptic and audio cues, and concise microcopy. Indicate required co-signer role, remaining time, and cancel options. Ensure WCAG-compliant color contrast, screen reader labels, and multilingual strings. Minimize cognitive load so the flow completes in under 20 seconds in typical conditions and operates reliably with gloves and common device cases.

Acceptance Criteria
Primary Tap UI: Large Targets and Guidance
Given a user initiates a DuoTap-required action in portrait mode When the DuoTap UI is presented Then the primary “Tap badge” control has a minimum hit area of 48x48 dp (Android) or 44x44 pt (iOS) with ≥8 dp/pt spacing around it And the on-screen instruction is ≤80 characters, sentence case, and visible without scrolling on a 5.5" display And the initial progress state reads “Awaiting first tap” When the first tap is accepted Then the progress state updates to “1 of 2 complete” within 300 ms and the second-tap control becomes primary focusable
Co-signer Role, Countdown, and Cancel
Given the first tap is accepted When the second tap is required Then the required co-signer role label is displayed verbatim from configuration (e.g., “Charge Nurse”) adjacent to the second-tap control And a countdown timer in mm:ss is visible and updates ≥1 Hz; default duration is 60 s (admin-configurable 30–120 s) And a persistent Cancel button with ≥44x44 pt hit area is visible on-screen When Cancel is tapped Then the DuoTap flow aborts with confirmation (“Cancel approval?”) and returns to the prior screen within 500 ms with no state committed When the same badge/identity is presented for the second tap Then completion is blocked, an inline error “Different co-signer required” is shown, distinct error feedback is provided, and only the second-tap step is reset
Haptic and Audio Feedback on Tap Events
Given the device supports haptics When a tap is accepted Then a success haptic triggers within 200 ms and a success tone plays if device volume > 0 and audio cues are enabled When a tap is rejected or times out Then an error haptic pattern triggers within 200 ms, an error tone plays if enabled, and an inline error message is shown And when the device is in Silent or Do Not Disturb Then no audio is played and an equivalent visual cue is displayed; screen readers announce the state change
Screen Reader Labels, Hints, and Focus Order
Given VoiceOver or TalkBack is enabled When the DuoTap UI opens Then initial focus lands on the DuoTap title, then instruction, then first-tap control, then Cancel; after first tap, focus moves to the second-tap control And all actionable elements expose programmatic names and hints describing action and state (e.g., “Tap badge. Awaiting first tap”) And dynamic updates (first tap complete, role required, countdown) are announced via a polite live region without stealing focus And countdown announcements are throttled to no more than once every 5 seconds
WCAG Color Contrast and Non-Color Indicators
Given the DuoTap UI is rendered Then body text and labels under 18 pt/14 pt bold meet contrast ≥4.5:1, large text meets ≥3:1, and non-text UI (including focus ring) meets ≥3:1 And success, pending, and error states are indicated by at least one non-color cue (iconography or text) in addition to color And focused elements have a visible focus indicator with a thickness ≥2 px and contrast ≥3:1 against adjacent colors
Multilingual Strings and Layout Resilience
Given device language is English or Spanish When the DuoTap UI is shown Then all static and dynamic strings are localized with no placeholder keys visible And the layout accommodates ≥30% text expansion without truncating critical labels or pushing controls off-screen on a 5.5" display in portrait And if a translation is missing, English is used as fallback and a telemetry event with the missing key is logged
Performance, Gloves, and Case Reliability
Given typical network conditions (≥10 Mbps downlink, <100 ms RTT) When a trained caregiver completes the DuoTap flow using nitrile gloves (≥5 mil) on a device with a 2 mm silicone case Then the median completion time across 20 trials by 5 users is ≤15 s and the 90th percentile is ≤20 s And first-attempt recognition success rate for both taps is ≥95% across those trials, with retry prompts appearing within 500 ms on failure And all touch controls register gloved taps with ≥95% success rate without requiring increased pressure
Badge Tech & Identity Integration
"As an IT admin, I want DuoTap to work with our existing badges and directory so that rollout is fast and secure without new hardware or passwords."
Description

Support common healthcare badge technologies (ISO 14443 Type A/B, MIFARE DESFire EV1/EV2, and compatible mobile credentials where available) via device NFC. Map badge tokens to KinLoop users through directory sync with the facility’s IAM/HR system, including role and status changes, and enforce local caching with short TTL and revocation checks. Encrypt badge identifiers at rest and in transit, avoid storing raw card secrets, and attest device integrity via MDM where available. Provide admin tools for test reads, enrollment, and lost/stolen badge workflows.

Acceptance Criteria
NFC Badge Compatibility: ISO 14443 A/B and MIFARE DESFire EV1/EV2
Given a device with NFC enabled and KinLoop running, When a compliant ISO 14443 Type A or Type B badge is tapped, Then the app captures a stable badge identifier and confirms read within 1.5 seconds at the 95th percentile. Given a MIFARE DESFire EV1 or EV2 badge, When tapped, Then the app acquires a non-secret, stable identifier without reading or storing application keys and confirms read within 1.5 seconds at the 95th percentile. Given a supported mobile NFC credential presented via the OS, When tapped, Then the app receives the OS-provided token and treats it equivalently to a physical badge token. Given an unsupported card technology, When tapped, Then the app displays an “Unsupported badge” error within 2 seconds and logs the failure with reason code. Given rapid consecutive taps, When two different badges are tapped within 5 seconds, Then each read is captured as a distinct event with correct token separation.
Directory Sync Mapping and Role/Status Propagation
Given a badge token exists in the IAM/HR directory mapping, When the badge is read, Then KinLoop resolves the user account, primary role, and facility within 500 ms at the 95th percentile after network response. Given a new user–badge association is added in the IAM/HR system, When directory sync runs, Then the mapping is created in KinLoop within 5 minutes. Given a user’s role changes in IAM/HR, When directory sync completes or a webhook event is received, Then the new role is reflected in KinLoop within 5 minutes. Given a user is terminated or suspended in IAM/HR, When the revocation event is received, Then the badge is rejected on next tap and no later than 1 minute from event receipt; and in all cases within 5 minutes. Given an attempt to map a badge token already associated to another active user, When enrollment is submitted, Then the system blocks the change and requires explicit reassign authorization by an admin with audit log entry.
Local Cache TTL and Revocation Enforcement
Rule: The local identity cache has a default TTL of 15 minutes, configurable between 5 and 30 minutes per facility. Given the device is online, When a badge is read, Then KinLoop validates the token against the server and revocation list before granting access. Given the device is offline and the cached entry is within TTL and not revoked, When a badge is read, Then access is granted and the event is queued for sync. Given the device is offline and the cached entry is expired or marked revoked, When a badge is read, Then access is denied with “Revalidation required” and no sensitive action is allowed. Given a revocation is received from the server, When the device is online, Then the corresponding cached entry is invalidated immediately, regardless of remaining TTL.
Encryption and Secret Handling for Badge Identifiers
Rule: Badge identifiers at rest are encrypted using platform keystore‑backed AES‑256‑GCM. Rule: All badge identifiers in transit use TLS 1.2 or higher; connections with weaker protocols are refused. Rule: Raw card secrets (e.g., DESFire keys, sector keys) are never read or stored by the app or server. Given a badge token must be persisted, When storing, Then only a salted HMAC‑SHA‑256 of the token (with per‑tenant salt) is stored; the raw token is never written to disk. Given a key rotation event, When new encryption keys are activated, Then existing data is re‑encrypted within 24 hours without data loss and with continuous operation.
Device Integrity Attestation via MDM
Given the facility uses MDM with device attestation, When KinLoop starts or returns to foreground, Then it verifies device compliance via MDM and OS integrity APIs before enabling badge reads. Given attestation fails (e.g., non‑compliant, jailbroken/rooted, not enrolled), When a badge is tapped, Then the read is blocked and the user sees “Device not compliant—contact IT”. Given attestation passes, When a badge is tapped, Then the read proceeds; attestation is rechecked at least every 12 hours or on policy change signal. Given MDM is not deployed at a facility, When configured by an admin, Then OS‑level integrity checks are required and badge reads are allowed only if checks pass.
Admin Tools: Test Read and Enrollment
Given an admin opens the Badge Tools, When a test read is performed, Then the tool displays detected technology (Type A/B/Desfire/mobile), anonymized token, and mapped user (if any). Given a badge is unassigned, When the admin enrolls it to a user, Then the mapping is created, effective immediately, and an audit log records admin ID, user ID, badge token hash, timestamp, and IP/device. Given a badge is already assigned, When the admin attempts to reassign, Then the system requires explicit confirmation and records the previous and new user in the audit log. Given enrollment completes, When the badge is tapped, Then KinLoop resolves to the newly assigned user on first attempt.
Lost/Stolen Badge Workflow and Auditability
Given an admin marks a badge as lost or stolen, When saved, Then the badge token is added to the revocation list immediately and rejected on next tap. Given a badge is marked lost/stolen, When viewed in admin tools, Then status shows “Revoked” with timestamp, actor, and reason. Given a replacement badge is issued, When linked to the same user, Then the old badge remains revoked and the new badge functions on first tap. Rule: All badge read attempts, enrollments, reassignments, revocations, and DuoTap approvals are logged with timestamp, device ID, facility, result code, and actor; logs are searchable and exportable by admins with proper permissions. Rule: Audit logs are retained for at least 1 year and are immutable to non‑auditor roles.
Failure Handling & Escalation Notifications
"As a unit lead, I want clear escalation and notifications when an approval is incomplete so that sensitive actions are resolved quickly and safely."
Description

Define deterministic outcomes for missing second taps, invalid badges, or expired windows: cancel and roll back the action, log the attempt, and notify the initiator. For pending co-sign scenarios (offline or emergency), create actionable tasks for qualified supervisors, escalate based on SLA, and pause any dependent content distribution until co-sign completes. Offer configurable time windows, SLAs, and notification channels (in-app, SMS, email) while maintaining passwordless operation; allow supervisor master-badge resolution where permitted by policy.

Acceptance Criteria
Missing Second Tap Within Window
Given an initiator completes the first badge tap for a sensitive action and an approval window is configured When no distinct second badge tap is recorded before the window expires Then the system cancels and fully rolls back the pending action with no side effects committed And an audit event is recorded with initiator ID, action, timestamp, and reason "second_tap_timeout" And the initiator receives an in-app notification of the cancellation within 10 seconds And, if enabled by policy and user preference, an SMS and/or email notification is sent within 60 seconds
Invalid or Non-Distinct Second Badge
Given the first badge tap has started a co-sign flow When the same badge is presented for the second tap or a badge without required role/permission or a revoked/expired badge is used Then the system immediately cancels and rolls back the action And displays an on-device error message within 2 seconds stating a distinct authorized badge is required And records an audit event with reason code (same_badge | insufficient_role | revoked | expired) And notifies the initiator via in-app notification; SMS/email if configured
Offline/Emergency Co-Sign Task & SLA Escalation
Given the second tap cannot be captured due to offline conditions or the initiator flags the action as emergency When the system detects a pending co-sign Then it creates an actionable task assigned to qualified supervisors per policy, including resident, action, initiator, reason, and expiration And delivers notifications to supervisors via configured channels And pauses the action from completing until co-sign or resolution occurs And if the task remains unresolved at the first SLA threshold, the system escalates to the next tier and re-notifies; continues until final tier or resolution And all escalations and notifications are logged with timestamps and recipients
Pause of Dependent Content Distribution
Given a sensitive action would distribute content (e.g., photo updates or digests) When the action awaits co-sign or is canceled Then dependent content remains hidden from family recipients and external feeds until co-sign succeeds And upon cancellation, the content is not distributed and any queued deliveries are purged And upon successful co-sign, distribution resumes only for authorized recipients And system state reflects correct distribution status in audit logs
Configurable Windows, SLAs, and Channels (Passwordless)
Given an administrator manages DuoTap settings When they configure the approval window duration, SLA tiers/timers, and notification channels (in-app, SMS, email) Then the new settings apply to newly initiated actions within 1 minute and do not retroactively change in-flight items And all flows remain passwordless; no password prompts are shown to any user And channel use respects both facility policy and individual notification preferences And configuration changes are captured in audit logs with before/after values and actor
Supervisor Master-Badge Resolution
Given policy permits master-badge use When a qualified supervisor presents a master-badge on a pending co-sign task Then the supervisor can approve or cancel the action without a password And the system requires a resolution reason selection and optional note And the outcome is executed immediately, with dependent content distribution unpaused on approve or purged on cancel And the event is logged with supervisor ID, reason, and timestamp
Comprehensive Audit Logging and Traceability
Given any co-sign attempt, cancellation, escalation, configuration change, or notification When the event occurs Then an immutable audit record is written with correlation ID, actors, roles, action, outcome, reason code, timestamps, and notification delivery results And audit records are queryable by correlation ID to trace end-to-end from initiation to final outcome And log integrity is preserved across offline periods with queued writes syncing on reconnect

Renewal Radar

Proactively tracks consent expirations and grace windows, surfacing color‑coded status right on the resident list and at capture. Sends smart reminders to families for renewal via SMS/email before lapses, and offers one‑tap outreach from the app. If a consent nears or reaches expiry, KinLoop warns or auto‑pauses posting for that resident until renewed, preventing last‑minute blocks, audit risk, and awkward follow‑ups.

Requirements

Consent Lifecycle Data Model & Sync
"As an administrator, I want a reliable consent record per resident with clear lifecycle fields so that the system can accurately determine status and drive reminders and posting rules without manual tracking."
Description

Implement a resident-centric consent object with fields for consent type, effective date, expiry date, grace window, status (Active, Expiring Soon, Grace, Expired, Paused), authorized contacts, communication channels (SMS/email), facility policy references, and audit metadata (who/when/how consent was captured). Provide APIs and background jobs to synchronize with external EHR/roster sources and CSV import, resolve duplicates, and handle timezone-aware dates. The model must support multi-facility configurations, per-facility policy overrides, and historical versioning so changes are non-destructive and auditable. Encrypt sensitive data at rest and in transit, restrict access by role, and expose a read-optimized cache for fast UI lookups.

Acceptance Criteria
Consent Object Creation & Required Field Validation
Given a facility admin submits a new consent with resident_id, consent_type, effective_date, expiry_date, grace_window_days, authorized_contacts[], channels[], policy_ref_id, and capture_method, When POST /consents is called, Then a unique consent_id is created and HTTP 201 is returned with persisted fields. Given a required field is missing or invalid (e.g., expiry_date <= effective_date), When POST /consents, Then HTTP 400 is returned with field-level error codes for each invalid field. Given authorized_contacts includes IDs not linked to the resident/facility, When POST /consents, Then HTTP 400 is returned with code INVALID_CONTACT and the offending contact IDs. Given channels contains values outside {sms,email}, When POST /consents, Then HTTP 400 is returned with code INVALID_CHANNEL and the offending values. Given a multi-facility deployment, When a consent is created, Then consent.facility_id is mandatory and persisted. Given capture_method and actor_user_id are provided, When saved, Then audit metadata includes actor_user_id, captured_at (UTC), capture_method, and source (api/ui/import/sync).
Status Derivation and Transitions
Rule: Paused overrides all other statuses when consent.paused = true. Rule: Active when now_in_facility_tz ≥ effective_date AND now_in_facility_tz < (expiry_date - expiringSoonDays) AND paused = false. Rule: Expiring Soon when now_in_facility_tz ≥ (expiry_date - expiringSoonDays) AND now_in_facility_tz < expiry_date AND paused = false; expiringSoonDays comes from facility policy override, default 14. Rule: Grace when now_in_facility_tz ≥ expiry_date AND now_in_facility_tz < (expiry_date + grace_window_days) AND paused = false. Rule: Expired when now_in_facility_tz ≥ (expiry_date + grace_window_days) AND paused = false. Given a status change is detected during evaluation, When transition occurs, Then a status_history entry is appended with from_status, to_status, evaluated_at (UTC), and evaluator (job/api). Given facility policy expiringSoonDays is updated, When the next evaluation job runs, Then statuses are recalculated within 15 minutes to reflect the new threshold.
Timezone-Aware Date Handling
Rule: effective_date and expiry_date are stored as instants (UTC) with original timezone_id persisted; status evaluation uses facility timezone. Given effective_date = 2025-09-01T00:00 America/Los_Angeles, When stored, Then internal UTC equals 2025-09-01T07:00Z and timezone_id = America/Los_Angeles. Given now = 2025-11-03T00:30Z and facility timezone = America/Los_Angeles, When evaluating a consent expiring 2025-11-03T00:00 in facility TZ, Then status reflects post-DST local time correctly (not off by 1 hour). Given a CSV date "2025-10-01" without time or offset, When imported for a facility in America/New_York, Then it is interpreted as 2025-10-01T00:00 America/New_York and normalized to UTC. Given an API payload includes ISO8601 with offset, When ingested, Then the exact instant is preserved with no double conversion. Rule: grace_window_days are applied as calendar days in facility timezone boundaries, not fixed 24-hour multiples.
External EHR Sync and Duplicate Resolution
Given the hourly sync job runs, When the EHR source returns consent data, Then the system upserts records idempotently using (facility_id, resident_external_id, consent_type, source_id) as identity keys. Given a duplicate consent for the same resident/facility/type from the same source, When processed, Then a new version is created only if incoming updated_at > current_version.updated_at; otherwise it is ignored as a no-op. Given the same payload is processed twice, When the job re-runs, Then no additional versions are created and the second run reports 0 changes. Given conflicting updates from multiple sources, Then precedence is applied: manual > csv_import > ehr; lower-precedence updates are stored as candidate metadata but do not advance current_version. Given a resident exists in multiple facilities, When syncing, Then updates affect only the matching facility_id and never cross-link to other facilities. Given a record fails validation, When encountered during sync, Then it is written to a dead-letter queue with error details and the batch continues; metrics emit counts for processed, upserted, skipped, failed.
CSV Import with Validation and Versioning
Given a CSV with required headers (resident_id, consent_type, effective_date, expiry_date, grace_window_days, authorized_contacts, channels, policy_ref_id), When POST /consents/import is called, Then a job_id is returned and the file is queued for processing. Given rows contain invalid values (e.g., malformed date, unknown contact id, invalid channel), When processed, Then those rows are rejected with row_numbers and error codes; valid rows are imported. Given a valid row matches an existing consent by (resident_id, facility_id, consent_type), When imported, Then a new immutable version is created with version_number incremented and current_version_id updated. Given the same CSV is imported again, When processed, Then import is idempotent and does not create duplicate versions for unchanged rows. Given the job completes, When querying GET /consents/import/{job_id}, Then a summary is returned with counts: processed, created, updated, failed, and links to error details. Given rows are imported, Then audit metadata is set with method = csv_import, actor_user_id, source_file_id, and processed_at (UTC).
Security: Encryption, Transport, and Role-Based Access
Rule: All consent APIs enforce TLS 1.2+; HTTP requests without TLS are rejected with 403 and no redirect. Rule: Sensitive columns (authorized_contacts, communication_channels, audit_metadata) are encrypted at rest using AES-256 with managed KMS keys; direct database reads show ciphertext; keys are rotated per policy. Given a caregiver role token, When calling GET /consents/{resident_id}, Then only read-only, least-privilege fields are returned (status, effective_date, expiry_date, grace_window_days, policy_ref_id); PII for authorized_contacts is redacted. Given an admin or compliance role token, When calling POST/PUT/PATCH, Then create/update succeeds with 2xx and full fields; actions are fully audited. Given an integration service account with scope=consents:write, When calling the sync endpoint, Then upsert is permitted; without the scope, 403 is returned. Given any create/update/delete on a consent, When committed, Then an audit log entry is persisted with actor, action, before/after snapshots, request_id, and timestamp (UTC).
Read-Optimized Cache for UI Lookups
Given 500 residents in a facility, When the UI requests GET /consents/status?facility_id={id}, Then P95 response time ≤ 75 ms via the read-optimized cache. Rule: Cache entries are keyed by (facility_id, resident_id) and invalidate within 2 seconds of a consent version change or status transition. Rule: Cache TTL defaults to 5 minutes; entries are updated via write-through on changes and warmed every 15 minutes by a background job. Given a cache miss, When a request is made, Then the system falls back to the read-optimized database view and populates the cache without user-visible errors. Given a cache outage, When serving requests, Then P95 latency remains ≤ 250 ms using the database path and error rate ≤ 0.1%. Rule: Eventual consistency window between write and cache visibility is ≤ 2 seconds under normal operation.
Color-Coded Status Badging (List & Capture)
"As a caregiver, I want clear visual indicators of a resident’s consent status where I work so that I can avoid posting when consent is near expiry or expired."
Description

Display real-time, color-coded consent status for each resident on the resident list and at the media capture screen. Use distinct labels and icons for Active, Expiring Soon, Grace, Expired, and Paused with WCAG AA-compliant contrast and text alternatives. Provide quick tooltips that show expiry date, grace end, and renewal path. Ensure badges update instantly from the cache, work offline with last-known state, and reconcile on reconnect. Respect role permissions so caregivers see actionable warnings while admins see configuration links.

Acceptance Criteria
Resident List Badges: Accurate, Distinct, and Accessible
Given the resident list is opened and the app has a last-known consent state for each resident When the list finishes rendering Then each resident displays a badge with one of [Active, Expiring Soon, Grace, Expired, Paused] that matches the last-known state And the badge includes a status label and a distinct icon per status (not color-only) And badge text contrast is >= 4.5:1 and icon/graphic contrast is >= 3:1 per WCAG 2.1 AA And status colors remain distinguishable under deuteranopia, protanopia, and tritanopia simulations And a screen reader announces "<Resident Name> — <Status>" And no badge takes more than 300 ms to render from cache after the list becomes visible
Capture Screen Status and Posting Rules
Given a user opens the media capture screen for a resident When the resident status is Active Then posting controls are enabled and no blocking warnings are shown Given a user opens the media capture screen for a resident When the resident status is Expiring Soon or Grace Then a non-blocking inline warning is shown with the current status And posting controls remain enabled Given a user opens the media capture screen for a resident When the resident status is Expired or Paused Then a blocking banner is shown indicating posting is disabled And the Post/Share action is disabled while Save as Draft remains available And a screen reader announces the blocking state on focus within 1 second
Tooltip Details: Dates and Renewal Path
Given a user taps the status badge or info icon on list or capture When the tooltip appears Then it displays the consent expiry date in the user’s local timezone (e.g., Aug 28, 2025) And if in Grace, it displays the grace end date And it includes a clear renewal path description or CTA label And the tooltip opens within 300 ms of the tap and can be dismissed via tap outside or ESC/back And the tooltip is keyboard-focusable and fully screen-reader readable Given the viewer is a Caregiver When viewing the tooltip Then configuration links are not visible And any CTA is limited to allowed actions (e.g., notify admin) Given the viewer is an Admin When viewing the tooltip Then a "Manage Consent" configuration link is visible and actionable
Cache-First Rendering and Instant Update
Given the app navigates to the resident list or capture screen When network is unavailable or slow Then the status badge renders from the local cache without waiting for network And the badge render occurs within 300 ms of the screen becoming visible Given the local cache receives a status change (e.g., via background sync or push) When the list or capture screen is visible Then the corresponding badge updates within 1 second without app restart And the updated status is consistent across list and capture for that resident
Offline Behavior and Reconnect Reconciliation
Given the device is offline and a last-known status exists When viewing badges on list or capture Then badges reflect the last-known status and indicate offline state non-intrusively Given a post is attempted offline while last-known status is Active/Grace/Expiring Soon When connectivity is restored and the server reports the status is Expired or Paused prior to upload Then the upload is blocked, the media is saved as Draft, and the user is notified of the status change within 2 seconds of reconnect Given connectivity is restored after being offline When the app syncs consent statuses Then all badges reconcile to server truth within 2 seconds And any visible tooltips refresh their dates and messaging accordingly
Role-Based Visibility and Authorization
Given a signed-in Caregiver views badges or tooltips When the status is Expiring Soon or Grace Then an actionable warning is visible (non-config) and any configuration links are hidden Given a signed-in Admin views badges or tooltips When any status is displayed Then a link or button to open Consent Settings is visible and opens the correct resident’s configuration screen Given an unauthorized role attempts to access admin configuration via deep link When the link is invoked Then access is denied with an appropriate message and no configuration data is exposed
Smart Reminder Engine (SMS/Email)
"As a family contact, I want timely, clear reminders with a direct action link so that I can renew consent before it lapses without phone tag."
Description

Create a scheduling service that sends renewal reminders to authorized contacts via SMS and email at configurable intervals (e.g., 30/14/7/3/1 days before expiry) with escalation into grace and post-expiry follow-ups. Support quiet hours, time zone alignment, throttling, and per-contact opt-out. Use message templates with facility branding and localized content, including secure renewal links and status context. Track delivery, opens, and clicks; retry on transient failures; and log all events to the consent audit trail. Allow admins to configure cadence and channels per facility and per consent type.

Acceptance Criteria
Admin-Configured Cadence and Channels
Given a facility admin sets a reminder cadence and channel preferences per consent type And a consent has a defined expiry date and authorized contacts When the scheduler evaluates pending consents Then reminders are queued at each configured offset before expiry for the specified channels And per-consent-type overrides take precedence over facility defaults And only authorized contacts for the consent type are targeted And changes to cadence or channels re-plan all future unsent reminders within 5 minutes And if the consent is renewed, all future unsent reminders for that consent are canceled within 5 minutes
Quiet Hours and Time Zone Alignment
Given a contact’s time zone is known and quiet hours are configured (e.g., 20:00–08:00 local) And a reminder is due during quiet hours When the system attempts to dispatch the reminder Then the send time is deferred to the next allowed window in the contact’s local time And no reminder is dispatched during quiet hours And daylight saving time transitions are respected for local calculations And facility-level quiet hours apply when contact time zone is unknown (using facility time zone)
Recipient Opt-Out and Throttling
Given a contact opts out of a channel (SMS STOP or email unsubscribe) for renewal reminders When future reminders are scheduled Then the opted-out channel is suppressed for that contact while other channels remain eligible And an opt-out confirmation is recorded and respected within 2 minutes Given the facility throttle is 120 messages per minute And 200 reminders are ready to send in a minute When dispatch occurs Then no more than 120 messages are sent in that minute And the remainder are queued and sent in subsequent minutes FIFO
Branded, Localized Templates with Secure Renewal Links
Given facility branding assets and localized templates exist for the consent type And the contact’s locale is available (fallback to facility default) When a reminder is generated Then the message uses the correct template, branding, and locale for the channel And includes a unique HTTPS renewal link bound to facility, consent, and contact And the link token expires per policy (e.g., 7 days) and is single-use And the message includes expiry date and grace status context And no personally identifiable information appears in the URL or query string
Delivery, Open, and Click Tracking with Retries
Given a reminder is dispatched When the provider returns delivery webhooks or events Then send, delivery, open (email), and click (email/SMS link) events are recorded with timestamps And transient failures (e.g., 429/5xx, carrier timeouts) are retried with exponential backoff up to 5 attempts within 24 hours And permanent failures (e.g., hard bounce, invalid number) are marked failed with no further retries and the channel is suppressed for that contact until updated And idempotency keys prevent duplicate sends and duplicate event ingestion
Consent Audit Trail Logging
Given any reminder lifecycle event occurs (scheduled, re-planned, sent, delivered, opened, clicked, bounced, failed, retried, canceled, opt-out) When the event is processed Then an immutable audit entry is appended to the related consent’s audit trail including timestamp, event type, channel, template ID, locale, contact ID (hashed), message ID, and link ID And audit entries are queryable by consent ID within 2 seconds And audit entries cannot be edited or deleted and are retained per retention policy
Grace and Post-Expiry Escalation
Given a consent enters its grace window before or after expiry per facility policy When reminders are scheduled during grace Then the cadence escalates to the configured grace cadence until renewal or max attempts reached And after expiry, post-expiry follow-up reminders are sent per configured cadence and max attempts And upon renewal, all grace and post-expiry reminders are canceled within 5 minutes And no further reminders are sent after max attempts are reached
Secure Family Renewal Flow (OTP + E‑Sign)
"As a family member, I want a secure, easy way to review and sign consent on my phone so that renewal takes minutes without logging into an app."
Description

Provide a mobile-first web flow launched from reminder links where the recipient verifies identity via one-time code (SMS/email), reviews facility-specific consent text, selects resident relationship, and completes an e-signature with timestamp and IP capture. Generate a tamper-evident PDF of the consent, store it securely, and update the consent record atomically on success. Support accessibility, localization, and device-agnostic rendering. Handle partial completions with resumable sessions, and fail-safe to keep posting paused if verification is not completed. Include consent text versioning and legal hold retention settings.

Acceptance Criteria
OTP Verification via Reminder Link
Given a valid reminder link tied to a resident and facility, When the recipient opens it, Then the flow displays the verification step with the preselected delivery channel matching the reminder (SMS or email). Given the recipient requests a one-time code, When the system sends the OTP, Then a 6-digit code is delivered via the selected channel within 5 seconds and a masked destination is shown. Given an issued OTP, When the correct code is entered within 10 minutes, Then identity is verified and the flow advances to consent review. Given an issued OTP, When an incorrect code is entered 5 times within 15 minutes, Then the verification is locked for 15 minutes and a generic error is shown. Given repeated OTP requests exceed 3 per 5 minutes, When another send is attempted, Then the request is throttled and the user is advised to wait. Given verification is not completed, When the link is closed, Then the resident’s posting state remains paused.
Consent Review and Relationship Selection
Given a verified recipient, When the consent page loads, Then the facility-specific consent text renders with its version number and effective date, localized to the browser language with fallback to English. Given a locale that uses right-to-left scripts, When the page renders, Then text direction and layout adjust to RTL without truncation. Given assistive technologies are used, When navigating the page, Then all controls have accessible names, meet WCAG 2.1 AA contrast, and are operable by keyboard. Given no relationship is selected, When Continue is pressed, Then submission is blocked and an inline error indicates the field is required. Given an allowed relationship is selected, When proceeding, Then the selection is persisted and included in the audit metadata. Given a mobile device (iOS Safari ≥14 or Android Chrome ≥96), When resizing or rotating, Then the layout remains responsive and readable without horizontal scrolling.
E‑Signature Capture with Timestamp and IP
Given the consent review is complete, When the signature step is reached, Then the user can provide a typed or drawn signature and must check an acknowledgment confirming e-signature intent. Given no signature or acknowledgment is provided, When Submit is pressed, Then submission is blocked with clear validation messages. Given a signature is submitted, When processing, Then the server records UTC timestamp to the second, public IP address, and user agent string. Given submission succeeds, When the confirmation screen displays, Then it shows the signer name, relationship, resident, facility, and timestamp in the selected locale’s format.
Tamper‑Evident PDF Generation and Secure Storage
Given a successful signature submission, When the record is created, Then a PDF is generated containing the full consent text, signer details, resident/facility, relationship, consent version, UTC timestamp, IP, and an embedded SHA-256 checksum of the content. Given the generated PDF, When any byte of the content is modified, Then the checksum verification fails and the system flags the document as tampered. Given the PDF is stored, When retrieval is attempted by an unauthorized user, Then access is denied and the attempt is logged. Given the PDF is stored, When retrieved by an authorized admin, Then the file downloads successfully and matches the stored checksum.
Atomic Consent Record Update and Posting Pause/Resume
Given the signature and PDF generation complete, When persisting the consent record, Then all fields (status Active, signer identity, relationship, consent version, timestamps, storage reference, checksum) are written atomically in a single transaction. Given any persistence step fails, When the transaction is rolled back, Then no partial data is saved and the resident’s posting remains paused. Given duplicate submissions from the same session occur, When the server processes them, Then idempotency ensures only one active record is created and subsequent attempts return the existing result. Given the consent record is activated, When checking the resident list, Then the consent status updates to current and posting is allowed.
Resumable Sessions for Partial Completions
Given a recipient verifies identity, When they abandon the flow before signing, Then a resumable session token persists for 7 days and the reminder link resumes at the last completed step. Given a session is resumed, When loading the flow, Then previously entered data (locale, relationship selection) is prefilled; signature input is blank until explicitly re-entered. Given a resumable session expires after 7 days, When the link is opened, Then the user is prompted to re-verify with a new OTP. Given multiple devices are used, When resuming on a different device, Then the session resumes with the same state after re-verification.
Consent Text Versioning and Legal Hold Retention
Given multiple consent text versions exist, When launching the flow, Then the latest effective version for the facility is displayed and its version identifier and content hash are recorded with the signature. Given a newer consent version is published, When an outstanding reminder is completed, Then the signer is presented with and signs the newer version; the prior signed record remains immutable. Given a legal hold is placed on a consent record, When a deletion or purge is requested, Then the action is blocked and an audit entry records the attempt. Given legal hold is active, When exporting records, Then the export includes a hold indicator and all associated artifacts (PDF, metadata, audit trail).
Auto‑Pause Posting & In‑App Warnings
"As a caregiver, I want the app to warn me and stop me from posting when consent has lapsed so that I stay compliant without second-guessing policies."
Description

Enforce posting rules based on consent state: warn at capture when consent is Expiring Soon or in Grace, and automatically block posting to families when Expired or Paused. Provide clear reasons, next steps, and a one-tap path to initiate outreach or view status details. Allow admins to define narrowly scoped overrides with justification and automatic expiry. Queue drafts locally when blocked and auto-release after renewal. Ensure behavior is consistent across photo, voice-to-text updates, and digests, while still applying auto-blur to non-consenting faces for unrelated residents.

Acceptance Criteria
Warn at Capture for Expiring Soon or Grace
Given a resident is in Expiring Soon state per policy, When a caregiver opens the capture screen for that resident, Then a non-blocking warning banner appears with severity color and text showing days until expiry, and capture remains allowed. Given a resident is in Grace state, When a caregiver opens the capture screen, Then a non-blocking warning banner appears with severity color and text showing time remaining in grace, and capture remains allowed. Given a resident is not in Expiring Soon or Grace, When a caregiver opens the capture screen, Then no consent warning is displayed. Given a resident is in Expiring Soon or Grace, When the resident list is viewed, Then the resident row displays a color-coded status indicator matching the state with accessible tooltip text.
Auto-Block Posting on Expired or Paused
Given a resident is in Expired or Paused state, When a user attempts to post any update (photo, voice-to-text, or digest inclusion), Then posting is blocked with a modal and no delivery occurs. Given a resident is in Expired or Paused state, When a user retries posting via any pathway, Then posting remains blocked until the state changes to an allowed state or a valid admin override exists. Given an update is in progress and the resident’s state changes to Expired before completion, When the system evaluates delivery, Then delivery is prevented and the item is moved to the local draft queue. Given a resident is in Active, Expiring Soon, or Grace state without additional restrictions, When posting, Then posting proceeds without a block.
Reason, Next Steps, and One-Tap Outreach/Status
Given any consent warning or block UI is shown, When displayed, Then it includes the current state, plain-language reason, time remaining or expiry timestamp (facility-local), and the next steps to resolve. Given a blocking modal is shown, When the user taps Contact Family, Then the one-tap outreach flow opens prefilled with the resident and appropriate family contacts. Given a warning or block UI is shown, When the user taps View Consent Status, Then the consent detail screen opens for that resident. Given the device is offline, When the user taps an outreach or status CTA, Then the action is queued with a visible offline indicator and executes on next connectivity.
Admin Scoped Override with Justification and Auto-Expiry
Given an admin has override permission and a resident is in Expired or Paused state, When attempting to post, Then the admin may create an override only after entering a required justification and selecting scope (resident and content type) within policy-defined limits and timebox. Given an override is active within its validity window, When posting content that matches the override scope, Then posting succeeds and the event is audit-logged with admin ID, timestamp, scope, and justification. Given an override reaches its auto-expiry or policy-defined max duration, When additional posting is attempted, Then the block resumes automatically without further admin action. Given a caregiver without override permission attempts to post under a block, When viewing options, Then no override creation option is available. Given an override exists, When viewing the resident’s consent status, Then the override details and expiry timestamp are visible.
Queue Drafts Locally and Auto-Release After Renewal
Given posting is blocked due to Expired or Paused, When a user attempts to post an update, Then the update is saved as a draft in a local encrypted queue with a visible queued state, timestamp, and reason. Given drafts are queued for a resident, When the resident’s consent is renewed and the device syncs the update, Then the queued drafts auto-release in capture order without additional user action. Given drafts are queued and consent remains blocked, When the app is closed and reopened, Then drafts persist in the queue with their metadata until user deletion or policy-defined retention elapses. Given the device is offline and consent is renewed server-side, When connectivity is restored, Then the app detects the renewal and auto-releases eligible drafts.
Consistency Across Photo, Voice-to-Text, and Digests
Given any consent state, When capturing a photo, recording voice-to-text, or preparing a digest, Then the same warning and blocking rules are applied with consistent messaging and behavior. Given a resident is in Expired or Paused state, When generating a digest, Then their items are excluded from delivery and the digest generation log records the omission reason. Given the same resident state and action are tested across all three content types, When results are compared, Then outcomes and UI copy match within acceptable variants for medium.
Auto-Blur Persists for Unrelated Non-Consenting Residents
Given a multi-resident photo is captured and posting is allowed for the target resident, When preparing to post, Then faces of unrelated non-consenting residents are auto-blurred regardless of the target resident’s consent state and the blur cannot be removed by the user. Given posting is blocked for the target resident and a draft is created, When the draft is saved, Then auto-blur is applied and persisted on the asset for any unrelated non-consenting residents. Given an admin override allows posting for the target resident, When the post is sent, Then auto-blur remains enforced for unrelated non-consenting residents and is not bypassed by the override.
One‑Tap Outreach & Contact Validation
"As an administrator, I want to reach the right family contact with one tap from the resident profile so that I can resolve consents quickly without searching for information."
Description

Enable caregivers and admins to initiate pre-filled SMS, email, or phone outreach to the correct authorized contact directly from the resident’s status panel. Validate contact channels (deliverability checks, number format, and opt-in status) and suggest alternatives if a channel is invalid. Log outreach attempts, outcomes, and notes to the consent audit trail. Provide templates for quick messages and integrate with the reminder engine to avoid duplicate pings. Respect privacy permissions and show only the minimum necessary contact details.

Acceptance Criteria
One‑Tap SMS to Authorized Consent Contact
Given a resident with at least one contact marked as Consent Authority, with SMS opt‑in=true and a valid E.164 phone number, When the caregiver taps SMS on the resident’s status panel, Then the native SMS composer opens to the highest‑priority eligible contact and the selected template body is pre‑filled with merged resident/contact fields. Given multiple eligible contacts, When SMS is tapped, Then a chooser displays eligible contacts sorted by authorization priority then last‑contacted time, and selecting one opens the composer addressed correctly with the pre‑filled body. Given no eligible SMS contact (invalid number or missing opt‑in), When SMS is tapped, Then sending is blocked and an inline error lists specific reasons and suggests the next valid channel(s) or eligible contact(s). Given privacy constraints, When the SMS action is shown, Then the phone number is masked on screen (e.g., +1•••••••34) unless the user has Admin role permissions. Then the SMS body is not stored in plain text; only the template ID and a content hash are logged.
One‑Tap Email to Authorized Consent Contact
Given a resident with at least one contact marked as Consent Authority, with email opt‑in=true and a syntactically valid RFC 5322 address with resolvable MX, When the caregiver taps Email on the resident’s status panel, Then the device email composer opens addressed to the correct contact with pre‑filled subject and body from the selected template and merged fields. Given multiple eligible email contacts, When Email is tapped, Then a chooser appears sorted by authorization priority then last‑contacted time; selecting one opens the composer addressed correctly with pre‑filled content. Given no eligible email contact (invalid format, no MX, or unsubscribed), When Email is tapped, Then sending is blocked and an inline error lists reasons and suggests valid alternative channels/contacts. Given privacy constraints, When showing email details, Then only the minimum necessary is displayed (masked local‑part, domain shown), and the full body is not persisted; only template ID and a content hash are logged.
One‑Tap Call with Minimal Disclosure and Outcome Capture
Given a resident with at least one contact marked as Consent Authority, with Call opt‑in=true and a valid E.164 phone number, When the caregiver taps Call on the resident’s status panel, Then the native dialer launches to the highest‑priority eligible contact and the number is masked in‑app prior to handoff. Given the call ends (connected, no answer, busy, or canceled), When the caregiver returns to the app, Then an outcome sheet appears requiring selection (Spoke, Left VM, No Answer, Wrong Number) and optional notes (max 500 chars) before completion. Given no eligible callable number or DNC status, When Call is tapped, Then dialing is blocked and an inline error lists reasons and suggests valid alternative channels/contacts. Then the call attempt and outcome are logged to the consent audit trail without storing the full number (only last 2–4 digits) and without exposing full contact details in the UI.
Channel Validation and Alternative Suggestions
Given a selected channel, When the user initiates outreach, Then the app validates format (SMS/Call: E.164; Email: RFC 5322) and consent status (opt‑in true, not unsubscribed/DNC) before enabling send. Given validation fails, When the user attempts to send, Then the send action is disabled, a specific error is displayed (e.g., "Invalid E.164 number" or "Email unsubscribed"), and a ranked list of alternative eligible channels/contacts is presented. Given a partially formatted number (missing country code) and a facility default country is set, When SMS/Call is tapped, Then the app auto‑normalizes to E.164 and re‑validates before enabling send. Given a contact has both valid SMS and Email with opt‑in, When the current channel is invalidated, Then the next highest‑ranked valid channel is suggested with a one‑tap switch action.
Audit Trail Logging of Outreach Attempts and Outcomes
Given any outreach attempt (SMS, Email, Call) is initiated, When the action is completed (sent, canceled, or failed), Then an append‑only audit record is written within 5 seconds containing: resident_id, contact_id, channel, template_id (if applicable), user_id, timestamp (UTC), outcome (sent, delivered if known, failed, canceled, spoke/left VM), external_message_id (if available), masked destination, and optional notes. Given privacy requirements, When logging the content, Then the message body is not stored; only a SHA‑256 hash of the rendered body and the template_id are recorded. Given an audit entry is written, When viewed by Admins, Then it is immutable except for notes which can be added (not edited) as additional append‑only entries with user_id and timestamp. Given exports are generated, When the consent audit trail is exported, Then all outreach entries appear with the above fields and no plaintext message content or full contact details.
Reminder Engine De‑duplication and Throttling
Given an automatic consent reminder is scheduled for a resident/contact/channel, When a manual outreach (same channel) is sent from the status panel, Then the reminder is canceled and future reminders for that resident/contact/channel are snoozed for the default 48 hours (facility‑configurable). Given a manual outreach was sent in the last 48 hours for a resident/contact/channel, When the reminder engine attempts to send an automated reminder, Then it is suppressed and an audit note records the suppression due to recent manual contact with a dedupe key (resident_id+contact_id+channel). Given a manual outreach is attempted while an automated reminder is pending for the next 2 hours, When the user opens the outreach panel, Then a non‑blocking notice indicates a pending reminder and allows either proceed (which cancels the pending reminder) or cancel. Then all dedup/snooze decisions are logged to the audit trail with reason codes and effective windows.
Message Templates, Merge Fields, and Localization
Given the user opens outreach, When selecting SMS or Email, Then a list of approved templates appears filtered by channel and context (e.g., Renew Soon, Consent Lapsed) with one default preselected based on consent status and days‑to‑expiry. Given a template with merge fields is used, When the message is rendered, Then all placeholders (e.g., {resident_first_name}, {consent_expiry_date}, {renewal_link}) are populated or replaced by defined fallbacks, with no unresolved tokens present in the outgoing message. Given SMS length exceeds 2 segments (320 chars), When rendering the message, Then a character/segment counter warns the user and allows edit before send; the final segment count is recorded in the audit log. Given a contact has a preferred language, When templates exist in that language, Then the localized template is auto‑selected; otherwise the facility default language template is used and this fallback is indicated to the user. Then the selected template_id and language code are stored in the audit trail, and caregivers can only edit allowed free‑text fields without altering locked compliance text.
Admin Consent Dashboard, Reporting & Audit
"As an administrator, I want a centralized view and reports of consent status and activity so that I can proactively manage renewals and demonstrate compliance during audits."
Description

Deliver a dashboard summarizing consent coverage, upcoming expirations, items in grace, and expired consents by facility and wing. Include filters, search, and CSV export. Provide detailed resident views with full consent history, reminder events, outreach logs, and signed document access. Offer configurable policies (expiry period, grace length, reminder cadence, templates) with change tracking and role-based access. Expose audit logs for regulator-ready reports, including who changed what and when. Include SLAs and health checks for reminder delivery and link uptime.

Acceptance Criteria
Dashboard Consent Coverage & Status Segmentation
Given an admin with permission "Consent.Dashboard.View" When they open the Admin Consent Dashboard for a selected facility and wing Then the header displays: total residents, count and % with active consent, count of consents expiring within the configured policy window, count in grace, and count expired And each status is color-coded per design tokens and meets WCAG AA contrast (>= 4.5:1) And each count is a link that drills down to a filtered resident list for that segment And data reflects the source of truth within ≤ 5 minutes of any consent change And the dashboard P95 load time is ≤ 2.5 seconds for up to 10,000 residents
Filtering, Search, and CSV Export
Given the dashboard resident list is visible When the user applies filters for Facility, Wing, Consent Status (Active/Near Expiry/Grace/Expired), Expiry Date Range, and search by Resident Name or Resident ID Then the result set updates within ≤ 1 second and only shows residents matching all active filters And the active filters persist when navigating to details and back When the user selects Export CSV Then a CSV is generated within ≤ 10 seconds for up to 100,000 rows and includes only the filtered result set And the CSV contains headers: ResidentID, ResidentName, Facility, Wing, ConsentStatus, ExpiryDate, GraceEndDate, LastReminderAt, LastOutreachOutcome And all timestamps are ISO 8601 UTC; values are comma-safe and quoted as needed; newline characters are preserved And only users with permission "Consent.Export" can export; others see a disabled control with tooltip And the export action is recorded in the audit log with actor, timestamp, and filter parameters
Resident Detail: Consent History, Reminders, Outreach & Documents
Given an authorized user with permission "Consent.Detail.View" When they open a resident's consent detail view Then a chronological timeline shows each consent version with version id, effective date, expiry date, status, source, and actor And reminder events show channel (SMS/Email), recipient contact, send time, provider message id, delivery status (Delivered/Bounced/Deferred), and error code if any And outreach logs show initiator, timestamp, channel used, and outcome (Sent/Failed/Completed) And signed consent documents are accessible to preview in-app and download as PDF; access is logged and URLs are time-bound (≤ 15 minutes) And users lacking scope to the resident's facility/wing are denied with a 403 and the attempt is audited
Policy Configuration with Change Tracking and RBAC
Given a user with permission "Consent.Policy.Admin" When they configure expiry period (days), grace length (days), reminder cadence (offsets), and message templates Then inputs validate allowed ranges (expiry 30–1095 days; grace 0–90 days; cadence offsets 0–60 days) and required placeholders before save And saving requires confirmation that shows before/after values and scope (org/facility/wing) And on save a new policy version is created with version id and effective timestamp; changes apply only to the defined scope And the change is written to the audit log with who, what, when, before, after, and optional reason text And users without "Consent.Policy.Admin" see read-only values and cannot save changes (control disabled) And an admin can revert to any prior version; the revert produces a new version and is audited
Audit Log Completeness and Regulator-Ready Reporting
Given an auditor with permission "Audit.View" When they query logs by date range, user, facility/wing, resident, and action type Then results include: timestamp (UTC), actor id, actor role, IP, action, entity type/id, outcome, correlation id, and before/after values where applicable And log entries are immutable and tamper-evident (hash chain verification passes) And logs can be exported to CSV and PDF with applied filters and page numbers; exports complete within ≤ 15 seconds for up to 200,000 rows And a regulator-ready report can be generated that summarizes consent coverage, expirations, grace, expired counts, and lists all consent-related changes and exports in the period; report uses UTC and includes facility/wing headers And all report and export actions are themselves logged with parameters and actor
Reminder Delivery SLAs and Link Uptime Health
Given reminder sending is enabled per policy When the system dispatches SMS/Email reminders Then P95 send-to-provider-ack latency is ≤ 15 seconds and delivery success rate is ≥ 99.0% per day; breaches trigger alerts to on-call within 2 minutes And transient failures are retried with exponential backoff up to 3 attempts per channel; a fallback channel is attempted if available And the dashboard shows real-time provider status, last 24h success rate, and queue lag with green/yellow/red thresholds defined by policy And renewal links have synthetic checks every 1 minute with monthly uptime ≥ 99.9% and P95 TTFB ≤ 500 ms; current status and last incident are visible And incidents record start/end time, impact summary, root cause, and remediation; health history is viewable for at least 90 days

Scope Templates

Prebuilt, customizable consent templates define what’s allowed (photo, audio, group events), where (room, dining, outings), and for whom (approved family vs. broader sharing), with effective dates and exceptions. Onboarding Guides can apply templates in one tap for new admissions, while Privacy Stewards fine‑tune per resident. Consistent scopes reduce set‑up time, eliminate ambiguity at capture, and standardize compliance across shifts.

Requirements

Template Library & Governance
"As an administrator, I want a governed library of consent templates so that our staff can standardize compliant sharing rules across residents and shifts."
Description

Provide a centralized library of prebuilt, customizable consent scope templates that define permitted media types (photo, audio, video), locations (room, dining, outings), audiences (approved family vs. broader sharing), and group scenarios (one-on-one vs. group events). Support CRUD operations, template tagging, facility-level defaults, and ownership with a lightweight approval workflow to publish/unpublish templates. Include safeguards to prevent deletion of in-use templates and display dependency counts. Ship with KinLoop-recommended starter templates while allowing organizations to clone and adapt them, ensuring standardization across shifts and sites. This forms the foundation for consistent, rapid setup and reduces ambiguity at content capture.

Acceptance Criteria
Create New Consent Scope Template
Given a Privacy Steward with Create permission is on the Template Library When they click New Template and provide name, description, at least one media type, at least one location, at least one audience, and select one or more group scenarios Then the Save action is enabled and validation errors are shown inline for any missing required fields And upon Save, the template is created with status Draft, version 1.0, owner set to the creator, and createdAt timestamp recorded And the template appears in the library list with its configured attributes and status Draft
Publish Workflow for Templates
Given a Draft template exists When a Privacy Steward submits it for approval with a required change summary Then the template status changes to Pending Approval and a notification is sent to Compliance Admins Given a Compliance Admin views a Pending Approval template When they Approve it Then the template status becomes Published, publishedAt timestamp and approver are recorded, and it is selectable in apply/capture flows When they Reject it Then the template returns to Draft with a required rejection reason stored and visible in the activity log
Deletion Safeguards with Dependency Counts
Given a template with zero dependencies (0 residents assigned, 0 onboarding guides referencing) When a user with Delete permission confirms deletion Then the template is deleted and an audit log entry records who, when, and what was deleted Given a template with dependencies > 0 When a user attempts to delete it Then deletion is blocked and a modal displays dependency counts by type (Residents, Guides) and provides primary actions Unpublish and Cancel When Unpublish is confirmed on a Published template Then its status becomes Unpublished, it remains on already assigned residents, and it is no longer selectable for new assignments
Template Tagging, Search, and Filters
Given templates have tags, owners, statuses, and defined media types When a user filters by tag "Group Events", media type Photo, status Published, owner "J. Smith", and searches for "Dining" Then only templates matching all filters and the search term are listed and the results count is displayed When filters are cleared Then the full library is shown When a user adds tags to a template on create/edit Then up to 10 unique tags can be saved, duplicates are prevented, and tags render as chips on the detail and list views
Facility-Level Default Application via Onboarding Guide
Given a Facility Admin sets a Published template as the facility default in Settings When they Save Then the default template is stored and visible in Onboarding Guides as the one-tap option Given a new resident is onboarded When the Onboarding Guide user taps Apply facility default template Then the resident's consent record is populated with the template scopes and effective dates, and an audit entry is created linking user, template, and timestamp When a Privacy Steward overrides the resident's consent after default application Then the overrides are saved, the default reference remains recorded, and the resident record reflects the latest effective scopes
Clone and Adapt KinLoop Starter Templates
Given KinLoop starter templates are available read-only on first use When a user with Create permission clicks Clone on a starter template Then a new Draft template is created with fields prefilled, name appended with "(Copy)", owner set to the cloner, and no change is applied to the original When the cloned template is edited and saved Then changes apply only to the clone and the original starter remains unchanged and read-only
Ownership and Permission Controls
Given roles exist: Privacy Steward (create/edit), Compliance Admin (approve/publish, reassign ownership), Facility Admin (set defaults), Viewer (read-only) When a Viewer attempts to create, edit, delete, publish, or set defaults Then those actions are hidden or disabled and cannot be executed via API When a non-owner Privacy Steward attempts to edit another Steward's Draft without Manage All Templates permission Then the template opens read-only with Edit disabled When a Compliance Admin reassigns ownership of a template Then the new owner is set, all changes are logged, and the reassignment takes effect immediately
One-Tap Template Apply
"As an Onboarding Guide, I want to apply a consent template in one tap during admission so that I can complete setup quickly and accurately."
Description

Enable Onboarding Guides to apply a selected consent scope template to a new resident in a single action during admission setup. Auto-map template rules into the resident’s consent record, prefill effective dates from admission, and present a confirmation summary before saving. Provide inline validation for missing prerequisites (e.g., lack of family contacts) and post-apply prompts to invite or confirm approved family recipients. This reduces onboarding time, minimizes errors, and ensures residents begin with a compliant, consistent scope from day one.

Acceptance Criteria
Confirmation Summary Prior to Save
Given a new resident admission with an admission date and a selected consent template When the Onboarding Guide taps "Apply Template" Then a confirmation summary modal is displayed before any data is saved And the summary lists template name and version, allowed content types, allowed locations, recipient scope, exceptions, and effective dates And the summary displays counts where applicable (e.g., number of locations, number of recipient groups) And the user can choose Confirm to proceed or Cancel to return with no changes persisted
Template Mapping and Effective Dates Upon Confirm
Given the confirmation summary is displayed for a selected template and resident admission When the Onboarding Guide selects Confirm Then the system maps all template rules (content types, locations, recipient scope, exceptions) into the resident’s consent record And sets the effective start date to the resident’s admission date and the end date to the template’s default (or leaves it blank if unspecified) And the apply operation completes within 2 seconds under normal load And a success toast confirms "Template applied"
Inline Validation for Missing Prerequisites
Given the Onboarding Guide is in admission setup and attempts to tap "Apply Template" When required prerequisites are missing Then if no template is selected, the button is disabled and an inline message reads "Select a template to continue" And if the admission date is missing, an inline error highlights the Admission Date field and prevents proceeding And if the selected template includes "approved family" recipients but there are zero approved family contacts, an inline warning is shown and the user may proceed to confirmation with a note that recipients will be handled post-apply
Post-Apply Prompts for Family Recipients
Given a template has been successfully applied When the resident has zero approved family contacts and the scope includes "approved family" recipients Then a post-apply prompt offers actions: Invite Family Now, Choose Existing Contact, or Skip for Now And selecting Invite Family Now opens the invite flow prefilled with the resident context And selecting Skip for Now records the decision and dismisses the prompt without blocking completion And if there are pending invites or unconfirmed recipients, a prompt to confirm recipients is displayed with a shortcut to the confirmation screen
Role-Based Access and Context Availability
Given a user is viewing a new resident’s admission setup When the user has the Onboarding Guide role Then the "Apply Template" control is visible and enabled And when the user lacks the required role or the resident is not in admission setup, the control is hidden or disabled with an explanatory tooltip And API enforcement rejects unauthorized apply attempts with HTTP 403 and no changes persisted
Audit Trail and Template Version Stamping
Given a template is applied to a resident and the operation succeeds When the system finalizes the save Then an audit log entry records user ID, resident ID, timestamp, template ID and version, and the list of applied rule categories And the resident consent record stores the applied template version for traceability And subsequent edits to the source template do not retroactively alter the resident’s consent record
Failure Handling and Atomicity
Given an error occurs at any point during apply (e.g., network or persistence failure) When the operation fails Then no partial consent data is saved (the resident’s consent record remains unchanged) And the user sees a clear error message with a Retry action And retrying the apply is idempotent (no duplicate records or duplicated notifications) And the failure and correlation ID are logged for support diagnostics
Per-Resident Scope Overrides
"As a Privacy Steward, I want to fine-tune a resident’s scope on top of a template so that individual preferences and edge cases are respected."
Description

Allow Privacy Stewards to fine-tune template-derived consents at the resident level with clear visibility of what differs from the base template. Provide a diff view that highlights overrides, a reversible toggle to revert to template defaults, and field-level exception notes (e.g., permit photos in room but not in dining). Maintain a link to the originating template so future template updates can be previewed for impact and selectively merged. This balances standardization with individualized dignity and preference needs without losing traceability.

Acceptance Criteria
Diff View Highlights Overrides
Given a resident with a template applied and at least one overridden field When a Privacy Steward opens the resident's Scope Overrides diff view Then all overridden fields are visually highlighted and grouped at the top And non-overridden fields are displayed with a “From Template” badge And a toggle exists to filter the view to “Overridden only” And the count of overridden fields is displayed and equals the number of highlighted fields
Per-Field Revert to Template Default
Given a resident with one or more overridden fields When the Privacy Steward clicks Revert on an overridden field Then the field value immediately matches the current template value And the field is no longer marked as overridden And an Undo option is available for at least 30 seconds to restore the override And the change is logged with user, timestamp, and field name
Field-Level Exception Notes and Validation
Given a Privacy Steward is editing a field-level exception note When they enter text up to 500 characters and save Then the note is saved and timestamped with the editor’s identity And empty notes are not allowed if an exception toggle is ON And prohibited content (e.g., PHI of other residents) is blocked per validation rules And notes appear inline in the diff view and in the audit log
Template Link and Impact Preview on Template Change
Given a resident is linked to Template A version 3 And Template A is updated to version 4 When the Privacy Steward opens the resident’s overrides Then an Impact Preview banner indicates pending template changes And a side-by-side preview shows each changed field with current resident value, template v3 value, and template v4 value And no changes are applied until the steward explicitly accepts them
Selective Merge of Template Updates
Given a template update introduces changes to multiple fields When the Privacy Steward selects “Merge” and chooses fields A and C but not B Then only fields A and C update to the new template values And existing resident overrides on unselected fields remain unchanged And a summary confirms which fields were merged and which were skipped And all merges are recorded with user, timestamp, and affected fields
Role-Based Access and Audit Logging
Given the user is a Privacy Steward When they access resident overrides Then they can create, edit, revert, and merge overrides Given the user is not a Privacy Steward (e.g., Caregiver or Admin without permission) When they access resident overrides Then they have read-only access and cannot modify fields And every view and change is captured in an audit trail including user, action, timestamp, resident, field, old value, new value
Capture Enforcement of Effective Consent Scope
Given a resident’s effective scope (template + overrides) disallows photos in Dining but allows in Room When a caregiver attempts to capture a photo tagged Dining for that resident Then the app blocks capture and displays a clear reason derived from the scope When the caregiver captures a photo in Room for that resident Then the capture proceeds without consent warnings And for group photos, non-consenting faces are auto-blurred according to each involved resident’s effective scope
Effective Dates & Exceptions
"As a Privacy Steward, I want to set and schedule effective dates and exceptions so that consents stay accurate over time without manual policing."
Description

Support time-bound consent with effective start/end dates, temporary blackout periods (e.g., during a clinical event), and scheduled changes (e.g., broaden sharing at 30 days post-admission). Provide proactive alerts to stewards and admins before expirations, along with quick actions to renew, adjust, or sunset scopes. At runtime, enforce the active ruleset based on the current timestamp and any overlapping exceptions, ensuring capture decisions remain accurate without manual checks.

Acceptance Criteria
Template Effective Start/End Dates Applied on Admission
Given a resident has a scope template with start_at and end_at set in the facility time zone When the caregiver opens the capture screen before start_at Then all actions governed by the template show disabled state with a message "Consent starts on <localized start_at>" and backend attempts are rejected with 403 CONSENT_NOT_YET_EFFECTIVE and are audit-logged with evaluated_at, start_at, end_at When the current time is >= start_at and < end_at Then only the allowed capture types/locations in the template are enabled, disallowed ones remain disabled, and decisions are audit-logged with rule_ids and evaluated_at When the current time is >= end_at Then permissions from the template are deactivated, the UI shows "Consent expired on <localized end_at>", backend attempts are rejected with 403 CONSENT_EXPIRED, and an audit entry records decision=deny with source=end_at
Temporary Blackout During Clinical Event
Given a resident has an active consent template allowing photo and audio When a Privacy Steward applies a blackout exception with blackout_start <= now < blackout_end Then any capture primarily involving the resident is blocked with 403 CONSENT_BLACKOUT and UI banner "Temporary privacy blackout through <date/time>" And group captures taken during the blackout auto-blur the resident and proceed only if all other policies are satisfied, with audit entries noting redaction_applied=true and reason=blackout When now >= blackout_end Then prior allow rules resume automatically without manual intervention, and an audit entry records blackout_lifted with timestamps
Scheduled Scope Change at 30 Days Post‑Admission
Given a scope template schedules a change at admission_date + 30 days to broaden sharing from "Approved Family" to "Family + Facility Channels" When the current time is < scheduled_change_at Then captures and distributions follow the pre-change scope When the current time reaches scheduled_change_at Then the new scope is applied automatically within 60 seconds without staff action, a scope_changed event is emitted, and the UI reflects updated sharing destinations And content captured after scheduled_change_at follows the new scope, while content captured before retains the original scope; all decisions are audit-logged with change_set_id
Proactive Expiration Alerts with Quick Actions
Given a scope template has an end_at date When it is 14 days before end_at and notifications are enabled for Privacy Stewards and Admins Then an in-app alert and email notification are sent once per recipient containing resident, template name, end_at, and quick actions: Renew, Adjust Dates, Sunset When it is 2 days before end_at and the scope is still active Then a reminder alert is sent with the same details and actions and is suppressed if the prior alert was acted on successfully When a Steward selects Renew and chooses a duration (e.g., +90 days) Then end_at is extended immediately, confirmation appears within 5 seconds, policy takes effect within 60 seconds, and an audit entry records previous_end_at and new_end_at When Adjust Dates is saved Then start_at/end_at are updated, re-evaluated against now, and affected decisions change accordingly with audit trail When Sunset is confirmed Then end_at is set to now, policy is deactivated, and subsequent captures are blocked with CONSENT_EXPIRED
Overlapping Exceptions Resolution at Runtime
Given multiple rules overlap in time for a resident (template allows, exception denies, blackout active) When the decision engine evaluates a capture at runtime Then precedence is applied deterministically: Blackout > Explicit Deny > Allow; if multiple of the same precedence apply, the rule with the latest updated_at wins And the engine returns decision=allow|deny along with source_rule_ids in order of precedence and is audit-logged with evaluation_window and facility_tz And the UI and backend present the same decision within the same second for the same evaluated_at timestamp
Time Zone and DST‑Safe Evaluation
Given the facility time zone is set to an IANA zone (e.g., America/Chicago) When a steward saves start_at and end_at in local facility time Then the system persists absolute instants in UTC plus the facility_tz, and all runtime evaluations compare against UTC to avoid DST ambiguity When a start_at falls on a DST spring-forward skipped minute/hour Then the saved UTC reflects the next valid local instant and the UI displays the normalized local time with a tooltip indicating adjustment When evaluating during a DST fall-back repeated hour Then the same local time maps to distinct UTC instants and evaluations are consistent with the stored UTC instants; no duplicate or missed enforcement occurs
Capture-Time Scope Enforcement
"As a caregiver, I want the app to tell me what I can capture and share in the moment so that I don’t risk violations or delay my shift."
Description

Integrate scope rules directly into the caregiver capture flow to validate media type, location, and audience before posting. Provide real-time indicators of allowed actions, soft warnings for review-required scenarios, and hard blocks for prohibited captures, with contextual guidance and suggested alternatives. Automatically invoke KinLoop’s auto-blur for non-consenting faces in group photos, and restrict distribution to only approved recipients. This eliminates ambiguity at the point of capture, reduces compliance risk, and maintains caregiver speed with one-tap clarity.

Acceptance Criteria
Real-Time Allowed Actions Indicator
Given a caregiver opens capture mode for a selected resident at a detected location, When the caregiver switches between Photo, Video, and Audio, Then the UI shows Allowed/Review/Blocked for the selected media type within 500 ms and updates when resident or location changes, And tapping the indicator reveals the reason and the scope source. Given the current selection is Blocked, When capture mode opens, Then the system preselects the first Allowed option without additional taps.
Location-Aware Scope Enforcement
Given a resident’s scope prohibits photos in the Room but allows them in the Dining area, When the caregiver attempts to take a photo in the Room, Then the shutter is disabled, no media file is saved, a message explains the restriction, and a one-tap option suggests allowed locations (e.g., “Go to Dining”). Given the caregiver is in an allowed location per scope, When taking a photo, Then capture proceeds without warnings or extra taps. Given location cannot be determined, When attempting capture, Then the system requires the caregiver to confirm location or defaults to the most restrictive rule before enabling capture.
Audience Restriction at Post
Given a resident’s scope allows sharing to Approved Family only, When the caregiver selects recipients, Then only allowed recipients are selectable, disallowed audiences are disabled with tooltip reasons, and default selection includes only approved family. When posting the update, Then distribution is restricted to the allowed recipients, disallowed channels are not sent any content, and the post metadata records the applied audience rule.
Auto-Blur for Non-Consenting Faces in Group Photos
Given a group photo contains consenting and non-consenting faces, When the image is captured, Then non-consenting faces are automatically blurred before preview within 2 seconds, no unblurred thumbnail is stored or displayed, and consenting faces remain unblurred. When reviewing the preview, Then caregivers can adjust blur on consenting faces only (to fix false positives), cannot remove blur from non-consenting faces, and posting is blocked if face detection fails to complete, with prompts to retake or crop.
Soft Warning for Review-Required Scenarios
Given a scope marks “Outings audio updates require steward review,” When the caregiver captures an outings audio update, Then the system shows a non-blocking warning with the reason, allows the caregiver to proceed in one additional tap, and flags the post as “Pending Review.” When the post is flagged Pending Review, Then it is visible to Privacy Stewards for approval, families do not receive the digest entry until approval, and all actions are logged with timestamps and actor IDs.
Hard Block for Prohibited Captures with Alternatives
Given a scope prohibits video anywhere, When the caregiver switches to Video, Then the shutter is disabled, a blocking message explains the policy, and contextual alternatives are offered (e.g., “Record Audio” or “Take Photo”) as one-tap actions. When a hard block occurs, Then there is no override path for caregivers, help text links to the governing scope, and an event is logged with resident, media type, location, reason, and device ID.
Effective Dates and Exceptions Handling
Given a scope template with an effective date, expiry date, and exceptions (e.g., “Group photos allowed during holiday week only; exception: resident’s daughter may receive group photos year-round”), When the current time is within the effective window, Then allowed actions reflect the window and exceptions precisely, including audience exceptions. When the effective window expires or a steward updates the template, Then enforcement changes take effect in the capture UI within 60 seconds, and actions outside the window are blocked with accurate messaging; time zone is derived from facility settings.
Consent Audit Trail & Versioning
"As a Compliance Officer, I want a complete versioned audit trail of consent scopes and actions so that I can demonstrate adherence and investigate issues quickly."
Description

Record an immutable audit trail for template creation, edits, approvals, applications to residents, overrides, and runtime enforcement decisions. Capture who, what, when, and why (including exception notes) and provide version history with the ability to view past states and regenerate compliance reports. Offer export options (CSV/PDF) and filters by resident, unit, user, template, and time window to streamline compliance reviews and incident investigations. This establishes defensible compliance documentation and speeds responses to regulatory or family inquiries.

Acceptance Criteria
Template Creation Audit Trail
Given a Privacy Steward creates a new consent scope template When they save the template Then the system writes an audit record with fields: action=create_template, template_id, template_name, version=1, actor_user_id, actor_role, timestamp_utc (ISO-8601), change_summary, rationale_note (nullable) And the audit record is immutable and viewable via audit UI and API And the record is returned when filtering by template_id, actor_user_id, and a time window covering timestamp_utc
Template Edit & Version History
Given an existing consent scope template at version N When an authorized user edits and saves the template Then a new version N+1 is created and version N remains read-only and viewable And an audit record is written with fields: action=edit_template, template_id, previous_version=N, new_version=N+1, fields_changed (name/value before→after), actor_user_id, actor_role, timestamp_utc, rationale_note And the version history view lists versions chronologically and supports viewing exact field values for any selected version
Approval Workflow Logging
Given a template requires approval before activation When an approver approves or rejects the template or a new version Then an audit record is written with fields: action=template_approval_decision, template_id, version, outcome=approved|rejected, approver_user_id, approver_role, timestamp_utc, comments (nullable) And the template/version status updates accordingly and is reflected in version history And any subsequent edit to an approved version auto-invalidates the prior approval, requiring re-approval, and this invalidation is logged as action=approval_invalidated
Resident Application & Overrides Logging
Given a resident is onboarded and a scope template will be applied When an authorized user applies template T version V to resident R with effective dates Then an audit record is written with fields: action=apply_template_to_resident, resident_id, template_id=T, version=V, effective_start, effective_end (nullable), actor_user_id, actor_role, timestamp_utc And any per-resident override at field-level writes a separate audit record: action=override_scope, resident_id, template_id, version, field_name, old_value, new_value, exception_note (required), actor_user_id, actor_role, timestamp_utc And filtering by resident_id returns all application and override records in chronological order
Runtime Enforcement Decision Logging
Given a caregiver attempts content capture or share (e.g., photo in group event) When enforcement evaluates applicable consent scopes Then an event record is written with fields: action=enforcement_decision, decision=allow|block, reason_codes (list of rule/template version IDs), resident_ids implicated, template_ids with versions, location_context, auto_redactions_applied (e.g., auto_blur=true for non-consenting), actor_user_id, actor_role, timestamp_utc, notes (nullable) And the record is retrievable by filters: resident, user, location, template, and time window And the record contains no PHI beyond necessary metadata for compliance review
Immutable Audit Log & Tamper Evidence
Given an audit record exists When any user attempts to edit or delete the record via UI or API Then the system denies the action and writes a security audit event: action=audit_tamper_attempt, actor_user_id, actor_role, target_record_id, timestamp_utc And each audit record includes hash and previous_hash enabling a verifiable hash chain And a verification endpoint returns chain_status=valid for a selected time range, or identifies the first invalid record_id if integrity is compromised
Filtered Export & Past-State Report Regeneration
Given an auditor applies filters by resident(s), unit(s), user(s), template(s), and time window When the filters are applied Then the results contain only matching records and display total_count And exporting to CSV generates UTF-8 CSV with ISO-8601 UTC timestamps, standardized headers, and exactly total_count data rows And exporting to PDF generates a paginated report containing the same records, a filter summary header, and a generation timestamp And given a reference time T, when an "as of T" compliance report is requested, then the system reconstructs template assignments/versions effective at T and produces records consistent with the historical state
Bulk Apply & Cohort Migration
"As an administrator, I want to roll out template changes to resident cohorts with a preview and rollback so that policy updates are fast and safe."
Description

Provide tools to apply or update templates across cohorts based on filters such as unit, care level, admission date, or existing scope attributes. Include an impact preview with conflict detection (e.g., residents with critical overrides) and safe rollout options: staged deployment, rollback, and change summaries to stakeholders. This reduces manual work when policies change, enables rapid standardization after audits, and keeps resident-level customizations intact where designated.

Acceptance Criteria
Filter Cohort by Unit, Care Level, Admission Date, and Scope Attributes
Given I am a Privacy Steward or Admin using the Bulk Apply & Migration tool And residents exist across multiple units, care levels, admission dates, and scope attributes When I set filters: Unit=East Wing, Care Level=Memory Care, Admission Date between 2025-01-01 and 2025-06-30, and Scope Attribute "Photo Capture" = Disabled Then the system displays the count of matching residents and a paginated list of resident identifiers And the filters combine using logical AND across fields And removing any one filter updates the count within 2 seconds for cohorts up to 2,000 residents And I can save this filter set as a named cohort and recall it later
Impact Preview Flags Conflicts and No-Change Residents
Given I have selected a template and a filtered cohort When I choose Preview Then the system shows totals for Will Update, No Change, and Conflicts (Critical Overrides) And each conflicted resident lists conflicting fields and the reason (e.g., legal/critical override) And the preview displays per-resident diffs of current vs proposed scope values And no resident data is modified during preview And I can export the preview results to CSV for review
Bulk Apply Preserves Resident-Level Designated Overrides
Given some residents have specific scope fields flagged as Do Not Overwrite When I execute a bulk apply using a selected template Then flagged fields remain unchanged for those residents And only non-flagged fields are updated to the template values And the completion report includes counts of preserved overrides, updated fields, and residents skipped
Staged Deployment Executes in Batches and Scheduled Windows
Given my cohort exceeds 50 residents When I configure Staged Deployment with batch size = 25 and schedule start = 21:00 in the facility’s timezone Then the system queues batches of 25 and begins at the scheduled time And it displays live progress (percent complete, residents processed, current batch) And I can pause and resume without data loss And residents processed before a pause retain their updated scopes
One-Click Rollback Restores Previous Scopes
Given a bulk apply deployment has completed within the last 30 days When I initiate Rollback for that deployment Then every affected resident is restored to their exact pre-change scope from a stored snapshot And the rollback executes in reverse order and reports success/fail counts And an audit entry links the rollback to the original deployment And residents with intervening manual changes are flagged and skipped unless I explicitly confirm overwrite
Change Summary Notifications Sent to Stakeholders
Given a bulk apply or rollback completes When notifications are enabled for Admins and Privacy Stewards Then a change summary is delivered within 5 minutes via in-app alert and email And the summary includes initiator, timestamp, filters, template name/version, totals (updated/no change/conflicts), preserved overrides, failures, and links to audit and CSV And only authorized recipients for the relevant facilities receive the summary
Permissions and Audit Log for Bulk Apply and Migration
Given role-based permissions are configured When an unauthorized user accesses the Bulk Apply & Migration tool Then bulk actions are disabled and an explanatory message is shown And authorized users can proceed with actions And every preview, apply, stage, pause/resume, and rollback creates an immutable audit record with timestamp, user, cohort filter, template, counts, and snapshot checksums And audit records are exportable in CSV and JSON

FaceLink Registry

Securely links resident faces to their consent records so auto‑recognition at capture can cross‑check who appears. If a non‑consenting resident is detected, KinLoop auto‑blurs or blocks the post based on policy; if all are cleared, it speeds posting with a green light. Snapshot Aides stay compliant without manual lookups, and Privacy Stewards gain confidence that every image respects the right scopes.

Requirements

Resident Face Enrollment & Consent Linkage
"As a Privacy Steward, I want to enroll and link a resident’s face to their consent record so that recognition at capture enforces the correct privacy scope automatically."
Description

Create an admin workflow to enroll residents’ faces and link them to authoritative consent records. Support multi-angle image capture/import, generation of face embeddings, duplicate detection, and versioned linkage to consent scopes (media types, audience groups, purpose, locations, time windows, expiration). Provide change history, validation, and bulk import from EHR/roster systems. Handle updates for appearance changes (e.g., hair, glasses) and record approvals, ensuring the registry stays accurate and audit-ready.

Acceptance Criteria
Enroll Resident Face via Multi‑Angle Capture
Given an admin starts enrollment for a resident with a valid resident_id When the admin captures at least 3 angles (front, left, right) at >= 720p with lighting/blur quality score >= configured thresholds Then the system generates face embeddings and marks the profile as Pending Approval Given any captured image fails quality thresholds (e.g., excessive blur, occlusion, low light) When the admin attempts to proceed Then the system blocks submission and displays specific recapture guidance per failed metric Given embeddings are generated When the admin submits for approval Then the profile is routed to an approver and records the submitter, timestamp, and image count Given the profile is approved When the approval is saved Then the face profile status is Active, a version number is assigned, and a confirmation is shown within 2 seconds Given the profile is Active When queried by resident_id Then the profile returns thumbnail, version, status, and embedding metadata
Update Face Profile for Appearance Changes
Given a resident has an Active face profile When an admin adds new photos reflecting appearance changes and requests an update Then the system creates a new Draft version and generates embeddings for the draft Given a Draft version exists When an approver approves the draft Then the Draft becomes Active, the previous Active moves to Archived, and the change is logged Given a Draft version is pending When recognition is performed during capture Then the system continues using the previous Active version until the draft is approved Given an approver performs a rollback When the rollback is confirmed Then the previously Archived version becomes Active and the action is recorded in the audit log Given a new Active version is in place When recognition runs Then only the latest Active version’s embeddings are used for matching
Duplicate Resident Detection and Merge Workflow
Given a new enrollment generates embeddings When similarity to an existing resident meets or exceeds the configured duplicate threshold Then the system flags a potential duplicate and prevents auto-approval Given a potential duplicate is flagged When an admin selects Merge Then the system requires target selection, consolidates identifiers, face profiles, and consent linkages, and deactivates the duplicate record Given a potential duplicate is flagged When an admin marks Not a Duplicate Then the decision is recorded with evidence scores and the enrollment may proceed to approval Given a merge is completed When the duplicate resident_id is queried Then it redirects to the target resident and cannot be used to create new linkages Given a merge or not-a-duplicate decision is made When the audit log is viewed Then the actor, evidence scores, selected target, and timestamps are present
Consent Linkage with Versioned Scopes
Given a resident has an Active face profile When an admin links an authoritative consent record with scopes (media types, audience groups, purposes, locations, time windows, expiration) Then required fields are validated and a new Consent Link version is saved Given multiple Consent Link versions exist with different effective windows When resolving consent for a specific capture_timestamp Then the version whose window covers the timestamp is selected; if overlapping, the most recently updated version wins Given a consent record is expired at capture_timestamp When resolving consent Then the decision is Block with rationale Expired Consent Given no consent record exists When resolving consent Then the decision is Block with rationale No Consent On File Given consent scopes exclude the requested media_type or audience_group When resolving consent with facility policy configured to blur non-consenting subjects Then the decision is Blur with rationale Missing Scope
Effective Consent Resolution API for Capture
Given resident_id, media_type, location_id, audience_group, and capture_timestamp When POST /facelink/resolve is called Then the response includes decision in {allow, blur, block}, effective_consent_version_id (or null), rationale codes, and cache_ttl Given inputs that map to an Allow outcome When the API is called under test load of 50 RPS Then 95th percentile latency is <= 300 ms with HTTP 200 and decision=allow Given resident_id does not exist When the API is called Then HTTP 404 is returned with error_code=resident_not_found Given the request body is missing required fields or has invalid formats When the API is called Then HTTP 400 is returned with a list of field-level validation errors Given a transient internal error occurs When the API is called Then HTTP 503 is returned with retryable=true and a Retry-After header
Bulk Roster/EHR Import with Validation
Given a CSV file with 1,000 residents including external_id, name, MRN, and optional photo_url When an admin uploads the file and selects Dry Run Then the system validates schema, performs matching by external_id, and returns a row-level report of creates/updates/skips with error reasons Given a completed Dry Run with errors When the admin selects Fix Mode and re-uploads corrected rows Then only valid rows are applied and invalid rows remain queued with actionable messages Given the same file is re-imported within 24 hours When the import runs Then the operation is idempotent by external_id and only deltas are applied Given an import of 1,000 valid rows When processing begins Then at least 95% of rows complete within 5 minutes and a final success/failure summary is generated Given an import completes When the admin downloads the results Then CSV and JSON reports are available listing created/updated/skipped rows with reasons and counts
Audit Trail and Change History Export
Given any create, update, approve, merge, or delete affecting face profiles or consent links When the action is committed Then an immutable audit event is recorded with actor, UTC timestamp, entity id/type, action, before/after fields, and reason Given an auditor requests history with filters for resident_id, action types, and date range When the export is generated Then the system returns CSV and JSON files containing all matching events with pagination metadata Given an export file is generated When integrity is verified Then the file includes a SHA-256 checksum and total event count Given an audit event is viewed in the UI When details are expanded Then the event shows linked entities (face profile version, consent link version) and a human-readable rationale
On-device Face Detection & Recognition Engine
"As a Snapshot Aide, I want the app to instantly recognize residents in the camera view so that I can capture updates without breaking workflow."
Description

Deliver low-latency, on-device detection and identification of faces during camera preview and capture, matching against the FaceLink registry without requiring network connectivity. Support multiple faces per frame, tunable confidence thresholds per facility, and graceful fallback to server validation when available. Optimize for entry-level Android/iOS hardware, robust to masks/hats/angles, and expose structured results (ids, confidence, bounding boxes) to downstream policy evaluation.

Acceptance Criteria
Real-time On-Device Face Detection in Camera Preview
- Given camera preview at 1280x720 @30fps on an entry-level device (Android: Moto E 2020 or equivalent; iOS: iPhone SE 2nd gen), When on-device face detection is enabled, Then median per-frame detection latency <= 60 ms and 95th percentile <= 90 ms with up to 4 faces in view. - Given continuous preview for 10 minutes, When detection runs, Then dropped frames attributable to detection <= 5% and the app does not ANR or crash.
Offline Recognition Against FaceLink Registry
- Given network connectivity is unavailable, When a known resident is in frame, Then the engine matches on-device against the FaceLink registry and returns residentId, confidence [0..1], and boundingBox without issuing any network requests. - Given network connectivity is unavailable and the local registry is missing or corrupted, When a face is detected, Then the engine returns residentId=null and emits a structured error code REGISTRY_UNAVAILABLE while continuing detection.
Multi-Face Support and Structured Results
- Given a frame containing N faces (1<=N<=6), When processed, Then the engine returns exactly N result objects each containing boundingBox (x,y,w,h in normalized coordinates), trackingId, residentId or null, confidence [0..1], and timestamp. - Given the same persons persist across consecutive frames, When processed, Then trackingId remains stable for at least 80% of frames with IoU>=0.5 between consecutive bounding boxes.
Facility-Tunable Recognition Threshold
- Given the facility recognitionThreshold is set to 0.85, When recognition runs, Then any face with top match confidence < 0.85 yields residentId=null and any face with confidence >= 0.85 yields the matched residentId. - Given an administrator updates recognitionThreshold in Settings and saves, When the camera preview resumes, Then the new threshold takes effect within 2 seconds without app restart.
Robustness to Masks, Hats, and Angles
- Given faces wearing surgical masks covering the lower half, When processed, Then face detection recall >= 98% and identification Top-1 accuracy >= 92% at threshold 0.80 on a test set of 200 images. - Given faces with yaw up to 30 degrees and pitch up to 20 degrees and occasional hats, When processed, Then face detection recall >= 98% and identification Top-1 accuracy >= 90% at threshold 0.80 on a test set of 200 images.
Graceful Fallback to Server Validation When Available
- Given on-device recognition produced results, When network becomes available and server validation is enabled, Then the engine enqueues embeddings/metadata and obtains server validation within 5 seconds p95 in the background without blocking capture or posting UI. - Given a server validation result differs from the on-device match, When merged, Then the result object includes validationSource ('device'|'server') and validationStatus ('confirmed'|'disputed'), preserving the on-device decision until policy resolves.
Resource Usage and Thermal Behavior on Entry-Level Devices
- Given continuous 15-minute preview with recognition enabled at 720p on entry-level devices, When profiled, Then average CPU utilization attributable to the engine <= 60%, peak memory increase <= 250 MB, and no thermal throttling or crashes are recorded. - Given the device battery is at 100%, When running the 15-minute preview test, Then battery drain attributable to the app <= 7%.
Consent Policy Evaluation & Decisioning
"As a Privacy Steward, I want policy decisions to reflect each resident’s consent scope and context so that content is automatically allowed, redacted, or blocked with clear rationale."
Description

Implement a policy engine that cross-checks detected identities against consent scopes and context (content type, location, unit, caregiver role, time constraints) to output a decision per capture: allow (green), allow with redaction (yellow), or block (red). Ensure deterministic rule precedence, explainable outcomes with human-readable reasons, and configuration at facility and resident levels. Provide APIs for the capture UI and logging to consume decision details in real time.

Acceptance Criteria
Real‑Time Decision for Single Resident with Valid Consent
Given content_type=photo, location=Common Room, unit=A, caregiver_role=Activity Aide, timestamp within resident R1’s active consent window, and face recognition matches exactly resident_id=R1 with confidence >= 0.98 When the capture UI calls POST /v1/decisions with the evaluated context and detected faces Then the engine returns HTTP 200 with decision=allow (green), reasons=["resident_consent_active"], resident_ids=[R1], consent_version_id, policy_version_id, evaluated_context echo, rule_trace[], and actor_ids, with latency p95 <= 250 ms and p99 <= 500 ms
Mixed‑Consent Group Photo with Auto‑Redaction
Given facility setting unknown_face_action=redact, and detected faces include R1 (consent: allow), R2 (consent: none for images), and U1 (unknown) When the capture UI requests a decision for content_type=photo Then the engine returns decision=allow_with_redaction (yellow), reasons includes ["nonconsenting_resident","unknown_face"], and redaction_targets=[R2, U1] with per‑face directives {resident_or_unknown_id, action=blur, bbox} And the directive bbox overlaps the corresponding detection bbox with IoU >= 0.90 And the response echoes detection_summary with per‑face decision actions
Non‑Consenting Resident Detected in Prohibited Location
Given facility policy prohibits imaging in locations tagged Bathroom regardless of consent And detected faces include any resident (e.g., R2) with any consent state When a decision is requested with location=Bathroom and content_type=photo Then the engine returns decision=block (red), reasons[0]="location_prohibited", redaction_targets=[], and upload_allowed=false And response latency p95 <= 250 ms
Role‑Scoped Consent Restriction Enforcement
Given resident R1 has consent scoped to caregiver_role in [Activity Aide] only And the current user has caregiver_role=Nursing Aide When a decision is requested for content_type=photo including R1 Then the engine returns decision=block (red) with reasons includes ["role_not_permitted"], resident_ids=[R1] And if the same request is repeated with caregiver_role=Activity Aide within the same context, Then decision=allow (green) with reasons includes ["resident_consent_active"]
Time‑Bound Consent Expiry Handling
Given resident R1 had consent effective_until=2025‑09‑01T00:00:00Z for images When a decision is requested at 2025‑08‑31T23:59:59Z with R1 detected Then decision=allow (green) and reasons includes ["resident_consent_active"] When a decision is requested at 2025‑09‑01T00:00:01Z with R1 detected Then decision=block (red) and reasons includes ["consent_expired"], and no redaction_targets
Deterministic Rule Precedence and Explainable Outcome
Rule: Precedence order is facility_hard_block > location_prohibited > resident_hard_block > role_not_permitted > time_expired > content_type_prohibited > unknown_face_action > resident_allow > facility_default_allow Given conflicting rules where resident R1 has an allow for images but the facility marks location=Bathroom as prohibited When a decision is requested including R1 in location=Bathroom Then decision=block (red), reasons ordered with reasons[0]="location_prohibited" And repeated identical requests (same inputs) produce identical decision, identical ordered reasons, and identical rule_trace[] entries
Decision API and Audit Logging Payload Contract
Given a decision is computed for any capture request When the engine returns HTTP 200 Then an audit event is written within 1s containing {request_id, decision, reasons[], rule_trace[], consent_version_ids[], policy_version_id, facility_id, unit, location, content_type, caregiver_role, timestamp, resident_faces[{id_or_unknown, action, bbox}], performed_by} And when GET /v1/decision-events?request_id={id} is called with valid auth Then it returns HTTP 200 within 2s with the persisted event matching the decision response payload, and events are immutable across reads
Auto-Blur & Redaction Pipeline
"As a Snapshot Aide, I want non-consenting faces automatically blurred so that I can share compliant updates without manual editing."
Description

Automatically apply irreversible redaction (blur or mosaic) to non-consenting or unknown faces prior to storage or distribution. Maintain accurate face boundary tracking, support multiple faces, preserve primary subject clarity, and generate instant previews. Process entirely on-device when possible; if server-side is used, send only necessary pixels over TLS and discard originals post-processing per policy. Provide manual review queue and override controls for stewards when policy permits.

Acceptance Criteria
On-Device Irreversible Redaction Before Save
Given a captured photo contains one or more non-consenting or unknown faces identified via FaceLink When the pipeline processes the photo on-device Then irreversible redaction is applied to each non-consenting or unknown face before any write to disk or any network transmission occurs And Then no unredacted pixels of non-consenting or unknown faces are present in any stored cache, upload payload, or preview artifacts And Then the redaction passes the irreversibility check (internal re-identification confidence <= 0.05 for each redacted face)
Consent Cross-Check at Capture
Given the device has synced FaceLink consent records within the last 24 hours and a photo is captured When face recognition matches detected faces to residents Then each face is classified as consenting, non-consenting, or unknown per current policy scope And When at least one non-consenting or unknown face is present Then the policy engine applies the configured action: per-face auto-blur redaction or full-post block, matching the site policy And Then the UI displays Clear (green) only when all faces are consenting; otherwise shows Redacted or Blocked with count of affected faces
Multi-Face Detection and Boundary Accuracy
Given a test set of photos containing 1–10 faces at varied angles and occlusions When processed by the pipeline Then face recall is >= 95% with false positive rate <= 2% against ground truth And Then redaction masks achieve Intersection-over-Union >= 0.65 with ground truth face regions and include a 10% margin And Then no redaction overlaps the consenting primary subject by more than 1% of their face area
Instant Preview and Green Light
Given a mid-tier reference device When a photo with up to 5 faces is captured Then the redacted preview renders on-device within <= 800 ms at P90 and <= 1.2 s at P99 And Then a green indicator is shown only when zero non-consenting or unknown faces are detected; otherwise show Redacted or Blocked per policy And Then the preview pixels exactly match the final stored or distributed image
Server-Side Fallback Minimal Pixels and Ephemeral Handling
Given on-device processing is unavailable or exceeds a 2-second timeout When server-side fallback is invoked Then only cropped face regions with 15% padding and minimal metadata are sent over TLS 1.2+ or TLS 1.3; originals are never uploaded And Then the server purges all received pixels and intermediates within 60 seconds post-processing and returns only redaction masks or a redacted image And Then the device discards any unredacted buffers; no face crops or originals persist on device or server, as verified by audit logs
Steward Manual Review and Override Controls
Given a post is blocked or redacted due to policy When it appears in the manual review queue Then Privacy Stewards with the appropriate role can approve, request changes, or override redactions within allowed policy scopes And Then any override requires a reason code and note; steward ID, timestamp, policy applied, faces affected, and action are recorded And Then the final decision updates the post accordingly and notifies the original submitter; all actions are auditable
Green/Yellow/Red Capture Indicator UI
"As a Snapshot Aide, I want a clear green-light when it’s safe to post so that I can move fast and stay compliant."
Description

Provide a simple capture UI with color-coded status (green=all cleared, yellow=redaction applied, red=blocked) and face counts. Offer tap-through details showing which residents were recognized and why, with guidance to reframe or step aside. Include haptics and accessible cues, work offline, and disable the shutter on hard blocks. Ensure minimal cognitive load to keep Snapshot Aides fast and compliant.

Acceptance Criteria
All-Consenting Faces Show Green with Accurate Face Count
Given the camera preview detects N faces and FaceLink marks all N as consenting for the current sharing scope, When detection stabilizes for ≥300ms, Then the capture indicator turns green within 500ms, displays "Cleared: N", enables the shutter, issues one short haptic pulse (50–80ms), announces "Cleared, N faces" for screen readers, and logs event capture_state=green with face_count=N. Given the indicator is green, When the user taps the indicator, Then the details sheet lists each recognized resident with name and consent scope as "Cleared" and no warnings. Given faces move or count changes, When stabilization completes (≥300ms without change), Then the displayed face count updates to match detected faces and remains correct in test scenes up to 5 faces.
Auto-Redaction Yields Yellow and Safe-to-Post
Given the preview detects at least one non-consenting face and the site policy allows redaction, When detection stabilizes, Then the indicator turns yellow within 500ms, shows "Redacted: M" (M = number of non-consenting faces), issues two short haptic pulses, provides accessible announcement "Redacted, M faces", and the shutter remains enabled. Given yellow state, When the user captures or posts, Then non-consenting faces are blurred in both preview and saved media with Gaussian blur radius ≥20px at 1080p (scaled proportionally), covering ≥95% of each face bounding box, and no unblurred pixels reveal identity at 200% zoom. Given yellow state, When the user taps the indicator, Then the details sheet lists each affected resident with reason "Consent not granted" and action "Blurred" plus the policy reference code, and offers guidance CTA "Reframe to exclude non-consenting person".
Hard Block Red with Shutter Disabled
Given the preview detects at least one non-consenting face and the site policy disallows redaction or consent is unknown/expired, When detection stabilizes, Then the indicator turns red within 500ms, shows a reason code (e.g., "Consent missing"), issues one long haptic (250–400ms), announces "Blocked", and the shutter is disabled and visibly dimmed. Given red state, When the user attempts to tap shutter, Then no image or video is captured, no frame is stored locally, and an inline guidance message appears: "Step aside or reframe to exclude non‑consenting resident". Given red state, When the user taps the indicator, Then the details sheet shows each detected face with status (Unknown/No consent/Expired), the blocking policy rule ID, and provides remediation tips; PHI is limited to recognized residents only; closing the sheet restores focus to the shutter within 100ms.
Details Sheet Content and Responsiveness
Given any indicator state (green/yellow/red), When the user taps the indicator, Then a details sheet opens within 300ms and is dismissible via swipe, back, or Close with a target size ≥44dp. Given the details sheet is open, When rendered, Then it shows a per-face list including: display name or "Unknown face", recognition confidence %, consent status, action taken (Cleared/Blurred/Blocked), reason code, and last consent update timestamp. Given the details sheet is open, When a user selects "Report misrecognition", Then only anonymized metadata (face box size, confidence, device model, app version, rule ID) is queued for upload; no image pixels are saved when state is red.
Offline Operation and Stale Data Handling
Given the device loses connectivity, When capture opens, Then an "Offline" badge appears within 1s and FaceLink uses the last-synced registry. Given offline mode, When a face has unknown consent due to missing data or registry age >24h for that resident, Then the indicator becomes red and shutter is disabled until the face exits frame or connectivity returns and data refreshes. Given offline audit events are generated (any state changes, captures, blocks), When connectivity resumes, Then all queued logs are uploaded within 60s and local queue is cleared; upon sync, the indicator re-evaluates current frame within 2s.
Accessible Multimodal Signals (Color, Haptics, Voice)
Given any indicator state, When displayed, Then color contrast against background is ≥4.5:1, and status is also conveyed by icon shape and text label so color is not the sole cue (meets WCAG 2.1 AA 1.4.1). Given device accessibility settings, When Reduce Motion or Haptics are disabled at OS level, Then animations are minimized and haptic feedback is suppressed while visual/text cues remain. Given a screen reader is active, When the indicator state changes, Then the app posts a live region announcement: "Cleared [N]", "Redacted [M]", or "Blocked" within 1s, and the indicator control has an accessible name and value reflecting state and counts.
Performance, Face Count Accuracy, and Cognitive Load
Given live preview on supported mid-tier devices, When face detection runs, Then preview maintains ≥24 FPS and indicator state changes propagate within 500ms of stabilization; shutter enable/disable toggles within 100ms. Given up to 5 faces in frame, When detection stabilizes for ≥300ms, Then the face count displayed equals the number of detected face boxes 100% of the time across the standard test set. Given user guidance microcopy under the indicator, When rendered, Then it is ≤60 characters, at or below Grade 6 reading level, and no more than one line on 375pt width.
Audit Trail & Steward Dashboard
"As a Privacy Steward, I want an auditable history of recognition and policy decisions so that I can verify compliance and resolve disputes."
Description

Capture immutable logs of detections, policy inputs, decisions, redactions, and user actions with timestamps and device identifiers. Provide a steward dashboard to search/filter by resident, date, unit, decision type, and export reports for audits. Surface alerts for repeated blocks or recognition failures, and support role-based access controls to protect sensitive data.

Acceptance Criteria
Immutable Audit Log Creation & Integrity
Given a photo or voice-to-text post is captured with FaceLink recognition enabled When any detection, policy input, decision, redaction, or user action occurs Then an audit event is appended with fields: event_id, event_time (ISO 8601 UTC), server_time, device_id, device_os, app_version, user_id, unit_id, resident_ids[], action_type, decision, policy_id, policy_version, outcome, correlation_id Given an audit event is written Then content_hash (SHA-256) and previous_hash are stored to form a verifiable hash chain And log storage is write-once (append-only) and prevents update/delete operations via application APIs Given the latest N events are validated When VerifyLogIntegrity is executed Then 100% of events return valid hash-chain continuity and signature verification Given a device is offline When audit events are generated Then they are queued encrypted at rest and uploaded within 60 seconds of connectivity without altering event_time
Dashboard Search & Filter Accuracy and Performance
Given a Privacy Steward opens the Audit Dashboard When filters are applied: resident (by name or ID), date range, unit(s), decision type(s) Then results include only events that match all selected filters, sorted by event_time desc with pagination (page size selectable: 25/50/100) Given a search is executed with valid filters over a dataset ≤ 50,000 events Then the first page renders within ≤ 2 seconds at p95 latency Given no events match the filters Then the result count is 0 and no rows are displayed
Report Export (CSV and PDF) with Filter Fidelity
Given filters are applied on the Audit Dashboard When Export CSV is requested Then the exported file includes only filtered rows, all visible columns plus event_id and correlation_id, UTF-8 with headers, timestamps in selected time zone Given filters are applied on the Audit Dashboard When Export PDF is requested Then the exported file includes the filter summary, a table of rows (up to 5,000 per file) with pagination, and a footer with generation time and checksum Given an export would include > 50,000 rows and ≤ 200,000 rows When export is requested Then an asynchronous job is created, a downloadable link is delivered within ≤ 10 minutes, the link expires in 7 days, and the export action is itself logged Given a user without export permission requests an export Then the request is denied with 403 and the attempt is logged
Repeated Blocks Alerting
Given the system tracks block decisions over time When block decisions for the same resident reach ≥ 3 within 24 hours or for the same unit reach ≥ 10 within 24 hours Then an alert is created within ≤ 5 minutes, visible in the Alerts panel, and delivered to stewards via configured channels Given an alert has already been raised for the same entity and window When additional block events occur Then the system increments the count without creating duplicate alerts and preserves a single thread for acknowledgment Given a steward views the alert When they acknowledge or resolve it Then the alert’s state, actor, and timestamp are recorded in the audit log
Recognition Failure Rate Alerting
Given the system measures recognition failures and unknown-face events When the recognition failure rate for a unit is ≥ 20% over the last 50 detections or unknown-face events ≥ 5 in 24 hours Then an alert is created within ≤ 5 minutes with entity, counts, window, and top error reasons Given a recognition failure alert exists When the failure rate drops below thresholds for a continuous 24-hour window Then the alert auto-resolves and the resolution is logged
Role-Based Access Controls & Data Scope Enforcement
Given predefined roles exist: Admin, Privacy Steward, Snapshot Aide When a user attempts to access the Steward Dashboard or Audit APIs Then only Admins and Privacy Stewards are granted access; Snapshot Aides receive 403 and the event is logged Given a user has unit-scoped permissions When they query or export Then only events for their permitted facilities/units are returned/exported Given a user downloads an export Then the file content reflects the user’s data scope and includes no events outside their permissions Given PII visibility rules are enforced When an Admin or Privacy Steward views data Then resident names and identifiers are fully visible; when a Snapshot Aide receives a 403 no PII is disclosed in responses
Decision Traceability & Redaction Evidence
Given an image or audio post is processed by FaceLink When faces are detected and consent policies are evaluated Then the audit log contains detection_count, recognized_resident_ids[], nonconsenting_detected flag, evaluated_policy_ids[], policy_versions[], decision (allow/blur/block), redaction_params, and device/user metadata Given a manual override of a system decision occurs When a steward changes allow/blur/block Then the audit log records the override_user_id, justification text (min 10 chars), previous_decision, new_decision, and timestamp Given a random sample of 100 events is selected When an auditor reviews only the logs and exports Then they can reconstruct the decision path (inputs, rules, outcome) for 100% of sampled events without accessing the original media
Consent Change Propagation & Retroactive Scrub
"As a Privacy Steward, I want consent updates to automatically trigger retroactive remediation so that existing content remains compliant without manual hunting."
Description

On consent updates or revocations, propagate new scopes to the policy engine and scan existing media to identify impacted items. Perform automated remediation (blur, unshare, or remove) per policy, notify affected recipient groups, and provide stewards with a review/approve workflow. Run as resilient background jobs with progress tracking, error retries, and SLA targets for completion.

Acceptance Criteria
Real-time Consent Propagation to Policy Engine
Given a resident’s consent is updated or revoked When the update is saved Then the policy engine receives the new scope within 30 seconds And the resident’s policy cache is invalidated within 30 seconds And any new capture or share checks after propagation enforce the updated scope And each update is versioned with a monotonic version and effective_at timestamp And out-of-order updates are resolved by version (last-write-wins by version, not receipt time) And duplicate updates are processed idempotently
Retroactive Media Scan and Automated Remediation
Given a consent revocation or scope narrowing takes effect When the retroactive scan job starts Then all existing media where the resident appears and violates the new scope are identified And remediation is applied per policy: blur faces, unshare links, or remove media And previously shared items become inaccessible within 5 minutes of remediation And job progress is available via API/UI (total, processed, remaining, percent, ETA) And 99% of jobs complete within SLA: up to 10,000 items in ≤ 30 minutes; linear scaling beyond And unaffected items remain unchanged
Recipient Notification on Content Changes
Given remediation unshares or removes content previously delivered When recipients are impacted Then notifications are sent within 5 minutes to affected recipient groups And notifications include count of items impacted, time window, and privacy-safe summaries And no PHI of non-consenting residents is disclosed in notifications And duplicate notifications for the same job and recipient are suppressed And recipient delivery outcomes (sent, bounced, opened) are tracked for audit And user notification preferences (channel, opt-out) are respected
Steward Review and Approval Workflow
Given policy requires steward review for specified remediations When impacted items enter the review queue Then stewards can view before/after previews with proposed redactions And stewards can Approve, Request Changes, or Override with required reason codes And approvals apply within 2 minutes and actions are auditable And overrides trigger reprocessing and, if applicable, re-notification And items pending review > 24 hours trigger escalation to designated admins
Resilient Background Jobs with Retries and Recovery
Given a scan/remediation job is running When transient errors occur (e.g., storage timeout, policy service 5xx) Then operations are retried with exponential backoff up to 5 attempts per item And items failing after max retries are moved to a dead-letter queue with diagnostics And jobs persist state and resume after worker restarts without duplicating work And exactly-once effects per media item are ensured via idempotency keys And deployments or node failures do not cancel jobs; they resume within 2 minutes
Comprehensive Audit and Compliance Reporting
Given any consent change and downstream actions When the job updates state or completes Then an immutable audit log records actor, timestamps (UTC), before/after scopes, affected media IDs, actions taken, notifications sent, and outcomes And audit entries are tamper-evident (hash-chained) and time-synced (NTP drift < 500 ms) And stewards can filter and export audit data by resident, date range, action, and outcome And retention policies are enforced with logged proofs-of-deletion for expired records
Effective Time and Scope Semantics
Given a consent change includes an effective_at timestamp and scope details When scanning for impacted items Then only media captured at or after effective_at are considered unless full-retroactive is configured And scope expansions re-authorize previously blocked items only per policy (auto-restore or steward approval) without premature exposure And multi-resident images honor the strictest consent across all detected faces And green-light status for new captures reflects latest scope within 30 seconds

eSign Anywhere

Collects and stores legally binding, multi‑language e‑signatures from authorized contacts in seconds—on device, via SMS/email, or lobby kiosk. Captures signer role (e.g., POA/guardian), ID photo, and timestamp; supports scanning/uploading paper forms for instant digitization. Consents activate immediately once signed, shrinking paper chases, expediting move‑ins, and keeping all proof centralized in the Vault.

Requirements

Multi-channel Signature Capture
"As an admissions coordinator, I want to collect signatures through the channel each family member prefers so that I can complete consents quickly without chasing paperwork."
Description

Enable staff to request, collect, and track legally binding signatures via in‑app capture, SMS/email links, or lobby kiosk. Provide a frictionless one‑tap flow with typed/drawn signatures, initials, checkboxes, and date fields optimized for touch. Generate secure, expiring links with OTP/magic‑code verification, handle resend/revoke, and show real‑time status in the resident’s record. Support offline capture on staff devices with encrypted local storage and automatic sync when online. Capture technical metadata (timestamp, IP, user agent, optional geolocation/device ID) and enforce session timeouts and rate limits. Integrate with KinLoop Contacts and the resident profile to prefill signer details and ensure channel selection fits the contact’s preferences. Provide robust error handling and fallback to the paper digitization workflow when needed.

Acceptance Criteria
In‑App One‑Tap Signature Flow (Typed/Drawn, Initials, Checkboxes, Dates)
Given a staff user initiates eSign from a resident’s record and selects an authorized contact When the signer opens the in‑app flow on a touch device Then the signer can choose between typed or drawn signature inputs And required initials fields must be completed before submit And required consent checkboxes must be explicitly checked before submit And date fields auto-populate with the signer’s local date but remain editable And the submit button remains disabled until all required fields validate And signature/initial capture areas accept finger or stylus input at 60 FPS on devices >= iOS 14 / Android 9 And field targets are at least 44x44pt for accessibility And upon submit, a confirmation screen displays the captured data summary before final confirmation
Secure SMS/Email Link with OTP and Expiring Tokens
Given a staff user sends a signature request via SMS or email When the system generates an access link Then the link contains a single-use token that expires after 7 days by default (configurable 1–14) And access requires a 6‑digit OTP delivered via the same channel And OTP TTL is 10 minutes with a maximum of 3 attempts before a 15‑minute lockout And resend is throttled to 1 per 60 seconds, max 5 resends per day per contact And staff can revoke a link; revocation takes effect within 1 second and invalidates the token And upon successful signing, the link is immediately invalidated and cannot be reused And all events (send, view, OTP verify, revoke, expire, complete) are logged with timestamps
Offline Signature Capture with Encrypted Local Storage and Auto‑Sync
Given a staff device is offline when starting a signature session When the signer completes the signature package Then the captured data (document, signature assets, metadata) is stored locally encrypted with AES‑256‑GCM And encryption keys are protected in the OS KeyStore/Secure Enclave And the session is marked "Pending Sync" with a visible offline badge And the app retries sync automatically with exponential backoff (1m, 2m, 5m, 10m, 30m) up to 10 attempts And on connectivity restoration, the pending session syncs within 15 seconds and status updates to "Completed" And if a conflict is detected (document updated server‑side), user is prompted to resolve and only one final version persists And locally stored artifacts are securely purged within 60 seconds of successful sync
Real‑Time Signature Status in Resident Record
Given a signature request with one or more signers is active When staff view the resident’s record Then a timeline shows per‑signer status with states: Not Sent, Sent, Viewed, Verified, Partially Signed, Completed, Declined, Revoked, Expired, Failed And status changes propagate to the UI within 5 seconds of the backend event And staff can filter by signer and channel, and resend or revoke from the same view And multi‑signer sequencing rules are respected (e.g., next signer notified only after previous completes when configured) And a downloadable audit report is available once any signer completes
Audit Metadata, Session Timeouts, and Rate Limiting
Given any signature flow (in‑app, link, or kiosk) When the signer interacts and completes or exits Then the system records immutable metadata: ISO‑8601 UTC timestamp, IP address, user agent, device ID (if available), and optional geolocation (if consented) And a tamper‑evident hash of the signed PDF and audit log is generated and stored And the signed PDF includes an appended Certificate of Completion summary page And sessions time out after 15 minutes of inactivity, requiring re‑verification to continue And signature request creation is rate‑limited to 5 per hour per contact and 60 per hour per facility, returning 429 on breach And on non‑recoverable delivery errors, staff are prompted to switch to Paper Digitization; the uploaded scan is linked to the request and status set to "Digitized" And error messages avoid leaking PII while providing actionable guidance
Contacts Integration and Channel Preference Enforcement
Given the resident’s KinLoop Contacts include roles and channel preferences When staff initiate a request and select a signer Then the signer’s name, role (e.g., POA/Guardian), and preferred language prefill the package And only approved channels for that contact are enabled by default; overrides require a reason and are logged And the system validates authority for restricted documents (e.g., POA required) before allowing send And the document and UI localize to the signer’s language, including date/time and right‑to‑left support where applicable And the signer can update contact info during verification; changes are reviewed and must be approved by staff before persisting
Lobby Kiosk Walk‑Up eSign with Identity Verification
Given a visitor uses the lobby kiosk to sign When staff lookup the resident and intended signer or the kiosk sends a magic link to the signer’s phone for verification Then the signer must verify identity via SMS OTP or staff‑assisted ID photo capture And the kiosk session auto‑resets after 60 seconds of inactivity and hard‑clears all local data on reset/complete And a privacy screen mode prevents shoulder‑surfing and disables external ports And the flow supports large‑font and high‑contrast accessibility modes And captured ID photo and timestamps are stored with the audit log and not retained on the kiosk after upload And the signer can select language at start; all screens and the certificate localize accordingly
Identity Verification with ID Photo & Document Scan
"As a compliance officer, I want reliable verification of each signer’s identity so that our signed consents are defensible during audits and disputes."
Description

Add optional identity verification to the signing flow by capturing a signer selfie (with liveness check) and scanning a government ID (driver’s license/passport). Automatically extract and compare name/DOB from the ID to the invited signer, flag mismatches, and allow documented manual override with reason codes. Store verification artifacts and a redacted preview in the Vault with clear retention rules. Display a confidence score and verification status to staff while minimizing friction for known/previously verified signers. Ensure consent is obtained for capturing biometric/ID data, and make the flow usable on personal devices and the lobby kiosk. Fail securely with clear guidance for in‑person verification steps when checks cannot be completed.

Acceptance Criteria
Consent Capture for Biometric/ID Verification
- Given a signer begins eSign Anywhere on any device or the lobby kiosk, When the flow requires identity verification, Then a consent screen explicitly describing biometric and ID data capture is displayed before any capture begins. - Given the consent screen is shown, When the signer selects "Agree", Then timestamp, language, version of notice, and consent method are recorded and stored with the transaction. - Given the consent screen is shown, When the signer selects "Decline", Then the verification flow is aborted, staff are notified in-app, and guidance for in-person verification is displayed. - Given organization languages are configured, When the signer selects their preferred language, Then the consent text and controls are displayed in that language. - Given a consent record exists, When staff view the transaction in the Vault, Then the consent artifact is retrievable and exportable.
Selfie Capture with Liveness Detection
- Given consent is captured, When the signer proceeds to selfie, Then the app opens the camera with framing guidance and accessibility hints. - Given the camera is open, When the liveness SDK checks motion/texture, Then a liveness result (pass/fail) and score are produced; failures prompt up to 3 guided retries. - Given repeated liveness failures, When maximum retries are reached, Then the flow fails securely and displays steps for in-person verification while logging the failure reason. - Given a pass result, When the selfie is captured, Then the image is stored as an artifact and associated to the transaction with hash and timestamp.
Government ID Scan and OCR Extraction
- Given consent is captured, When the signer selects ID type (driver’s license or passport), Then the camera scanner guides front/back/MRZ capture and validates glare, blur, and crop before accepting. - Given an ID image is captured, When OCR/MRZ parsing completes, Then full legal name and date of birth are extracted with a quality score; parse failures trigger up to 2 recaptures. - Given parsing repeatedly fails, When retries are exhausted, Then the flow fails securely and displays steps for in-person verification while logging the failure reason. - Given extraction succeeds, When non-required fields are present, Then only required data are stored in structured form; raw images are stored per retention rules.
Automated Identity Match with Mismatch Flagging and Fail-Secure Guidance
- Given invited signer metadata includes legal name and DOB, When extracted ID data are available, Then the system normalizes and compares name and DOB using defined rules (e.g., middle name, suffix) and computes a match score (0–100). - Given the match score is ≥ configured threshold, When comparison completes, Then the verification status is set to Verified and the confidence score is recorded. - Given the match score is < threshold or DOB mismatch, When comparison completes, Then the verification status is set to Mismatch, a blocking banner is shown to staff, and the signer is presented with guidance for in-person verification. - Given a mismatch occurs, When the user is remote, Then the system offers secure re-attempt options (recapture selfie/ID) limited to 2 attempts before fail-secure.
Manual Override with Reason Codes and Audit Trail
- Given a mismatch or failed verification, When an authorized staff user chooses Override, Then they must authenticate and select a reason code from a configurable list and optionally add notes. - Given an override is submitted, When the action completes, Then the system sets status to Overridden, records actor, timestamp, reason code, and notes in an immutable audit log, and links to supporting documents. - Given an override exists, When reports are generated or the record is viewed, Then the override details are visible to authorized users and exportable; signature activation proceeds only if policy allows overrides.
Vault Storage with Redacted Preview and Retention Enforcement
- Given verification artifacts (selfie, ID images, extracted fields, audit log) exist, When stored in the Vault, Then they are encrypted at rest, access-controlled, and indexed by transaction. - Given artifacts are stored, When staff view the record, Then a redacted preview of the ID image is shown with sensitive fields masked; full images require elevated permissions. - Given retention settings are configured (e.g., X months/years), When the retention period elapses, Then raw images are purged automatically while retaining minimal verification metadata; purges are logged. - Given a legal hold is applied, When a purge would occur, Then artifacts under hold are retained until the hold is lifted.
Confidence Score & Low-Friction Flow Across Devices and Kiosk
- Given a signer was previously Verified within the configured lookback window, When they re-sign, Then the system bypasses ID scan/selfie steps per policy and reuses prior verification while displaying the reused verification banner. - Given verification completes (new or reused), When staff view the signer in the eSign dashboard, Then a confidence score (0–100) and status badge (Verified, Mismatch, Overridden, Not Verified) are displayed with hover details. - Given access via SMS/email on personal device or lobby kiosk, When the verification steps run, Then the UI performs within 3 seconds per step on a 3G-equivalent connection and supports touch and keyboard-only input. - Given the kiosk session times out, When no activity is detected for N minutes, Then all captured data are cleared from the device and the session returns to the welcome screen.
Role-based Authorization & Consent Mapping
"As an admissions coordinator, I need to ensure only appropriately authorized contacts can sign specific forms so that we stay compliant and avoid voided agreements."
Description

Capture the signer’s legal role (e.g., POA, guardian, health care proxy) during the invite and signing process, validate it against the resident’s authorized contacts, and require proof documents where applicable. Configure which roles are permitted to execute each consent/form type, and block signing until required role evidence is on file. Support multi‑signer workflows (e.g., co‑guardians), delegated authority, and countersignature by facility representative. Persist role metadata with the signature and expose it in the audit trail. Automatically map signed consents to the resident’s consent matrix and update role assignments when documentation is approved.

Acceptance Criteria
Role Capture and Pre‑Invite Validation
Given a staff user selects a resident and initiates an invite, When the user selects the signer’s legal role from a controlled list (POA, Guardian, Health Care Proxy, etc.), Then the selection is required and stored with the invite token. Given the selected role requires proof documentation, When no valid proof is attached, Then the Send Invite action is disabled and an inline error specifies the missing document type. Given the resident has an existing authorized contacts registry, When the invite is saved, Then the system validates the invitee’s identity and role against the registry and flags any mismatch for correction before sending. Given a signer opens the invite, When they attempt to change their declared role, Then the system re-validates permissions and requires any additional proof before allowing signature entry. Given all validations pass and required documents are attached, When Send Invite is pressed, Then the invite is successfully issued and logged with the declared role metadata.
Role‑Based Consent Configuration and Enforcement
Given a consent/form type has a configured set of permitted roles, When a signer’s validated role is not in the permitted set, Then the signing UI is blocked and a specific “Role not authorized for this consent” message is displayed. Given a consent/form type requires evidence-on-file for certain roles, When evidence is pending review or rejected, Then signing is blocked until evidence status is Approved. Given the signer’s role is permitted and evidence is Approved, When the signer completes the signature, Then the consent transitions to Signed (pending any additional required signatures) without error. Given an admin updates the permitted roles configuration for a consent type, When the configuration is saved, Then new invitations use the updated rules and previously executed consents remain unaffected.
Co‑Guardian Multi‑Signer Workflow
Given a consent type is configured to require two co‑guardian signatures, When the first co‑guardian signs with an Approved role, Then the consent status is Pending second co‑guardian and is not active. Given the workflow is configured as sequential, When the first required role signs, Then the second required role is the only role permitted to sign next and others are blocked. Given the workflow is configured as parallel, When either co‑guardian signs, Then the other co‑guardian can sign at any time, and duplicate signatures from the same individual are prevented. Given all required co‑guardian signatures are captured with Approved roles, When the final signature is applied, Then the consent activates immediately (unless countersignature is also required).
Delegated Authority Handling
Given a principal role holder (e.g., POA) submits a delegation document naming a delegate for a resident, When a reviewer approves the document with scope and validity dates, Then the delegate is added with a Delegated <Role> designation and recorded scope/expiry. Given a delegated signer attempts to sign a consent, When the consent type is outside the approved scope or the delegation is expired/revoked, Then the signing action is blocked with a specific reason. Given a delegated signer completes a permitted consent, When the signature is recorded, Then the audit trail links the delegate to the principal and records the delegation document reference. Given a delegation is revoked, When there are pending invitations issued to the delegate, Then those invitations are invalidated and cannot be completed.
Facility Countersignature Flow
Given a consent type is configured to require a facility countersignature, When all required external signer roles have completed with Approved evidence, Then the system requests a countersignature from a user with the authorized facility role. Given countersignature is required, When a staff member without the authorized facility role attempts to sign, Then the action is blocked with an authorization error. Given countersignature is required, When the authorized representative signs, Then the consent status changes to Active and the audit trail records the representative’s identity, role, and timestamp. Given countersignature is required, When external signatures are not yet complete, Then countersignature cannot be captured and the UI indicates the missing prerequisites.
Proof Document Review and Role Assignment Update
Given a contact uploads proof documentation for a claimed role, When a designated reviewer marks the document as Approved, Then the contact’s role status updates to Approved and becomes eligible to sign where permitted. Given a reviewer rejects the proof with a reason, When the contact attempts to sign, Then the signing action is blocked and the rejection reason is displayed with instructions to resubmit. Given a resident lacks an authorized contact record for the claimant, When the proof is Approved, Then the system creates/updates the resident’s authorized contacts registry with the contact and approved role. Given a contact uploads a newer version of proof, When Approved, Then the previous version is archived with a version history entry and the new version becomes the active basis for authorization.
Audit Trail and Consent Matrix Mapping
Given a consent reaches its fully executed state (all required signers and countersignature complete), When the system finalizes the record, Then it persists for each signer: legal role, proof document reference and approval status, ID photo reference, timestamp, and unique signature ID in the immutable audit trail. Given a consent is fully executed, When finalization occurs, Then the consent is automatically mapped to the resident’s consent matrix under the appropriate category with status Active and effective date/time. Given a signature was captured while evidence was pending, When the evidence is later Approved, Then the audit trail records the approval event and the consent’s status updates per configuration (e.g., moves from Pending evidence to Active) without re-signing. Given a paper form is scanned/uploaded and digitized with required role metadata, When validation passes, Then the consent is mapped to the resident’s consent matrix and labeled as Digitized paper in the audit trail.
Paper Form Digitization with Smart Field Detection
"As a front desk associate, I want to snap a photo of a paper form and turn it into a reusable e‑sign template so that I can stop reprinting and chasing physical paperwork."
Description

Allow staff to scan or upload paper forms and convert them into clean, e‑signable documents. Perform image enhancement (de‑skew, crop, glare/contrast correction) and OCR to detect common fields (signature, initials, date, checkboxes, text). Provide a human‑in‑the‑loop editor to confirm or draw fields, set required/optional rules, and save as reusable templates with merge fields tied to KinLoop resident data. Support multi‑page documents, template versioning, and a QR/barcode stamp to route returned paper to the correct resident/form. Generate accessible, fillable PDF/A outputs and retain the original scan alongside the templated version in the Vault.

Acceptance Criteria
Auto Image Enhancement on Upload/Scan
Given a staff member uploads or scans a paper form image with skew ≤ 15° and uneven lighting When the system processes the image Then page edges are auto-detected and cropped with tolerance ≤ 2 mm from the border And skew is corrected to within ±1° And glare/contrast normalization yields an OCR average character confidence ≥ 85% on printed text And an enhanced preview is displayed within 4 seconds for a single Letter/A4 page ≤ 3500×2500 px And the enhanced page is stored at ≥ 300 DPI
Multi-Page Document Support
Given a multi-page paper form (2–50 pages) is captured via camera or uploaded as a PDF When ingestion and processing complete Then all pages are retained in order with thumbnails And the user can reorder pages via drag-and-drop, delete pages, and insert additional pages before saving And image enhancement and OCR are applied page-by-page And average processing time is ≤ 1 second per page for up to 20 pages
OCR Field Detection for Common Fields
Given an enhanced page is ready for analysis When automatic field detection runs Then signature lines, initial boxes, date fields, checkboxes, and text input regions are identified and typed correctly And each detected field displays a confidence score And fields with confidence < 0.60 are flagged for human review And on a defined benchmark set, detection achieves ≥ 90% precision and ≥ 90% recall for common fields
Human-in-the-Loop Field Editor with Required/Optional Rules
Given detected fields are presented in the editor When a user edits the template Then the user can move, resize, delete, and draw fields (signature, initials, date, checkbox, text) And set each field as required or optional and configure validation (e.g., date format, text length) And snap-to-grid and alignment guides assist precise placement And the editor prevents saving if any required field is out of bounds or overlapping And a live preview simulates completion and blocks completion when required fields are empty
Template Save with Merge Fields to Resident Data and Versioning
Given a user maps fields to KinLoop resident data When the template is saved as reusable Then mapped merge fields (e.g., resident_name, DOB, room_number) pre-fill correctly on preview for a selected resident And the template is assigned a semantic version (e.g., v1.0.0) or incremented appropriately with change notes And prior versions remain read-only and retrievable And an audit log records saver identity, timestamp, and changed elements
QR/Barcode Stamp and Routing of Returned Paper
Given a finalized template is configured to include a routing code When a QR or 1D/2D barcode with resident and template identifiers is stamped at a user-selected position with adequate quiet zone Then printed copies include the code without obscuring fields And when a coded paper is later scanned or uploaded, the system decodes and auto-routes it to the correct resident and form record in the Vault And decoding/routing succeeds in ≥ 99% of scans for codes printed at ≥ 200 DPI with moderate wear And failures prompt manual assignment and are logged
Accessible Fillable PDF/A Output and Vault Retention
Given a template is finalized When generating the e-signable document Then the output is a tagged, accessible, fillable PDF/A (e.g., PDF/A-2u) with correct reading order and accessible field names/tooltips And the PDF passes validation with a standard PDF/A conformance checker And the original scan(s) are retained alongside the templated PDF in the resident’s Vault record And both artifacts are immutable, timestamped, and linked to the template version, with preview and download available
Instant Consent Activation & Policy Hooks
"As a caregiver, I want consents to take effect the moment they’re signed so that I can share updates confidently without waiting for manual approvals."
Description

On successful signature, immediately update resident consent flags and trigger KinLoop policy hooks (e.g., enable/disable sharing types, adjust auto‑blur behavior, restrict media categories). Support granular consent scopes (photo, video, audio, messaging, release of information), effective and expiration dates, and scheduled re‑consent. Emit events/webhooks for downstream systems (EHR/CRM) and move‑in checklists. Block posting/sharing actions if required consents are not active and surface clear guidance to staff. Notify relevant caregivers and display consent status prominently in the resident header and activity composer.

Acceptance Criteria
Instant Activation on Successful Signature
Given a resident has a pending consent package and the signer completes with a valid e-signature When the eSign service returns a success callback for that package Then the resident’s consent flags for all scopes in the package are set to Active within 5 seconds if the client is online And effectiveAt is set to the server signature timestamp (ISO 8601 UTC) And the change propagates to all active sessions/devices within 5 seconds via realtime sync And if a client is offline, the flags update within 30 seconds of reconnection and next sync And the update is idempotent—replaying the same callback does not create duplicates or flip states
Policy Hooks Apply Sharing/Blur/Category Rules
Given any consent scope for a resident changes state When the policy engine evaluates the new consent state Then disallowed sharing types are hidden or disabled in the activity composer immediately And auto-blur is forced on for visual media when photo/video consent is inactive and can be toggled per policy when active And restricted media categories mapped by facility policy to the consent state are blocked And only media options permitted by active scopes are enabled And server-side validation rejects noncompliant submissions with HTTP 403 and a machine-readable reason code
Granular Scopes with Effective/Expiration and Re-Consent
Given scopes exist for photo, video, audio, messaging, and release of information each with effectiveAt and expiresAt When current time is on/after effectiveAt and before expiresAt Then the scope status is Active; otherwise it is Inactive or Expired accordingly And scheduled re-consent reminders are created at activation with notices 14 and 3 days before expiresAt (org-configurable) And upon expiresAt, actions requiring the scope are blocked and re-consent prompts are auto-surfaced And all time logic stores UTC and renders in facility timezone for UX
Consent Events/Webhooks to Downstream Systems
Given a consent activates, updates, or expires for a resident When the state change is committed Then an internal event is published within 1 second and an external webhook is delivered within 3 seconds And the webhook payload includes residentId, facilityId, scopesChanged, previousState, newState, effectiveAt, expiresAt, signerId, signerRole, consentPackageId, timestamp, correlationId, idempotencyKey, and signatureEvidenceUrl And webhooks are retried with exponential backoff for up to 24 hours with at-least-once delivery and idempotency honored by idempotencyKey And subscribed move-in checklist items are auto-completed within 5 seconds of activation
Blocking and Staff Guidance When Consent Missing
Given a staff user attempts to compose or post content that requires a consent scope When the required consent is not Active Then the Post action is disabled and an inline message lists missing scopes with a one-tap "Request eSign" action And any direct API attempt returns HTTP 403 ConsentRequired with the missing scopes enumerated And actions not requiring the missing scope remain available And the system logs the blocked attempt with userId, residentId, requiredScope, timestamp, and reason
Prominent Consent Status in Header and Composer
Given a resident profile is viewed in the app When the header and composer render Then per-scope badges (Photo, Video, Audio, Messaging, ROI) display status Active/Inactive/Expired and expiry date or <30-day countdown And the composer shows contextual hints reflecting current scope status And after a successful signature, UI reflects new status within 5 seconds without manual refresh And badges meet WCAG AA contrast and include screen-reader labels with scope, status, and expiry
Notifications and Audit Trail on Consent Changes
Given a consent changes to Active, Updated, or Expired When the change is saved Then assigned caregivers and facility admins receive notifications per preference (push/email) within 2 minutes including resident, scopes affected, new status, effective/expiry, and a deep link And an immutable audit record is created capturing before/after values, actor (system/signer/staff), channel (device/SMS/email/kiosk), deviceId/IP, location if available, timestamp, and evidence pointers And audit records are queryable by resident and time range and exportable as CSV and PDF
Secure Vault Storage & Comprehensive Audit Trail
"As an administrator, I need centralized, secure storage with a complete audit trail so that I can retrieve defensible evidence quickly during audits or disputes."
Description

Store all signed documents, templates, verification artifacts, and proofs in the KinLoop Vault with encryption at rest and in transit, tenant‑scoped keys, and tamper‑evident hashing. Generate a certificate of completion including signer identity data, role, timestamps, IP/user agent, document checksum, and any verification outcomes. Provide role‑based access controls, legal hold/retention policies, exportable audit bundles, and full‑text search. Implement backups and disaster recovery objectives, and expose immutable event logs to support ESIGN/UETA/eIDAS‑aligned evidence requirements and healthcare privacy obligations. Allow administrators to configure data residency and retention per region/policy.

Acceptance Criteria
Tenant‑Scoped Encryption and Tamper Evidence
Given any Vault artifact is written, When persisted at rest, Then it is encrypted with AES‑256‑GCM under a tenant‑scoped CMK and the CMK ID is recorded with the object metadata. Given any client connects to Vault APIs, When data is transmitted, Then TLS 1.2+ with modern ciphers is enforced and connections using TLS <1.2 are rejected. Given keys reach the rotation interval (12 months or admin‑configured), When rotation occurs, Then new key versions are used for new writes and old versions remain for decrypting historical data, with rotation events logged. Given an artifact is read with a non‑matching tenant context, When decryption is attempted, Then access is denied with 403 and the attempt is logged. Given any stored artifact is altered outside the system, When its integrity check runs on read, Then a SHA‑256 checksum mismatch is detected, access is blocked, and a tamper event is logged.
Auto‑Generated Certificate of Completion
Given all required signers have completed a document package, When the last signature is submitted, Then a certificate of completion is generated within 5 seconds. Given the certificate is generated, Then it contains signer full name, captured role, unique signer ID, ID photo reference, ISO‑8601 UTC timestamps (start and completion), IP address, user agent, document/package IDs, SHA‑256 document checksum, and verification outcomes (e.g., OTP/ID check results). Given the certificate is generated, Then it is stored in the Vault linked to the document/package and is immutable; any change creates a new version with a reason and both versions are retained. Given an authorized user views the document, When requested, Then the certificate is downloadable and included in exports.
RBAC‑Enforced Access with Immutable Audit Trail
Given a user with role Caregiver, When they attempt to view Vault artifacts outside their assigned residents, Then access is denied with 403 and no data is returned. Given a user with role Administrator or Compliance Officer, When they access Vault artifacts for any resident in their tenant, Then access is granted. Given any Vault read/write/delete/export action, When it occurs, Then an audit event is appended capturing actor ID and role, tenant ID, object ID, action, timestamp (UTC), IP, and user agent. Given audit logs are stored, When modification or deletion is attempted, Then the attempt is rejected and recorded; daily hash chaining ensures integrity verification passes with no gaps.
Configurable Data Residency, Retention, and Legal Hold
Given an administrator sets data residency to a region (e.g., US or EU), When new artifacts are stored, Then their storage location metadata reflects the selected region and cross‑region storage is prevented unless explicitly allowed by policy. Given retention rules per artifact type (e.g., 7 years for consents), When an artifact reaches expiry, Then it is purged within 24 hours and the purge is logged. Given a legal hold is applied with case ID and reason, When purge time arrives, Then deletion is blocked until the hold is removed and the block is logged. Given export is requested for an artifact with residency constraints, When generating the export, Then the export occurs in‑region and cross‑region transfers are blocked.
Exportable Audit Bundle
Given an authorized Administrator selects a completed document, When Export Audit Bundle is requested, Then a ZIP bundle is generated within 60 seconds. Given the bundle is generated, Then it includes the signed document, original template, certificate of completion, verification artifacts (e.g., ID photo, OTP logs), and the object‑scoped event log. Given the bundle contents, Then a manifest.json lists file names, SHA‑256 checksums, versions, and timestamps; a detached signature and public certificate are included, and signature verification succeeds. Given the bundle is downloaded via link, When the pre‑signed URL expires (≤ 15 minutes), Then further downloads are denied.
Full‑Text Search Across Vault
Given an artifact is uploaded (including scanned paper), When OCR and indexing complete, Then the artifact becomes searchable within 2 minutes. Given a user submits a search query, When results are returned, Then only artifacts the user is authorized to access are shown. Given a search index of 1,000,000 artifacts, When running a term query, Then P95 response time is ≤ 2 seconds and P99 ≤ 5 seconds. Given a user filters by signer, resident, date range, and artifact type, When applying filters, Then results reflect all filters accurately and counts are correct. Given an artifact is deleted by retention, When the index updates, Then the artifact no longer appears in search within 24 hours.
Backups and Disaster Recovery
Given normal operation, When backups run, Then point‑in‑time recovery is available with RPO ≤ 15 minutes and backups are encrypted and verified. Given a scheduled DR test, When a primary region outage is simulated, Then the Vault is restored in the secondary region with RTO ≤ 4 hours and all artifacts, certificates, and audit logs are intact. Given a restore operation completes, When integrity checks run, Then checksum manifests and audit log hash chains validate with no discrepancies. Given legal holds exist at backup time, When data is restored, Then those holds persist and continue to block deletions.
Multi-language Templates & Localized Signing Experience
"As a family member whose first language isn’t English, I want the signing flow and documents in my language so that I can understand and confidently agree to consents."
Description

Offer a fully localized signing experience and document output across supported languages, selectable per recipient and available on kiosk. Manage translations for UI, email/SMS invites, legal boilerplate, and template content with version control and reviewer workflows. Support RTL scripts, appropriate fonts, date/number formats, and accessibility features (read‑aloud prompts, large touch targets). Generate language‑specific PDFs with correct hyphenation and reading order. Allow jurisdiction‑specific clauses and language variants to be tied to facility location and resident jurisdiction, with sensible fallbacks when a language or clause is unavailable.

Acceptance Criteria
Recipient-Specific Language Selection and UI Localization
Given a template with translations (en-US, es-MX, fr-CA) and a recipient preference of es-MX, When the recipient opens the invite via SMS or email, Then all UI strings, system messages, legal boilerplate, and template content display in es-MX. Given a specific UI string lacks es-MX, When rendering, Then the app falls back to es, and if absent to the facility default (en-US), and records the fallback path in the audit log. Given a multi-recipient envelope with mixed language preferences, When each recipient opens the signing flow, Then each sees their own localized UI and document without affecting others. Given an invite email/SMS is queued for a recipient, When it is sent, Then subject, body, CTA, and legal disclaimers are localized to the recipient language and pass link opens in the same language. Given the recipient changes language via the language switcher, When a new language is selected, Then the UI re-renders within 500 ms and the choice persists for the session and is included in the audit log.
Kiosk Language Selection and Accessibility Controls
Given a lobby kiosk is idle, When the attract screen displays, Then a language picker shows all enabled languages using native names and search, with the facility default preselected. Given a signer selects a language on the kiosk, When the signing flow starts, Then all screens, prompts, and read‑aloud TTS are in the selected language, touch targets are ≥44x44pt, and focus order is logical for keyboard and switch input. Given no interaction for 60 seconds, When timeout occurs, Then the kiosk returns to the attract screen, clears session data/PHI, and restores the default language. Given accessibility mode is toggled on, When applied, Then font size increases ≥30%, high‑contrast theme is applied, and all interactive elements remain within viewport on a 10" display without horizontal scrolling.
RTL Script Support in Signing Flow
Given an Arabic (ar) template, When the signing flow renders, Then UI chrome, progress indicators, and document content are mirrored RTL while mixed LTR fields (emails, numbers) retain correct LTR segments per Unicode Bidi rules. Given the signer inputs Arabic text in a text field, When typing, Then caret movement, selection, and line wrapping behave per the Unicode Bidi Algorithm and saved values preserve order. Given a PDF is generated for an RTL language, When inspected, Then structure/reading order tags, bookmarks, and article threads reflect RTL order and screen readers read content in correct sequence.
Locale-Specific Date, Time, Number, and Currency Formatting
Given locale fr-CA, When displaying dates and numbers in the UI and PDF, Then dates use D MMMM YYYY (or YYYY‑MM‑DD if configured), week starts Monday, thousands separator is thin space, and decimal is comma. Given locale en-GB, When displaying times, Then 24‑hour format is used; Given locale en-US, Then 12‑hour format with AM/PM is used. Given facility currency CAD and locale fr-CA, When rendering currency amounts, Then the symbol, spacing, and placement follow CA‑FR conventions (e.g., 1 234,56 $ CA). Given timestamps are captured, When stored, Then values are saved in UTC with facility timezone and display locale recorded in the audit log.
Language-Specific PDF Generation with Hyphenation and Reading Order
Given a de-DE template with hyphenation dictionaries, When generating a PDF, Then automatic hyphenation follows de-DE rules and avoids invalid breaks (no orphaned syllables across page breaks). Given a document includes Latin+CJK scripts, When generating a PDF, Then appropriate fonts with full glyph coverage are subset‑embedded (no tofu) and a 10‑page document remains ≤5 MB. Given any generated PDF, When validated, Then Lang and structure tags are present, form fields have ActualText, alt text exists for non‑decorative images, and reading order matches the on‑screen flow; for RTL, article/thread order is RTL. Given a screen reader (NVDA/JAWS/VoiceOver) reads the PDF, When navigating headings and fields, Then announcements use the selected document language and correct label associations.
Jurisdiction-Specific Clauses with Sensible Fallbacks
Given facility location CA-BC and resident jurisdiction US-CA, When generating a consent, Then clauses mapped to (facility=CA-BC, resident=US-CA) are included and non‑applicable clauses are excluded. Given no exact resident clause exists, When rules evaluate, Then the system falls back to country‑level (US) and then facility default with the applied fallback path recorded in the audit log. Given clause versions have effective dates, When generating on/after a new effective date, Then the new version is applied; generating before uses the prior version. Given an admin previews a template with different resident jurisdictions, When switching the jurisdiction selector, Then the preview updates clauses within 500 ms and displays the source and fallback path per clause.
Translation Version Control and Reviewer Workflow
Given a translator submits an update for es-MX v2, When submitted, Then the translation enters In Review and cannot be used for production envelopes until approved; es-MX v1 remains live. Given a reviewer with the Translator Reviewer role approves v2, When approval is recorded, Then v2 becomes live for new envelopes, prior invites continue on v1, and the audit log captures approver, timestamp, and change summary. Given a reviewer rejects a translation, When rejecting, Then a comment ≥10 characters is required, submitter is notified, and status is set to Changes Requested. Given an admin attempts to publish a template with missing translations, When validation runs, Then publishing is blocked with the missing key count and list unless an explicit fallback override is accepted and recorded.

Incident Freeze

One‑tap legal hold suspends media sharing for a resident, unit, or whole community after an incident or family request. Requires DuoTap to initiate or lift, logs reason and timeframe, and notifies staff at capture with clear guidance. Prevents accidental posts during sensitive periods while preserving a clean audit trail and protecting resident dignity and organizational risk.

Requirements

DuoTap Legal Hold Control
"As a charge nurse or administrator, I want to apply or lift a legal hold with a second authorized confirmation so that no single person can inadvertently enable or disable sharing during sensitive incidents."
Description

Require two distinct authorized staff to initiate or lift an Incident Freeze, capturing both identities, roles, timestamps, and authentication method. Enforce role-based permissions and optional step-up verification for high-risk scopes. Mandate structured reason selection and a timeframe before activation; block activation if inputs are incomplete. Support offline initiation via signed, time-bounded tokens with deferred server validation. Log every attempt (success/failure) with tamper-evident event chaining to preserve audit integrity. Provide clear success/failure states with retry and escalation paths, and ensure the hold immediately propagates to all capture and sharing workflows without impacting normal capture performance.

Acceptance Criteria
DuoTap Initiation Captures Identities and Enforces Permissions
Given a user with Initiate Freeze permission selects a resident, unit, or community scope and opens the Incident Freeze control And the structured Reason and Timeframe fields are populated And a second distinct authorized approver presents within 5 minutes When both staff authenticate using supported methods and confirm initiation Then the system records two distinct user IDs, roles, timestamps, and authentication methods for the initiation And any attempt where the two user IDs are identical is rejected with an error and logged as a failure And if either user lacks the required role-based permission the initiation is denied with a descriptive error and logged as a failure And the hold becomes active within 300 ms on the initiating device and within 3 seconds on other online clients in scope And all capture and sharing workflows in the selected scope block posting and display hold guidance immediately upon activation
DuoTap Lift with Step-Up for High-Risk Scopes
Given an active Incident Freeze at unit or community scope where step-up verification is required by policy And two distinct authorized staff attempt to lift the hold When at least one approver successfully completes step-up verification in addition to standard authentication Then the hold is lifted and the system records both user IDs, roles, timestamps, authentication methods, and step-up method And if step-up is required but not satisfied the lift is blocked with a descriptive error and logged as a failure And the lifted state propagates within 300 ms on the device performing the lift and within 3 seconds to other online clients in scope And capture and sharing workflows resume normal behavior once the lift state is received
Structured Reason and Timeframe Required Before Activation
Given a user initiates the Incident Freeze flow When the user attempts to confirm without selecting a structured Reason from the configured list and specifying a Timeframe within configured bounds Then the confirm action remains disabled and inline validation messages indicate missing or invalid inputs When the user selects a valid Reason and a valid Timeframe (duration or end date/time) within configured bounds Then the confirm action enables and the selected Reason and Timeframe are persisted with the initiation record and displayed in the confirmation summary
Offline DuoTap via Signed Time-Bounded Tokens with Deferred Validation
Given both approvers are offline and possess valid signed, time-bounded tokens issued for Incident Freeze actions And the tokens have not expired and have not been used previously When the approvers DuoTap and present their tokens and authenticate locally Then the hold becomes Provisionally Active locally within 300 ms and capture/sharing workflows in scope are blocked with guidance And upon connectivity restoration the server validates both tokens within 5 seconds and either finalizes the hold if valid or automatically lifts it within 5 seconds if any token is invalid, expired, or revoked And any token reuse attempt is rejected both offline and online with a descriptive error and logged as a failure And if only one valid token is presented offline the initiation is denied and logged as a failure
Tamper-Evident Audit Logging for All Attempts
Given any attempt to initiate or lift an Incident Freeze occurs When the event is recorded Then the log entry includes event type, outcome (success/failure), scope, both actor IDs and roles (for DuoTap), timestamps, device IDs, authentication methods, reason, timeframe, and any step-up or offline token indicators And each entry contains a cryptographic hash of its contents and a hash link to the previous entry to form a tamper-evident chain And chain verification detects any modification or deletion via a public verification endpoint accessible to authorized roles And log storage is write-once append-only and enforces access controls restricting read access to authorized roles And clock skew beyond ±5 minutes is flagged in the entry without blocking the action
User Feedback, Retry, and Escalation on Failure
Given an initiation or lift attempt fails due to network error, permission denial, or second-approver timeout When the initiating user views the result Then a clear failure banner with a human-readable reason and an error code is displayed and an audit entry is created And a Retry option is available for transient failures for 10 minutes without re-entering Reason/Timeframe And if no second approver confirms within 5 minutes or after two consecutive failures an Escalate option appears that notifies the on-call supervisor and records the escalation in the audit log And on success a confirmation banner is shown to both participants and relevant staff receive a push notification of the new state
Immediate Propagation Without Performance Degradation
Given no active Incident Freeze exists Then capture and sharing workflows exhibit added latency ≤ 50 ms at p95 compared to baseline with the feature enabled Given an Incident Freeze is initiated or lifted Then the new state is enforced across all capture and sharing workflows within 3 seconds for online clients and at next heartbeat (≤ 30 seconds) for background clients And hold-state checks add ≤ 20 ms p95 overhead to capture start when a hold exists And if any client cannot confirm state within the SLA it locally blocks sharing and displays a sync indicator until the state is synchronized
Scoped Freeze Targeting (Resident/Unit/Community)
"As an administrator, I want to freeze sharing at the resident, unit, or community level so that I can respond precisely to an incident without over- or under-blocking."
Description

Enable holds to be targeted at the resident, unit, or community scope with immediate propagation to all related entities and media pipelines. Apply additive enforcement: if any applicable scope is frozen, sharing is blocked. Resolve scope changes dynamically (e.g., room transfers, admissions/discharges) and ensure the correct enforcement follows the resident and unit membership in real time. Block inclusion of frozen subjects in digests, feeds, or outbound shares while allowing secure local capture/storage. Provide admins with a preview of impacted users and content before activation and a summary of coverage after activation.

Acceptance Criteria
Resident-Level Freeze Blocks Sharing, Allows Local Capture
Given a resident-level freeze is activated for Resident R When any user attempts to share media that includes Resident R Then the share action is blocked across mobile and web within 10 seconds of activation And a non-dismissible notice explains that a resident-level legal hold is in effect And any new captures tagged to Resident R are saved locally/securely but cannot be posted, included in digests, or shared outbound And the enforcement event is recorded with resident ID, scope=residential, timestamp, and actor
Unit-Level Freeze Propagates to All Members
Given Unit U has residents R1..Rn and a unit-level freeze on U is activated When any user attempts to share media that includes any current member of Unit U Then the share action is blocked within 10 seconds across mobile, web, and outbound pipelines And new admissions to Unit U during the freeze become enforced within 10 seconds of membership update And residents removed from Unit U are no longer blocked due solely to the unit freeze after removal And unit feeds and unit-scoped digests exclude content featuring Unit U members while the freeze is active
Community-Level Freeze Halts All Outbound Sharing
Given a community-level freeze is activated for Community C When any user attempts outbound sharing, posting to feeds, or digest generation for any resident in Community C Then all outbound pipelines are blocked within 10 seconds and marked as under legal hold And local capture remains permitted and stored securely without outbound distribution And when the freeze is lifted, outbound pipelines resume but no content captured during the freeze is auto-shared without explicit re-queue by an admin
Additive Enforcement Across Overlapping Scopes
Given Resident R belongs to Unit U in Community C and multiple freezes may be active (resident, unit, community) When content includes Resident R (or is scoped to Unit U) Then sharing is blocked if any applicable scope (R, U, or C) is frozen And if freezes exist on multiple scopes, lifting sharing restrictions requires all applicable freezes to be lifted And the UI communicates the most specific blocking scope available (resident over unit over community) while retaining additive enforcement And audit logs capture all contributing scopes for each blocked attempt
Real-Time Enforcement on Unit Transfer During Active Freeze
Given Resident R transfers from Unit U1 to Unit U2 And a freeze is active on U2 but not on R or U1 When the transfer is saved in the source-of-truth system Then within 10 seconds, sharing of content including R is blocked due to the U2 freeze And if a freeze is active on U1 but not U2, then after transfer R is no longer blocked due solely to U1 And membership changes propagate without requiring app restart, backgrounding, or manual refresh And the audit trail records the membership change and resulting enforcement state
Exclude Frozen Subjects from Digests and Feeds
Given a freeze exists at any applicable scope for Resident R or Unit U When digests are generated on their scheduled cadence Then items featuring Resident R or members of Unit U are excluded from outbound digests and distribution lists And when in-app feeds are rendered, items including frozen subjects are hidden from share surfaces or clearly disabled from outbound sharing And digest generation logs the count of excluded items grouped by blocking scope
Admin Preview and Post-Activation Coverage Summary
Given an admin selects a freeze scope (resident, unit, or community) and a timeframe When the activation preview is requested Then the system lists impacted residents/units and shows estimated counts of affected items per pipeline (feeds, digests, outbound integrations) And activation is blocked if preview computation fails, with a retry pathway and error logged And when the admin confirms activation, a post-activation summary shows scope, start time, optional end time, number of impacted users, and channels covered And both preview and activation events are logged with actor, reason, timestamps, and scope details
Capture-Time Freeze Alerts & Safe Capture Mode
"As a caregiver, I want clear warnings and blocked share options during a hold so that I don’t accidentally post sensitive media while still documenting care."
Description

Present clear, persistent in-app banners and interstitials at capture and upload time indicating an active hold, with disabled share/post actions and contextual guidance on permitted actions. Allow capture to proceed safely (e.g., photos, voice-to-text) while routing outputs to drafts or private storage until the hold is lifted. Provide consistent UX across camera, gallery upload, and voice update flows; support multilingual copy and WCAG AA accessibility. Preserve existing auto-blur behavior for non-consenting faces while ensuring no external sharing pathways are available under a hold.

Acceptance Criteria
Active Hold Notice at Capture and Upload
Given an Incident Freeze hold is active for the selected resident, unit, or community When a user opens Camera, Gallery Upload, or Voice Update Then a high‑visibility banner indicating Hold active is shown persistently with scope name, reason if provided, and hold start time And an interstitial appears on first entry per app session with concise guidance and a primary acknowledge action And the banner remains visible throughout the capture or upload flow and disappears only when the hold is lifted or the user exits the flow And the banner and interstitial render within 500 ms of the view becoming visible on a mid‑tier device And the notices cannot be dismissed in a way that re‑enables sharing
Share/Post Actions Disabled Under Hold
Given a hold is active for the target of the content When the user views or attempts to use any send, share, post, or publish controls Then all sending controls are disabled or hidden and a brief explainer indicates sharing is disabled during hold And OS share sheets and external intents are suppressed And long‑press, swipe, or context‑menu export options are disabled And any attempt to trigger send via deep link or API returns a 423 Locked error and no payload is transmitted And no network requests to family delivery endpoints are made while a hold is active as verified by network logs
Safe Capture to Drafts/Private Storage
Given a hold is active When the user captures a photo or records a voice‑to‑text update Then the media is saved to encrypted private storage with status on_hold And the item appears in Drafts with a Hold badge and is not visible to family recipients And background sync only uploads to private endpoints and generates no family notifications And when the hold is lifted, the item remains in Drafts for manual review and explicit send by staff
Consistent UX Across Camera, Gallery, and Voice
Given a hold is active When the user navigates among Camera, Gallery Upload, and Voice Update flows Then the freeze banner component uses identical copy, iconography, color, and placement per the design system And the interstitial uses the same content and actions across flows And analytics events for hold_notice_viewed and send_blocked use consistent names and properties across flows And UI snapshot tests confirm visual parity within 2 percent pixel difference tolerance
Multilingual Freeze Copy Rendering
Given the app language is set to a supported locale such as English, Spanish, or French When freeze notices and guidance are rendered Then all strings are sourced from localized resources with no mixed language fragments for supported locales And dynamic fields such as scope name and times are localized and formatted per locale And unsupported locales fall back to English gracefully And pseudolocalization tests show no truncation or overflow in common viewports And language changes at runtime update notices within 1 second without app restart
WCAG AA Accessibility for Freeze Notices
Given assistive technologies are in use When the freeze interstitial appears Then keyboard focus moves to the interstitial and is trapped until dismissed And screen readers announce title, scope, reason, and actions with accurate roles and labels And the persistent banner is exposed via a polite live region and is announced on entry And all text meets at least 4.5 to 1 contrast and non‑text UI elements meet at least 3 to 1 contrast And keyboard‑only users can access all actions with visible focus indicators meeting 3 to 1 contrast And state is not conveyed by color alone and touch targets are at least 44 by 44 points And automated accessibility scans report zero AA violations for affected screens
Auto‑Blur Preserved During Hold
Given non‑consenting faces are present in the frame When capturing under an active hold Then auto‑blur is applied using the same detection thresholds and masks as when no hold is active And the blurred variant is stored and the unblurred variant is not accessible via the UI or export And blur toggles cannot be changed to expose faces while a hold is active And tests confirm blur coverage is consistent with baseline performance on the test set
Hold Reason, Timeframe, and Auto-Expiry with Immutable Audit
"As a compliance officer, I want holds to capture reason and timeframe with an immutable audit trail so that we meet legal and policy obligations during incident reviews."
Description

Require a structured reason code, optional free-text notes, and a start/end timeframe when placing a hold. Default to server-sourced timestamps to prevent device clock manipulation. Support indefinite holds and scheduled auto-expiry, with pre-expiry review prompts. Maintain an immutable, exportable audit trail recording reason, timeframe, placements, lifts, modifications, and all user identities involved, with cryptographic chaining for tamper evidence. Provide filtered audit views and CSV/JSON export for compliance reviews.

Acceptance Criteria
Server-Sourced Timestamps Enforcement
Given a device clock is incorrect by over 10 minutes, When a user places a hold, Then the recorded start_time equals server time within ±1 second and ignores the device clock. Given a user sets custom start or end times, When saving the hold, Then the system stores server-evaluated instants in UTC ISO 8601 and displays localized time only in UI. Given server time cannot be reached, When a user attempts to place, modify, or lift a hold, Then the action is blocked with an error "Server time required" and the attempt is logged.
Reason Code Required and Notes Optional
Given hold initiation, When submitting, Then a reason_code from the managed list is required and save is rejected if missing. Given notes are provided, When saving, Then up to 1000 characters are accepted, HTML/script tags are neutralized, and Unicode is preserved. Given the reason code catalog is updated centrally, When a user opens the hold form, Then the latest list is available within 5 minutes and the audit stores both code_id and code_label snapshot.
Indefinite vs Scheduled Holds with Auto-Expiry
Given the user selects Indefinite, When saving, Then no end_time is required and the hold remains active until an explicit lift event occurs. Given the user schedules an end_time T, When server time reaches T, Then the hold auto-expires within 60 seconds, the state becomes Inactive, and an Auto-Expiry audit entry is appended. Given an auto-expired hold, When viewing history, Then start_time, end_time=T, reason_code, and Auto-Expiry actor are visible.
Pre-Expiry Review Prompt and Actions
Given a scheduled hold ends at T and a lead_time of 24h is configured, When server time reaches T-24h, Then an in-app review prompt is sent to assigned roles with options Extend, Lift Now, or Keep Schedule. Given a user chooses Extend from the prompt, When confirmed, Then a new end_time is required, server time is used, and an Extend audit entry with updated timeframe and user identity is appended. Given no action is taken from the prompt, When server time reaches T, Then the hold auto-expires as scheduled and is audited.
Immutable Audit Trail with Cryptographic Chaining
Given any hold event (place, modify, extend, lift, auto-expire), When recorded, Then the system appends an audit entry containing event data, a hash of the previous entry, and its own hash. Given an attempt to edit or delete an audit entry via UI or API, When executed, Then the system rejects the operation and logs a tamper attempt. Given an export is generated, When chain verification is run, Then each entry’s prev_hash matches the predecessor’s hash and the export includes the chain_head and chain_tip hashes.
Identity Capture for All Hold Actions
Given a hold is placed or lifted using DuoTap, When audited, Then both participants’ user_ids, display_names, and authentication timestamps are recorded in the entry. Given a hold is modified or extended, When audited, Then the acting user’s user_id and authentication method are recorded. Given any audit entry is viewed, When displayed, Then it shows all recorded identities and denies redaction or overwrite.
Filtered Audit Views and CSV/JSON Export
Given filters by resident/unit/community, date range, event type, and user, When applied, Then the result set updates within 2 seconds for up to 10,000 entries and returns accurate counts. Given an export request in CSV or JSON for the filtered set (≤50,000 entries), When generated, Then the file downloads within 10 seconds and contains fields: event_type, reason_code, notes, start_time, end_time, status, user_identities, created_at, prev_hash, hash. Given the JSON export, When validated, Then it conforms to schema version 1.0 with timestamps in UTC ISO 8601 and CSV includes a header row with the same fields.
Staff Notification and Escalation Workflow
"As an administrator, I want staff notified and acknowledgements tracked for hold events so that everyone follows the correct protocol without confusion or missed updates."
Description

Deliver targeted notifications to impacted staff and managers when a hold is placed, updated, nearing expiry, or lifted. Support in-app, push, and email channels with deduplication, quiet-hour rules, and read receipts. Provide escalation paths to on-call roles if acknowledgements are not received within defined SLAs. Include a concise summary of scope, reason, and do/don’t guidance with links to policy and the incident record. Do not notify families by default; allow admin-configurable external communications policies where required.

Acceptance Criteria
Notify Impacted Staff on Hold Placement
Given an Incident Freeze hold is confirmed via DuoTap for a resident, unit, or community with reason and timeframe And notification channels (in-app, push, email) are enabled When the hold is placed Then the system identifies impacted staff and managers based on scope, assignment, location, and on-shift status And sends one targeted notification per recipient within 60 seconds via their highest-priority available channel And the notification includes scope, reason, start/end (or expiry) time, concise do/don’t guidance, and links to policy and the incident record And no family/external contacts are notified by default And if an admin-configured external communications policy is active for this incident scope, external messages are sent only per that policy’s recipients, channels, and templates And delivery, content hash, and recipient list are recorded in the audit log
Notify Impacted Staff on Hold Update or Lift
Given an Incident Freeze hold exists When the hold is updated (scope, timeframe, or reason) or lifted via DuoTap Then impacted staff and managers receive a targeted notification within 60 seconds indicating “Updated” or “Lifted” And the message supersedes prior guidance and highlights changes since last notice And any pending or deferred notifications rendered obsolete by the change are canceled And no family/external contacts are notified unless permitted by an active external communications policy And the change, notifier, timestamps, and affected recipients are written to the audit log
Pre‑Expiry Reminders and Expiry Handling
Given a hold has a scheduled expiry time When time remaining reaches 24 hours and 1 hour (configurable) Then impacted staff and managers receive pre‑expiry reminders with renew/extend actions and current guidance And if the hold expires without extension, a “Hold Expired” notification is sent within 60 seconds and guidance reverts to normal capture policy And all reminders, actions taken, and the expiry event are recorded in the audit log
Quiet Hours and Urgency Controls
Given organization quiet hours are configured per role and timezone When a notification is generated during a recipient’s quiet hours and is not marked urgent Then push and email are deferred until quiet hours end, and an in‑app banner appears at next app launch And urgent flagging is restricted to Admin/Compliance roles and requires a reason captured in the notification payload and audit log And deferred sends are released at quiet‑hours end with a “delayed due to quiet hours” marker And all deferrals, releases, and urgency overrides are logged with timestamps
Channel Deduplication and Delivery Reliability
Given multiple channels are enabled and a single event triggers notifications When dispatching messages Then no recipient receives duplicate content for the same event across channels within a 10‑minute dedup window (content hash based) And channel priority follows per‑user preference (in‑app > push > email by default) with automatic fallback upon delivery failure And transient failures are retried up to 3 times with exponential backoff, after which the failure is surfaced in ops monitoring And channel, attempt count, outcome, and dedup decisions are written to the audit log
Read Receipts and Acknowledgement SLA Tracking
Given a notification requires acknowledgement When a recipient opens the in‑app notification Then a read timestamp is captured and the UI requires explicit Acknowledge or Snooze And if not acknowledged within the configured SLA (e.g., 15 minutes on‑shift, 2 hours off‑shift), the item is marked SLA Breached And per‑user and aggregate acknowledgement metrics are visible in an admin dashboard and exportable (CSV) And all reads, acknowledgements, snoozes, and SLA state changes are logged
Escalation to On‑Call Roles on Missed Acknowledgement
Given an on‑call roster with escalation tiers and SLAs is configured When a notification remains unacknowledged past its SLA by the primary recipient group Then the system escalates to Tier 1 on‑call via configured channels (in‑app, push, SMS/email where permitted) And if Tier 1 does not acknowledge within its SLA, escalate to Tier 2, repeating up to N tiers or until acknowledged And escalation messages include incident summary, do/don’t guidance, and links to policy and record And escalation halts immediately upon any valid acknowledgement and records the responder And the full escalation path, timestamps, and outcomes are captured in the audit log
Offline Enforcement and Sync Integrity
"As a caregiver working with unreliable Wi‑Fi, I want the app to enforce holds offline so that we never violate legal holds due to connectivity issues."
Description

Enforce holds even when devices are offline by distributing signed policy snapshots with short TTLs and grace windows. Block all share/post operations locally under an active or recently-expired-but-unvalidated hold and queue permissible actions for later sync. Reconcile conflicts on reconnect using server authority and capture all attempted violations in telemetry and audit logs. Mitigate clock drift and attempted time tampering by relying on monotonic counters and server times for policy decisions.

Acceptance Criteria
Offline Hold Enforcement Within TTL and Grace Window
Given a device holds a valid server‑signed Incident Freeze snapshot for a resident/unit/community with TTL and grace values And the device is offline When a user attempts any share/post operation within the snapshot’s TTL or grace window Then the action is blocked locally and a message indicates "Hold in effect — sharing disabled" And the content is saved as a local draft marked "On Hold" And enforcement persists across app restarts and OS reboots
Block Shares Under Unvalidated Expired Hold
Given the local hold snapshot’s TTL has elapsed And the device has not yet validated with the server (offline or policy endpoint unreachable) When a user attempts to share/post affected content Then the action is blocked locally with a message "Awaiting server validation" And a violation attempt entry is recorded with reason code "EXPIRED_UNVALIDATED_HOLD"
Queue Permissible Actions While Offline Under Hold
Given an Incident Freeze is active for the target scope and the device is offline When a user captures media or notes related to the affected scope Then capture is allowed but distribution is prevented And the items and metadata are queued for later sync without publishing And upon reconnect, the queue is processed according to current server policy (released if lifted, retained if still on hold) And no duplicate uploads occur
Server‑Authoritative Reconciliation on Reconnect
Given the device reconnects after operating offline under a hold When the app initiates an immediate policy refresh Then share/post remains blocked until server policy is fetched and verified And local policy state is aligned to the server‑authoritative snapshot (by snapshot ID/version) And queued items are either released or retained/rejected per the retrieved server policy And a reconciliation audit record is created linking local and server snapshot IDs
Telemetry and Audit of Blocked Attempts
Given an attempted share/post is blocked due to active or unvalidated hold while offline When the block occurs Then the app records a local telemetry event including: userId, deviceId, appVersion, actionType, targetScope, reasonCode, localSnapshotId, signatureHash, lastKnownServerTime, monotonicElapsed And upon reconnect, the event is uploaded to the server and appears in the resident/unit/community audit trail And duplicate events (retries) are deduplicated by client event ID And users cannot delete or alter the local event via in‑app actions
Clock Drift and Time Tampering Resilience
Given the device wall‑clock is adjusted forward or backward while offline When evaluating hold TTL and grace windows Then the app uses last known server time plus monotonic elapsed time to decide enforcement And hold enforcement is not shortened by backward clock changes and not lifted early by forward changes And enforcement continues until server time is revalidated And a tampering suspicion event is recorded if significant drift is detected beyond threshold
Signed Snapshot Verification and Failsafe Enforcement
Given a policy snapshot is present on device When the snapshot signature is invalid, expired, or not signed by a trusted key Then the app treats policy as most restrictive and continues enforcing the hold And it refuses to lift or relax the hold based on the invalid snapshot And it records a security event and prompts for re‑sync with the server
Admin Console and API for Hold Management
"As a community director or IT admin, I want a dashboard and APIs to manage and audit holds so that I can operate at scale and integrate with our incident systems."
Description

Provide an admin dashboard to create, view, search, filter, and bulk-manage holds by scope, status, reason, and timeframe. Include detail pages with full audit history, affected entities, and quick actions (extend, narrow scope, lift via DuoTap). Expose secure RBAC-protected APIs and webhooks for integration with incident management systems, including events for placed, updated, and lifted holds. Support SSO groups for authorization, rate limiting, and export of hold and audit data for external archival.

Acceptance Criteria
Admin Console: Create, Search, Filter, and Bulk-Manage Holds
- Given an authenticated Hold Manager, when opening the Holds list, then they can search by resident name, unit, community, hold ID, creator, reason tag, and timeframe, and results update within 1500 ms p95 for datasets up to 50k holds. - Given applied filters by status (Active, Scheduled, Expired, Lifted), scope (Resident/Unit/Community), reason, and created_at range, when executed, then only matching holds are returned and active filters are visibly indicated. - Given 2–1000 holds selected, when bulk Extend/Narrow Scope/Lift via DuoTap is confirmed, then eligible holds are updated, ineligible holds are skipped with per-hold error, and a summary shows counts succeeded/failed; an audit entry is recorded per hold and for the batch. - Given a new hold is created via UI, when required fields (scope, reason, timeframe) are valid and submitted, then the hold is created with correct status (Active if start<=now else Scheduled) and appears in the list; otherwise inline validation prevents submission.
Hold Detail: Audit Trail and Quick Actions
- Given a Hold Manager views a Hold Detail, then metadata (ID, scope, reason, status, start/end, creator) and the list of affected entities are displayed. - Given the detail view, when Extend or Narrow Scope is used, then a reason note is required, input is validated, and changes apply only if the hold is Active or Scheduled; Expired holds cannot be edited. - Given Lift is initiated, when the DuoTap challenge is approved by two distinct authorized users within 60 seconds, then the hold is lifted and an audit entry is recorded; if approval fails or times out, the hold remains unchanged and a failed attempt is audited. - Given any change, when the audit trail is viewed, then entries display timestamp (UTC), actor, method (UI/API), before/after diffs, and DuoTap verification outcome; entries are immutable and ordered newest-first.
RBAC with SSO Groups for Hold Management
- Given SSO (SAML/OIDC) is configured, when a user signs in, then group claims map to roles (Hold Viewer, Hold Manager, Hold Admin, API Client) per tenant-defined rules. - Given a user's role and community scope, when accessing UI or API resources outside their allowed scope, then a 403 is returned and the attempt is audited with user ID, resource, and timestamp. - Given a Hold Viewer, when attempting to create/update/lift a hold, then the action is blocked; Hold Managers can manage within assigned communities; Hold Admins can manage across all tenant communities. - Given group-to-role mappings are changed, when the user next signs in, then the new permissions take effect without code changes and are enforced consistently across UI and API.
RBAC-Protected APIs and Idempotent Operations
- Given a client with a valid OAuth2 token and scopes (hold.read/hold.write), when calling POST /holds, GET /holds, GET /holds/{id}, PATCH /holds/{id}, POST /holds/bulk, and POST /holds/{id}/lift, then responses match the OpenAPI schema with 2xx on success and appropriate 4xx/5xx on error; unauthorized requests return 401, forbidden return 403. - Given an Idempotency-Key header on POST/PATCH requests, when the same key is retried within 24 hours, then the original operation is not re-applied and the original response is returned with the Idempotency-Key echoed. - Given sustained traffic, when a client exceeds 1000 requests per minute, then the API responds 429 with standard rate limit headers; within limits, p95 latency is <= 500 ms for reads and <= 800 ms for writes under 1k RPS aggregate. - Given any write operation, then an audit record is persisted containing client_id, actor (if present), source IP, request ID, reason note, and before/after snapshots.
Webhooks: Hold Placed, Updated, Lifted
- Given a tenant admin registers a webhook endpoint with a shared secret and selects event types (hold.placed, hold.updated, hold.lifted), when those events occur, then webhooks are delivered signed with HMAC-SHA256 and include a timestamp header for verification. - Given a delivery returns non-2xx, when retries are scheduled, then exponential backoff is used for up to 24 hours; deliveries are at-least-once and include event_id to support idempotent receivers. - Given normal operation, when an event fires, then 95% of webhooks are delivered within 5 seconds; tenants can view recent deliveries with status, last attempt, and can trigger manual retry. - Given event payloads, then they include hold metadata (id, scope, reason tag, status, timestamps, actor) and a change diff; payloads exclude any non-consenting resident media or PII beyond defined fields.
Export Hold and Audit Data for Archival
- Given an authorized Hold Admin, when requesting an export with filters (date range, status, scope) and format (CSV or JSON), then an export job is queued, visible with progress, and only authorized roles can create exports. - Given large datasets up to 1,000,000 audit rows, when the export completes, then files are chunked to <= 250 MB with a manifest; timestamps are UTC ISO8601; CSV uses UTF-8 with RFC4180 escaping; JSON is newline-delimited if chunked. - Given export completion, when downloading, then a signed URL expires in 7 days, files are encrypted at rest, and only the requester and Hold Admins can download; all export requests and downloads are audited. - Given data schema, then exports include holds (id, scope, status, reason, created_by, created_at, start_at, end_at) and audit entries (id, hold_id, actor, action, before, after, method, timestamp).

Proof Seal

Every post carries a verifiable consent snapshot—hash, timestamp, signer, and scope—so auditors can see exactly which authorization was active at capture. Tap through to an exportable, tamper‑evident PDF for external review. This eliminates back‑and‑forth during audits, reduces legal exposure, and reassures families and administrators that updates are consistently authorized.

Requirements

Consent Snapshot Capture & Hashing
"As a caregiver, I want the app to automatically attach a verifiable consent snapshot when I capture a photo or note so that I don’t need extra steps and admins can later prove the update was authorized."
Description

Capture a consent snapshot at the moment of media creation, packaging the active consent doc ID/version, signer identity, resident ID, scope (distribution, media types, purposes), caregiver ID, device ID, and capture context into a canonical JSON object. Compute a SHA-256 hash of this payload and assign a unique Proof Seal ID. Persist the snapshot and hash server-side with transport over TLS 1.2+ and at-rest encryption. Integrate seamlessly into the existing one-tap post flow with <150ms added latency and transparent UX. Expose the Proof Seal ID and short hash in the post header and store a reference on the post record to guarantee later verification and traceability.

Acceptance Criteria
Canonical Consent Snapshot Composition at Media Capture
Given a caregiver initiates media capture for a resident with an active consent record When the capture event occurs Then a canonical JSON snapshot is built with exactly these keys: consentDocId, consentDocVersion, signerId, residentId, scope.distribution, scope.mediaTypes, scope.purposes, caregiverId, deviceId, captureContext.timestampUtc, captureContext.location, captureContext.mediaType, captureContext.appVersion And each required field is present, non-null, and validated against the schema; arrays in scope contain at least 1 item And captureContext.timestampUtc is the moment of media creation in ISO 8601 UTC with millisecond precision And the JSON is canonicalized (UTF-8, sorted keys, trimmed strings, normalized numbers) prior to hashing And if no active consent exists for the resident, post creation is blocked and an error message "Active consent required" is shown
Deterministic SHA-256 Hashing and Proof Seal ID Assignment
Given the canonical JSON snapshot payload When a SHA-256 digest is computed over its UTF-8 bytes Then the hex digest is exactly 64 lowercase characters And recomputing the digest server-side yields the identical value When a Proof Seal ID is generated Then it is globally unique (UUID v7 or equivalent monotonic unique ID) and associated to the snapshot And the short hash displayed equals the first 10 characters of the hex digest
Server Persistence and Post Traceability Linkage
Given a post submission with a snapshot, hash, and Proof Seal ID When the client submits the post Then the snapshot and hash are transmitted to the server and persisted atomically And the post record stores the Proof Seal ID as a foreign-key reference And querying the post by postId returns the associated Proof Seal ID And querying by Proof Seal ID returns the exact stored snapshot and hash And referential integrity is enforced (a post cannot reference a non-existent Proof Seal ID)
Exposure of Proof Seal ID and Short Hash in Post Header
Given a post with a stored Proof Seal ID and hash When the post is rendered in the app Then the header displays the Proof Seal ID and the short hash And the values are copyable to clipboard with a single tap And truncation uses middle-ellipsis without altering the underlying value And accessibility labels announce "Proof Seal ID" and "Short Hash"
Performance: <150ms Added Latency at p95
Given the one-tap post flow on mid-tier devices under typical 4G/Wi‑Fi conditions When snapshot composition and hashing are executed client-side Then the added client-side latency attributable to the Proof Seal step is ≤ 150 ms at p95 and ≤ 250 ms at p99 across 1,000 sampled posts And no additional taps, modals, or blocking UI are introduced by the Proof Seal step
Secure Transport and At-Rest Encryption
Given any transmission of the snapshot and hash to the server When the connection is negotiated Then TLS version is ≥ 1.2 with strong cipher suites; attempts below 1.2 are rejected And the snapshot and hash are stored encrypted at rest using KMS-managed AES-256 or equivalent And snapshot contents and hashes are not logged in plaintext in client or server logs
Verification: Recompute Hash Matches Stored Snapshot
Given a stored Proof Seal ID When the snapshot is retrieved from the server and hashed using the same canonicalization and SHA-256 process Then the recomputed digest exactly matches the stored hash And any byte-level modification to the stored snapshot results in a different digest, failing verification And the verification result is available via an internal admin tool or API endpoint returning pass/fail and mismatch details
Trusted Timestamping
"As a compliance officer, I want each post’s consent to include a verifiable timestamp so that auditors can confirm exactly when authorization was in effect at capture."
Description

Apply an authoritative, tamper-resistant timestamp to each Proof Seal using a server-controlled time source with NTP synchronization and drift monitoring. Optionally obtain an RFC 3161-compliant TSA token when connectivity permits; otherwise record a server-signed timestamp and reconcile TSA tokens asynchronously. Embed timezone and UTC offset, and store evidence of time source health. Surface drift alerts to ops if variance exceeds a configurable threshold (e.g., >2s). The timestamp becomes part of the signed payload and is immutable after sealing.

Acceptance Criteria
Server-NTP Trusted Timestamp on Seal Creation
Given the server time service is synchronized via NTP and reporting healthy When a caregiver submits a post and a Proof Seal is created Then the server applies an authoritative timestamp sourced from the server clock, not the device clock And the timestamp is recorded in RFC 3339 format and includes both the IANA timezone ID and the UTC offset And the timestamp is embedded in the Proof Seal’s signed payload And the seal creation API response includes the timestamp fields exactly as stored
RFC 3161 TSA Token Acquisition with Fallback and Reconciliation
Given the TSA endpoint is reachable within 3 seconds When a Proof Seal is created Then the server requests an RFC 3161-compliant Time-Stamp Token (TST) for the seal’s content hash and validates the TSA signature and certificate chain And the message imprint in the TST matches the seal’s content hash And the TST reference and verification status are attached to the seal without delaying the API response beyond the configured timeout Given the TSA endpoint is not reachable or times out When a Proof Seal is created Then the server stores a server-signed timestamp and enqueues an asynchronous TSA request with exponential backoff and idempotent retries for up to 24 hours And upon later success, the TST is linked to the original seal without mutating the signed payload; the reconciliation status updates to "TSA:Verified"
Drift Monitoring and Ops Alerting
Given continuous NTP offset measurements are recorded by the server When the absolute drift at seal time exceeds the configured threshold (default 2000 ms) Then the system flags the seal with a "time_source_degraded" indicator and records the measured offset in milliseconds And an alert is sent to Operations within 60 seconds containing current offset, stratum, primary peers, and host identifier And when the measured drift remains below threshold for 5 consecutive minutes, the alert is auto-resolved and the resolution is logged And the drift threshold is configurable and changes take effect without service restart
Time Source Health Evidence Persistence and Audit Export
Given a Proof Seal is created Then a snapshot of time source health is persisted with the seal, including last_ntp_sync_at, peers, stratum, offset_ms, jitter_ms, sync_state, and configured_drift_threshold_ms And the exportable tamper-evident PDF includes: timestamp, timezone, UTC offset, signer, scope, seal hash, TSA status (and TST if present), and the time source health snapshot And the PDF is cryptographically signed so that external verification of its signature and content digest succeeds And if the seal was created under degraded time conditions, the PDF clearly marks "Time source degraded at seal time"
Timestamp Immutability and Audit on Modification Attempts
Given a Proof Seal exists When any actor attempts to modify the timestamp or any field within the signed payload via API, UI, or direct data access Then the operation is rejected (HTTP 409 or equivalent) and no mutation occurs And an immutable audit log entry is recorded with actor identity, timestamp of attempt, request metadata, and reason "immutable_seal" And storage-layer protections (e.g., append-only records or cryptographic write-ahead log) prevent direct mutation of the persisted seal And all read endpoints return the original timestamp unchanged
Delayed Upload Uses Server Time at Sealing
Given a post is captured on a device offline at T1 and uploaded at T2 When the server creates the Proof Seal upon receipt at T2 Then the seal timestamp equals the server’s trusted time at T2, not the device-reported time And the timezone and UTC offset reflect the server configuration at T2 And ordering in audit views and digests uses the seal timestamp consistently And the original device-capture time is stored separately as device_time (not part of the signed payload) for user context
Signer Identity Verification & Scope Mapping
"As an administrator, I want the Proof Seal to reflect the correct signer and consent scope so that only authorized updates are shared and we stay compliant with resident preferences."
Description

Validate and bind the signer’s identity to the resident’s active consent record prior to sealing. Enforce scope rules (media type allowed, distribution channels, purposes, expiration, and facility-specific restrictions). Support multiple signers with precedence and quorum rules (e.g., any-of, all-of). Block sealing when consent is expired or out-of-scope and present actionable guidance to caregivers. Provide APIs and admin UI to manage signers, scope templates, and consent document versions, ensuring the correct authorization is always applied at capture.

Acceptance Criteria
Sealing succeeds with verified signer and in-scope consent
Given a caregiver starts sealing a photo update for Resident R and the selected channel is Family App and purpose is Care Update And Resident R has an active consent (version v3) whose scope permits media: photo, channels: Family App, purposes: Care Update, facility restriction: Wing A only, and expiration is in the future And the capture location is Wing A and signer S has verified identity via 2FA within the last 10 minutes and matches the consent’s signer When the caregiver taps Seal Then the system binds the seal to Resident R’s consent v3 with signer S, stores verification method and timestamp, and generates a proof snapshot including consent ID, signer ID, scope (media/channel/purpose/facility), and expiry And the post is sealed and queued for delivery to Family App And an audit log entry records user, resident, consent version, scope applied, and outcome = success
Sealing is blocked for expired or out-of-scope consent with actionable guidance
Case: Expired consent Given a video update is ready and Resident R’s consent expired 2 hours ago When the caregiver taps Seal Then sealing is blocked, no post is created, and an error banner states "Consent expired at {timestamp}" And the UI shows actions: Request new consent, Save as draft, Delete media Case: Channel not permitted Given an image update targets channel Public Newsletter but Resident R’s consent scope allows only Family App When the caregiver taps Seal Then sealing is blocked and the UI highlights the failing rule "Channel not permitted" And the UI offers Change channel to Family App and View consent details And an audit log entry records outcome = blocked and reason_code = CHANNEL_OUT_OF_SCOPE
Quorum and precedence rules across multiple signers
Case: Any-of quorum Given a consent requires any-of with signers S1 and S2 and S1 has verified identity and S1’s scope allows media: photo When sealing a photo update Then sealing proceeds without S2 and the proof records quorum = any-of and approver = S1 Case: All-of quorum unmet Given a consent requires all-of with signers S1 and S2 and only S1 has verified identity When sealing an update Then sealing is blocked with guidance "Second signer required (S2)" and no seal is created Case: All-of scope intersection Given quorum is all-of and S1 disallows media: video while S2 allows video When sealing a video update Then sealing is blocked because the intersection denies video and the UI cites "Media type not permitted by all signers" Case: Precedence between active consents Given two active consents exist with precedence order Facility Guardian > Family Proxy, where Family Proxy allows channel Social Share and Facility Guardian restricts to Family App only When attempting to seal to channel Social Share Then the higher-precedence consent (Facility Guardian) governs and sealing is blocked with reason "Precedence restriction"
Scope templates and consent document versioning applied at capture
Given an admin publishes scope template T2 (version 2) and associates it to Resident R effective 2025-08-29 00:00 local And Resident R currently has active consent v1 from template T1 When a seal is attempted on 2025-08-28 15:00 local Then the system applies consent v1 When a seal is attempted on 2025-08-29 09:00 local Then the system applies consent v2 and the proof snapshot stores template_id = T2 and version = 2 And the version history for Resident R shows v1 end-dated at 2025-08-29 00:00 and v2 start-dated at 2025-08-29 00:00 with no overlaps or mutations to prior records
Admin APIs for signers, scope templates, and consents
Given a client with role = Compliance and a valid OAuth2 token When POST /consents with a valid payload Then response is 201 with consent_id, version = 1, and audit_id When POST /consents with the same Idempotency-Key Then response is 200 and no duplicate record is created When PATCH /consents/{id} to publish a new version Then version increments and the previous version is end-dated and remains immutable When a non-privileged client calls any consent management endpoint Then response is 403 and no changes occur When request rate exceeds 100 requests/min per API key Then responses are 429 with Retry-After header And all create/update/delete operations produce audit logs including who, when, what, before/after, and reason
Admin UI for managing signers, precedence, and expiring consents
Given an admin opens Resident R → Consents in the admin UI When adding a signer, setting quorum = all-of, and precedence = Facility Guardian Then the UI reflects the configuration and a preview shows the effective scope intersection When a consent is within 14 days of expiration Then the UI badges it as "Expiring" and offers Send renewal link When searching signers by name, relationship, or status Then results return within 300 ms at the 95th percentile When bulk-assigning scope template T2 to 50 residents Then 50 assignments are created and a summary shows successes/failures with retriable actions Rule: Only Admin or Compliance roles can edit; others can view only; edit attempts by unauthorized roles show "Insufficient permissions" and are logged
Post-to-Consent Linkage & Immutability
"As an auditor, I want each post to be immutably linked to the consent active at capture so that I can verify integrity and detect any post-capture alterations."
Description

Require every post to reference a single immutable Proof Seal ID before it can be published. Store seals and linkage in an append-only ledger with versioned updates; edits to a post create a new version referencing the original seal or a new seal if new media is captured. Prevent deletion or alteration of sealed data; instead, permit redactions via additive records with reason codes. Provide a verification endpoint that recalculates the hash from stored payloads to confirm integrity and surfaces discrepancies for investigation.

Acceptance Criteria
Block Publish Without Valid Proof Seal
- Given a user attempts to publish a post without a Proof Seal ID, When they submit, Then the API responds 422 Unprocessable Entity with error code "proof_seal_required" and the post is not created. - Given a Proof Seal ID that does not exist or is not active, When publishing, Then the API responds 422 with error code "proof_seal_invalid" and the post is not created. - Given a publish request includes more than one Proof Seal ID, When submitting, Then the API responds 422 with error code "multiple_seals_not_allowed" and the post is not created. - Given a valid Proof Seal ID whose scope covers the post’s media and resident, When publishing, Then the API responds 201 Created and the post version references exactly that Proof Seal ID.
Append-Only Ledger Write on Publish and Edit
- Given a successful post publish, When the transaction commits, Then a ledger entry is appended capturing postId, versionId, proofSealId, contentHash, timestamp (UTC), actorId, and action="publish". - Given a post edit or redaction, When saved, Then a new ledger entry is appended with a monotonically increasing sequenceNumber and previousEntryId; existing entries remain unchanged. - Given any attempt to update or delete an existing ledger entry via public APIs, When executed, Then the API responds 405 Method Not Allowed (or 409 Conflict) and the ledger length remains unchanged. - Given the ledger, When queried for a post, Then entries are returned strictly ordered by sequenceNumber with no gaps and with verifiable linkage via previousEntryId.
Post Edit Versioning Rules
- Given an edit that changes only text/metadata without adding new media, When saving, Then a new post version is created with versionNumber incremented by 1 and the same proofSealId as the prior version. - Given an edit that adds or replaces media, When saving without providing a new Proof Seal ID, Then the API responds 422 with error code "new_seal_required_for_new_media" and no new version is created. - Given an edit that adds or replaces media with a valid new Proof Seal ID, When saving, Then a new post version is created referencing that new Proof Seal ID and the version chain preserves references to all prior versions. - Given a post with N versions, When fetching version history, Then N immutable version records are returned with their respective proofSealId values, contentHash, and timestamps.
Redaction via Additive Records with Reason Codes
- Given an authorized role initiates a redaction, When submitting with reasonCode in {"PHI","PII","NonConsentingThirdParty","Safety","Other"} and details, Then a new additive redaction record is appended to the ledger and no prior record is altered. - Given a redaction exists for a post field or media, When the post is rendered, Then the redacted element is omitted or masked and a redaction indicator with reasonCode is displayed; original sealed data remains retrievable in audit views only. - Given an unauthorized role attempts a redaction, When submitting, Then the API responds 403 Forbidden and no ledger entry is added. - Given a redaction record, When exporting audit data, Then the redaction appears as a separate ledger entry with timestamp, actorId, reasonCode, and affected fields/media identifiers.
Verification Endpoint Hash Recalculation and Discrepancy Surfacing
- Given a post versionId, When calling GET /verification/post/{versionId}, Then the service recalculates the content hash from stored payloads and returns 200 with {verified:true, calculatedHash, storedHash, proofSealId, checkedAt} when hashes match. - Given the recalculated hash does not match the stored hash, When calling the endpoint, Then it returns 200 with {verified:false, calculatedHash, storedHash, proofSealId, discrepancy:"integrity_mismatch"} and logs an event; the post version is flagged status="investigate". - Given an invalid or unauthorized request, When calling the endpoint, Then the service returns 401 or 403 and performs no verification. - Given a caller exceeds 60 requests per minute per API key, When calling the endpoint, Then the service returns 429 Too Many Requests.
Immutable Proof Seal Properties and Single-Reference per Version
- Given an existing Proof Seal, When an update is attempted to its hash, timestamp, signerId, or scope, Then the API responds 409 Conflict with error code "seal_immutable" and no change occurs; creating a new seal is required for changes. - Given a post version, When inspecting its data model, Then it contains exactly one non-null proofSealId with a foreign-key constraint to the seals table and a unique index (postVersionId) ensuring single-reference. - Given a request attempts to set or change proofSealId on an existing post version, When executed, Then the API responds 409 Conflict with error code "version_immutable_seal_ref" and no change occurs.
Tamper‑Evident PDF Export with QR Verification
"As an external auditor, I want a signed PDF with a scannable code so that I can independently validate the consent details without needing access to the internal system."
Description

Generate an exportable, tamper-evident PDF containing the consent snapshot (signer, scope, doc/version), post metadata, SHA-256 hash, and trusted timestamp. Digitally sign the PDF (e.g., ECDSA P-256) and embed a QR code/URL that points to a verification endpoint returning the snapshot and signature for independent validation. Include a visual seal, checksum, and watermark to discourage alteration. Support batch export by date range/resident and store export events in an access log for auditability.

Acceptance Criteria
Single Post PDF Includes Consent Snapshot
Given a post with an active consent When a user exports the Proof Seal PDF for that post Then the PDF includes the consent snapshot fields: signer, scope, and consent document name/version exactly as recorded at capture And Then the consent snapshot values in the PDF match the system-of-record for that post at the capture timestamp And Then the PDF opens without errors in standards-compliant PDF readers
Post Metadata, SHA-256, and Trusted Timestamp Embedded
Given a post with media and/or text When the Proof Seal PDF is exported Then the PDF includes post metadata: post ID, resident ID, author ID, and created-at timestamp (UTC) And Then the PDF includes a SHA-256 checksum of the post payload captured for the Proof Seal And Then the PDF embeds a trusted timestamp token bound to the checksum, verifiable to a trusted time source
ECDSA P-256 Digital Signature and Tamper Detection
Given an exported Proof Seal PDF When validating its embedded digital signature with the KinLoop public certificate Then the signature algorithm is ECDSA P-256 with SHA-256 and validation passes And When any byte of the PDF is modified after export Then signature validation fails in standards-compliant PDF validators And Then the PDF contains sufficient certificate chain data to validate trust to the configured root
QR Code/URL Verification Endpoint Returns Verifiable Payload
Given an exported Proof Seal PDF When the embedded QR code is scanned or the URL is visited Then the verification endpoint responds with HTTP 200 and JSON including: consent snapshot (signer, scope, doc/version), relevant post metadata identifiers, SHA-256 checksum, digital signature reference, and trusted timestamp And Then the response includes cryptographic material or references enabling independent verification using KinLoop public keys And When the URL is malformed or the record is not found Then the endpoint returns HTTP 4xx without exposing resident PII
Visual Seal, Checksum, and Watermark Present
Given an exported Proof Seal PDF When opened in a PDF viewer Then a visible Proof Seal badge is present on the first page including a short checksum (e.g., first 8 hex of SHA-256) and the trusted timestamp (UTC) And Then a non-obstructive watermark indicating tamper-evidence and verification via QR appears on all pages And Then these visual elements are preserved when printing the PDF
Batch Export by Date Range and Resident
Given an administrator selects a resident and a date range When batch export is triggered Then the system generates tamper-evident PDFs for all posts in the range for that resident in a single operation And Then the number of PDFs generated equals the number of posts matching the filters And Then each generated PDF meets the single-post Proof Seal criteria And When no posts match the filters Then the system informs the user that no records were found and does not produce a package
Access Log Records Export Events
Given a single or batch export is attempted When the operation completes (success or failure) Then an access log entry is written containing: actor identity, action type (single/batch), resident identifier(s), selected date range (if any), timestamp, outcome (success/fail), and count of PDFs generated And Then access log entries are immutable and viewable by authorized administrators for audit And Then the log entry can be correlated to the exported artifacts via post IDs or checksums
Auditor View & Access Control
"As an administrator, I want a secure auditor view with bulk export so that I can respond to audit requests quickly without exposing unnecessary resident data."
Description

Provide role-based access (admin/auditor) to view Proof Seal details from any post, including signer, scope, timestamp evidence, and hash verification results. Enable filters and bulk export across residents and time ranges. Log all access and exports with user, time, and scope for compliance. Integrate with existing admin web console and SSO, honoring least-privilege and PII minimization (e.g., mask non-essential identifiers). Offer a guided audit mode that assembles the required documents and seals for common audit requests.

Acceptance Criteria
Role-Based Access Control for Proof Seal
- Given an authenticated Admin, When opening any post, Then the Proof Seal panel and "View Seal Details" control are visible and accessible. - Given an authenticated Auditor, When opening any post within their assigned facility scope, Then the Proof Seal panel is visible and the post remains read-only (no edit/delete controls). - Given a user without Admin or Auditor role, When attempting to access Proof Seal via UI or direct URL, Then the system returns 403 and no seal data is leaked. - Given an Auditor scoped to Facility A, When accessing a post from Facility B, Then access to the Proof Seal is denied with 403 and an audit log is recorded. - Given multi-tenant data, When an Admin with tenant-level scope accesses a post, Then only tenant-contained data is shown and cross-tenant data is never exposed.
SSO Integration and Least-Privilege Enforcement
- Given SSO is enabled, When a user signs in with a valid SSO token lacking the auditor/admin role claim, Then Proof Seal features are not visible and related API endpoints return 403. - Given SSO is enabled, When a user signs in with the auditor role claim, Then the system maps the claim to the Auditor role and grants read-only Proof Seal access. - Given an Auditor session idle for the configured timeout, When initiating an export, Then the system requires step-up reauthentication before proceeding. - Given an Auditor, When attempting to modify or delete any post or consent, Then the system blocks the action and records the attempt in the audit log. - Given an Admin, When updating SSO role mappings, Then changes take effect on next login without manual user provisioning and are reflected in access rights.
Proof Seal Detail View and Hash Verification
- Given a post with a valid Proof Seal, When viewing details, Then the following fields are present: signer full name and role, consent scope description, capture timestamp (ISO 8601 with timezone), seal creation timestamp, hash algorithm and value, and verification result (Pass). - Given a post where underlying media has been altered post-capture, When verifying, Then hash recomputation mismatches and verification result shows Fail with a clear warning banner. - Given a post with multiple consent updates over time, When viewing the seal, Then the seal reflects the authorization in effect at the capture timestamp, not later updates. - Given clock skew tolerance of ±5 minutes, When verifying timestamps, Then out-of-window discrepancies are flagged with a warning indicator. - Given the details view, When the user selects "Export Seal PDF", Then a tamper-evident PDF is generated containing all fields above and a digital signature. - Given an Auditor without export permission, When attempting to export, Then the system denies the action with 403 and logs the attempt.
Cross-Resident and Date Range Filtering
- Given the Audit view, When filtering by residents A and B and date range 2025-01-01 to 2025-03-31, Then only posts for A and B within that range are returned. - Given no filters applied, When loading the Audit view, Then no resident PII beyond initials is displayed until a facility scope is selected. - Given a dataset of 20,000 posts, When applying any combination of supported filters, Then the first page (50–200 items) loads within 3 seconds at the 95th percentile. - Given filters applied, When drilling into a post and returning, Then the selected filters and pagination state persist. - Given sorting by timestamp asc/desc, When toggled, Then result order updates correctly and consistently across pages.
Access and Export Audit Logging with PII Minimization
- Given any view of Proof Seal details by Admin/Auditor, When the panel is opened, Then an immutable audit log entry is written within 5 seconds containing user ID, role, action type (view), resident scope, post ID, timestamp (ISO 8601), IP, and user agent. - Given any export (single PDF or bulk), When initiated and when completed, Then audit log entries include export ID, filter scope, record count, file size, and outcome (success/failure with error message if failed). - Given a retention policy of 7 years, When querying logs, Then entries older than the policy are unavailable to non-compliance roles and purged according to policy. - Given the Auditor role, When viewing resident info, Then non-essential identifiers are masked: resident last name reduced to initial, DOB hidden, internal IDs truncated to last 4, and contact info omitted. - Given auditor exports (PDF/CSV), When generated, Then masked fields remain masked; unmasking requires Admin action and is logged with user, time, and reason.
Bulk Export Packaging and Delivery
- Given selected filters producing up to 10,000 posts, When initiating a bulk export, Then the system creates a package containing: CSV metadata, individual tamper-evident seal PDFs, and a manifest with SHA-256 checksums for each file. - Given a bulk export in progress, When the user navigates away or logs out, Then the export continues server-side and completion is notified via in-app alert and email with a single-use download link that expires in 7 days. - Given network interruption during download, When resumed within link validity, Then the download supports range requests and verifies integrity against the manifest. - Given a package size greater than 2 GB, When generating, Then the system segments output into multiple archives (<=2 GB each) with an index file that lists segment order. - Given rate limits of 1 concurrent export per user and 5 per tenant, When limits are exceeded, Then the system queues the request and displays an estimated start time.
Guided Audit Mode Assembly
- Given the Guided Audit wizard, When selecting a predefined template (e.g., Consent Verification for Resident X, Q1 2025), Then the system pre-selects required documents and seals and displays a checklist of required items. - Given missing required seals or verification failures, When validating, Then the wizard flags gaps with remediation steps and prevents finalization until resolved or explicitly acknowledged by an Admin with a reason. - Given completing the wizard, When generating the package, Then the output includes: cover letter summarizing scope, checklist with statuses, index CSV, and all referenced seal PDFs, with masked PII per auditor role. - Given an Auditor, When running Guided Audit mode, Then all actions are read-only; attempts to edit content are blocked and logged. - Given standard audit templates, When updated by an Admin, Then changes are versioned and reflected for future runs while existing exports retain the original template version used.
Revocation & Scope Change Handling
"As a privacy officer, I want revocations and scope changes reflected without altering past seals so that we maintain truthful records and prevent future out-of-scope sharing."
Description

Preserve historical integrity by locking each post to the consent snapshot that was active at capture while clearly indicating any subsequent revocations or scope changes. Display visual flags on affected posts, prevent further distribution if newly out-of-scope, and generate admin notifications. Provide reports summarizing posts captured near consent changes and tools to annotate remediation actions. Do not mutate past seals; record revocations as new append-only events linked to the original seal.

Acceptance Criteria
Lock Post to Capture-Time Consent Snapshot
Given a post P was captured at time t1 under consent snapshot S1 (hash, timestamp, signer, scope) When any consent revocation or scope change occurs at time t2 > t1 for the same resident Then P displays S1 unchanged in all views and exports, and the stored S1 hash equals the original hash And P shows a non-dismissable "Authorization updated" badge with the effective timestamp t2 And the Proof Seal PDF includes the original S1 and an appended event entry referencing the revocation/scope change
Visual Flagging After Revocation or Scope Change
Given a post P is affected by a consent revocation or scope change event E at time t2 When P is rendered in feed cards, post detail, and bulk export lists Then a visible flag is shown indicating either "Out of scope since <t2>" or "Scope changed <t2>" And the flag is keyboard-focusable with accessible name and tooltip text And the flag renders consistently in light/dark modes and on iOS, Android, and Web
Block Out-of-Scope Distribution Paths
Given a consent change makes post P out-of-scope at time t2 When any user or job attempts actions: include in digest, share, download, external API export, or webhook dispatch after t2 Then the system prevents the action, returning error code CONSENT_OUT_OF_SCOPE (HTTP 403 for APIs) and a user-facing message And scheduled/saved distributions that include P are automatically canceled and logged with reason CONSENT_OUT_OF_SCOPE And P is excluded from all digests generated after t2
Administrator Notifications on Consent Changes
Given a revocation or scope change event E is recorded for a resident When E is committed Then facility administrators receive an in-app notification within 5 seconds and an email within 2 minutes And the notification includes resident identifier, event type, effective timestamp, count of affected posts, and a deep link to the impact report filtered to E And duplicate notifications for the same admin and event are de-duplicated
Change-Window Impact Report
Given an admin opens the Consent Change Impact report for event E at time t2 When the default window is applied Then the report lists all posts for the resident captured within t2±60 minutes (configurable) And the report supports filters (resident, caregiver, post type), and exports to CSV/PDF with the same rows and columns And the report returns within 3 seconds for up to 5,000 posts and shows total counts of in-scope vs out-of-scope since E
Append-Only Revocation Events and Seal Immutability
Given an existing Proof Seal S1 on post P When a revocation or scope change occurs Then a new append-only event is created and linked to S1 with type, timestamp, signer, and scope delta And any attempt to update or delete S1 is rejected with 409 Conflict and recorded in the audit log with actor and timestamp And the Proof Seal PDF presents a timeline showing S1 followed by the linked event(s) without altering S1
Remediation Annotation Tool
Given an admin views an affected post P or the impact report for event E When they add a remediation annotation Then they must select an action type from a predefined set and may add free-text notes up to 500 characters And saving creates an append-only annotation with timestamp, actor, and action type, visible on post detail, in the impact report, and in the Proof Seal PDF And annotations are immutable (no edit/delete) and are included in CSV/PDF exports

Delta Highlights

Auto-calls out what changed since the last period—new vitals tags, mood or activity shifts, incident notes, and family acknowledgments—right at the top of each card. Color-coded arrows and “New Since Last Shift” badges reduce scan time so Shift Relay Leads can brief faster with fewer misses.

Requirements

Unified Delta Detection Engine
"As a Shift Relay Lead, I want the system to automatically identify what changed since the last shift so that I can brief quickly without scanning full timelines."
Description

Compute per-resident deltas across vitals tags, mood/activity changes, incident notes, and family acknowledgments relative to the last defined period. Ingests structured data from photo posts and voice-to-text notes, supports late/backdated entries, and re-computes deltas on new events or configuration changes. Anchors comparisons to a stored baseline snapshot for each resident and period, with a fallback to the last 24 hours if no baseline exists. Provides idempotent APIs for the mobile app to fetch current deltas, includes reason codes for each highlight (what changed and why), and handles multi-tenant facilities with distinct shift schedules. Meets performance targets of under 200 ms per resident (p95) for delta generation, with retries and eventual consistency guarantees. Emits metrics and logs for observability and auditability.

Acceptance Criteria
Per-Resident Delta Computation with Reason Codes
Given a resident has a stored baseline snapshot for the current period and events across vitals, mood, activities, incidents, and family acknowledgments occur after the baseline, When the engine generates the delta, Then it includes only changed items per domain with old and new values and a non-empty reasonCode for each change. Given no changes occurred since the baseline, When the engine generates the delta, Then the API returns 200 and the changes array is empty. Given duplicate or semantically equivalent events are ingested for the same field/value, When deltas are computed, Then the engine de-duplicates and includes a single consolidated change. Given structured tags embedded in a photo post or voice-to-text note, When the event is ingested, Then the extracted fields appear in the delta with correct data types and source metadata.
Baseline Anchoring and 24-Hour Fallback
Given a valid baseline snapshot exists for the resident and period boundaries, When a delta is requested, Then comparisons are anchored to that baseline's values and timestamps. Given no baseline snapshot exists for the resident and period, When a delta is requested, Then the engine uses the last 24 hours from request time as the comparison window and persists a new baseline for the period. Given a baseline is created for a period, When subsequent delta requests for the same resident and period are made without configuration changes, Then the same baseline is reused until the period ends.
Late/Backdated Event Handling and Recompute
Given an event with an eventTime inside a prior or current period is ingested after initial delta generation, When processing completes, Then the system recomputes the affected resident's delta for that period and exposes the updated result within the eventual consistency window. Given multiple late events arrive out of order, When recomputation occurs, Then delta results are ordered by eventTime and contain no duplicates. Given a late correction or deletion is applied to a prior event, When recomputation occurs, Then the delta reflects the corrected state and includes a reasonCode indicating correction or deletion.
Idempotent Delta Fetch API
Given the same residentId and periodId with no intervening changes, When the client repeats a GET request for current deltas, Then the response body is identical and no additional side effects or audit entries are produced. Given the client retries the same request due to a timeout, When the server receives duplicate requests within 60 seconds, Then it returns 200 with the same stable delta identifier and cache validators. Given a conditional request is made using cache validators, When the delta has not changed, Then the API responds 304 Not Modified within the latency SLO.
Multi-Tenant Shift Schedules and Isolation
Given two facilities with distinct time zones and shift schedules, When deltas are computed for residents in each facility, Then period boundaries respect each facility's configuration and no data crosses tenant boundaries. Given an authenticated user from Facility A, When they request deltas for a resident in Facility B, Then the API returns 403/404 with no indication of the other tenant's data. Given a facility updates its shift configuration effective at a future timestamp, When the effective time begins, Then deltas for new periods use the new schedule without altering historical baselines before the change.
Performance, Retries, and Eventual Consistency
Given a representative load of residents and events, When generating per-resident deltas, Then p95 latency per resident is under 200 ms measured over a rolling 10-minute window. Given a transient processing or datastore error occurs, When generating deltas, Then the system retries up to 3 times with exponential backoff and either completes successfully or surfaces a retriable error without data loss. Given a new event is ingested, When requesting the resident's delta, Then the change is visible to clients within 60 seconds (p95) and no later than 5 minutes (max) under normal operations.
Observability and Auditability
Given delta generation or serving occurs, When processing completes, Then structured metrics are emitted for counts per domain, compute latency, retry counts, and success/failure labeled by tenant and status code. Given a delta response is served, When logs are written, Then entries include tenantId, residentId (tokenized or hashed), periodId, baseline reference, correlationId, and reasonCodes for changes with no PII. Given an auditor requests a trace for a resident and period, When retrieving the audit trail, Then the system can produce a chronological record of baseline snapshots, events consumed, deltas generated, and API responses.
Configurable Period Windows & Baselines
"As an administrator, I want to define when a period starts and ends so that Delta Highlights reflect our actual shift handoffs."
Description

Allow administrators to define the "last period" via configurable shift templates (start/end times, overlaps, and grace windows), including holiday overrides and timezone handling. Persist a baseline snapshot at shift start or end (configurable) for each resident, and use it to anchor delta calculations. Support retroactive period corrections and backfills if shifts were missed or edited. Provide a settings UI and secure APIs, with audited changes and versioned configurations. Default to safe presets for facilities that do not configure shifts. Ensure all downstream delta computations reflow when period definitions or baselines change.

Acceptance Criteria
Shift templates: overlaps, grace windows, timezone and DST
Given a facility timezone is configured and DST transitions occur When an admin defines shift templates with start and end times, optional overlaps, and grace windows Then each template validates with duration > 0 and non-equal start/end times And overlapping templates require explicit priority and grace values And generated period instances over a 30-day horizon align to local time across DST with no unintended gaps after grace Given a shift spans midnight When period windows are generated Then instances correctly roll over days without double-counting or omission Given no templates exist for a facility When Delta Highlights requires a period definition Then the system defaults to a single 24-hour period 00:00–24:00 local time with a 15-minute grace and baseline at shift end
Holiday overrides precedence and application
Given base shift templates exist and a holiday override is defined for a date or range When the current date falls within the override Then the override’s periods replace the base template for period determination Given multiple overrides overlap When saved Then the system requires a numeric priority and only the highest-priority override applies at runtime deterministically Given an override expires When the date is outside the override range Then the system reverts to the base template without manual action
Baseline snapshot timing and content
Given facility baseline mode is set to "start of shift" When a shift starts Then a baseline snapshot is persisted for each resident with timestamp, configuration version, and fields for vitals tags, mood, activity, incident notes, and family acknowledgments And the snapshot content is immutable and addressable by ID Given facility baseline mode is set to "end of shift" When a shift ends Then a baseline snapshot is persisted accordingly Given a resident has no new data at baseline time When the snapshot is created Then the snapshot records empty values and still anchors subsequent delta calculations
Retroactive period corrections and backfills
Given an admin edits a past shift’s start/end times or creates a missed shift backfill When the change is saved Then affected period windows are recalculated and stored And impacted residents’ delta computations are reflowed within 60 seconds And each affected card displays an "Updated" indicator until next open And an audit record is created with actor, timestamp, before/after values, scope, and configuration version
Settings UI permissions, validation, and versioning
Given a non-admin user When they attempt to access Shift Settings Then access is denied with HTTP 403 and no settings are exposed Given an admin user When they create or edit templates, overrides, grace windows, or timezone Then client and server validation block invalid ranges, overlaps without priority, and missing required fields And on save a new configuration version is created with incremented version number, author, changelog note, and effective-from timestamp And the previous version remains read-only and visible in a version history view
Secure APIs for configurations and baselines
Given an authenticated admin with facility-scoped permission When they call POST/PUT/PATCH on /v1/shift-templates or /v1/overrides Then updates require If-Match ETag and return 409 on version conflicts, 400 on invalid input, and include an audit-id in responses Given an unauthorized caller When they invoke these endpoints Then the API returns 401 or 403 and persists no changes Given a GET request with a version query When executed Then the API returns the exact configuration for that version including created_at, effective_from, author, and diff metadata
Reflow propagation and consistency guarantees
Given period definitions or any baseline snapshot changes When a change is committed Then downstream delta computations for Delta Highlights are recomputed for all affected residents and windows within 60 seconds And caches are invalidated so badges and arrows reflect new deltas on next view And no duplicate family notifications are emitted due to reflow-only changes And a reflow job status is logged and observable with success or failure Given a reflow failure occurs When retried with exponential backoff Then all affected computations complete within 5 minutes or an alert is surfaced to admins
Delta Highlight UI & Accessibility
"As a caregiver, I want clear, color-coded badges that show what’s new since my last shift so that I can spot critical changes at a glance."
Description

Render at the top of each resident card a compact, color-coded summary of changes with arrows, counts, and a "New Since Last Shift" badge. Group highlights by category (Vitals, Mood, Activity, Incidents, Family) with tappable chips to expand details and navigate to the source update. Use an accessible, color-blind–safe palette and WCAG AA contrast, support large text and RTL locales, and minimize motion with subtle animations (<200 ms) and haptics (optional). Optimize for low-end Android devices: first meaningful paint under 500 ms with cached highlights and skeleton loading. Localize all labels, show timestamps relative to the period, and degrade gracefully when data is stale or offline. Integrate with existing card layout without breaking current interactions.

Acceptance Criteria
Top-of-Card Delta Summary Rendering & Integration
Given a resident card has changes in the last shift period When the card renders Then a compact delta summary appears at the top with up/down arrows, per-category counts, and a “New Since Last Shift” badge without displacing or obscuring existing action areas Given a category has zero changes When the summary renders Then that category is omitted from the summary Given app locale and pluralization rules When labels and the badge render Then they use localized i18n strings with correct plural forms Given change timestamps within the reporting period When times are shown Then they display as relative to the period (e.g., “2h ago”) in the current locale Given existing card tap, long-press, and swipe interactions When the summary is present Then all original interactions remain functional and touch targets are unchanged
Category Chips Expand & Deep-Link Behavior
Given a visible category chip When the user taps the chip Then the section expands within 200 ms to show new items for that category without navigating away Given an expanded item When the user taps its View Source action Then the app navigates to the originating update detail for that item Given navigation to a source update When the user presses Back Then the user returns to the same resident card with the previously expanded state preserved Given screen reader is enabled When focusing the chip and expanded items Then focus order is chip > count > first item > View Source and each element exposes accessible name and role
Color-Blind Safe Palette & WCAG AA Contrast
Given light or dark theme When the delta summary renders Then body text contrast is ≥4.5:1 and icons/graphical indicators are ≥3:1 per WCAG 2.1 AA Given users who cannot perceive color differences When interpreting status Then color is not the sole indicator; arrows/icons and labels also convey meaning Given category color assignments When arrows and badges render Then they use the approved color-blind–safe palette and avoid conflict with error/warning system colors Given automated and manual accessibility audits When run on the summary Then contrast and non-color-indicator checks pass
Large Text Scaling & RTL Mirroring
Given system font scale up to 200% When the summary and chips render Then no text is clipped or overlapped; content wraps without horizontal scrolling Given font scale at 200% When interacting with chips and actions Then all tap targets remain ≥44x44 dp and fully reachable Given an RTL locale (e.g., Arabic, Hebrew) When the UI renders Then layout mirrors horizontally: chip order reverses, arrow glyphs mirror, and counts/badges align correctly Given an RTL locale When relative time strings render Then they use correct locale formatting and numeral shaping
Motion Duration & Optional Haptics
Given animations for chip expansion or badge appearance When they play Then each animation duration is ≤200 ms and avoids large translations or parallax Given OS Reduce Motion is enabled When interacting with the summary Then nonessential animations are disabled and replaced with instant state changes Given system haptics are enabled When expanding a chip or following a source link Then a light haptic feedback occurs; when disabled Then no haptic fires
Low-End Android Performance & Loading
Given a low-end Android device (≈2 GB RAM, ~1.8 GHz class) and cached highlights When opening the resident list Then first meaningful paint of the delta summary occurs within 500 ms at the 95th percentile Given highlights are not cached When opening the resident list Then a skeleton loader for the summary shows within 100 ms and replaces with content within 1,200 ms at the 95th percentile Given scrolling through 20 resident cards When rendering summaries Then the app sustains 55+ FPS with <5% janky frames and no visible GC stutters Given the app is backgrounded and resumed within 30 minutes When returning Then highlights render from cache immediately and refresh in the background without blocking UI
Offline and Stale Data Degradation
Given the device is offline or highlights predate the last shift boundary When the summary renders Then a non-blocking Offline or Stale indicator appears with the timestamp of last successful sync Given the device is offline When a user taps View Source Then navigation is prevented and an inline message offers Retry upon connectivity Given connectivity is restored When the user refreshes or auto-refresh triggers Then the indicator clears and latest highlights display without app restart Given offline conditions and no cached highlights When rendering Then the app does not crash and shows a skeleton with an explanatory empty state
Signal Tuning & Noise Suppression
"As a nurse supervisor, I want to filter out trivial changes so that Delta Highlights surface only meaningful updates."
Description

Introduce configurable thresholds and rules to reduce alert fatigue: suppress minor variations within clinically normal ranges, deduplicate repeated tags, and consolidate multiple small updates into a single highlight. Provide facility-level defaults with the option to override per resident or tag. Include a whitelist of critical events/tags that are never suppressed. Allow supervisors to mark highlights as "not significant" to improve heuristics and generate feedback metrics. Expose suppressed-count indicators and maintain an audit trail of suppression decisions. Validate rules with test cases and monitor precision/recall of surfaced highlights.

Acceptance Criteria
Configuration Precedence and Normal-Range Suppression
Case A1: Given facility-level default thresholds are configured for vitals tags And a resident-specific override exists for "SpO2" variance of ±2% (facility default is ±4%) And the resident’s "SpO2" changes by 3% since the last shift When Delta Highlights are generated Then the "SpO2" change is surfaced as a highlight per the resident override And the audit trail records rule source "resident-level override", evaluated values, threshold used, resident ID, and timestamp Case A2: Given the facility default threshold for "Heart Rate" variance is ±10% And the resident’s "Heart Rate" changes by 5% since the last shift When Delta Highlights are generated Then no new vitals highlight is surfaced for "Heart Rate" And the suppressed-count increments by 1 on the resident's card And an audit entry is recorded with rule ID "threshold_suppress", evaluated values, and thresholds
Deduplicate Repeated Tags Within Time Window
Given a 2-hour deduplication window is configured for tag "mood:Anxious" And three "mood:Anxious" tags are recorded for the same resident within 2 hours When Delta Highlights are generated Then a single highlight appears for "mood:Anxious" with count=3 and timestamp of the most recent event And the audit trail lists all three source events and the deduplication decision "merged_within_window"
Consolidate Multiple Minor Updates Into Single Highlight
Given the consolidation rule bundles >=3 non-critical minor updates within 4 hours And four low-severity tags "Hydration", "Stretching", "Room Temp Adjusted", "Light Snack" occur within 4 hours and none exceed alert thresholds When Delta Highlights are generated Then one consolidated highlight titled "Minor updates (4)" is displayed, showing categories and time range And the individual minor updates are suppressed from separate display And the suppressed-count reflects the number of individually suppressed items And the audit trail records rule "minor_consolidation" with source event IDs
Critical Events Whitelist Never Suppressed
Given whitelist includes "Fall", "New Medication Started", and "Chest Pain" And a "Fall" event occurs during a period with active suppression rules When Delta Highlights are generated Then the "Fall" highlight is surfaced prominently and is not deduplicated, consolidated, or threshold-suppressed And the audit trail records a "whitelist_bypass" with rule ID and reason "critical"
Supervisor Feedback: Mark Not Significant Updates Heuristics
Given a supervisor marks a highlight as "Not significant" with category and optional note When the same pattern of inputs reoccurs for the same resident within the next 7 days Then the system suppresses the reoccurring highlight per the configured feedback policy unless thresholds are exceeded And the audit trail logs the feedback application with supervisor ID, rule affected, effective period, and decision outcome And the feedback metrics dashboard reflects the new "Not significant" count and suppression impact within 15 minutes
Suppressed-Count Indicator and Audit Drill-Down
Given one or more updates were suppressed for a resident in the current period When a Shift Relay Lead opens the resident’s Delta Highlights card Then a "Suppressed: N" badge is visible at the top of the card And tapping the badge reveals a breakdown by tag with counts and suppression reasons (e.g., "threshold_suppress", "dedupe", "minor_consolidation") And no data about non-consenting individuals is displayed in the breakdown, honoring consent and auto-blur policies And the breakdown provides a link to view the corresponding audit entries
Precision/Recall Monitoring and Test Suite Validation
Given a labeled regression test suite for highlight relevance is maintained and nightly evaluation is scheduled at 02:00 local time When the signal tuning rules are run against the last 30 days of labeled events Then precision >= 0.85 and recall >= 0.75 overall, and precision >= 0.80 for each whitelisted critical tag And if any target is missed, a "Tuning Required" alert is sent to supervisors and the previous passing rule set remains active And the evaluation report, metrics, and rule-set version are archived with timestamps for audit
Role-Based Privacy & Redaction
"As a compliance officer, I want Delta Highlights to respect consents and roles so that sensitive information is not exposed."
Description

Ensure Delta Highlights respect role-based access controls, resident consents, and privacy constraints. Hide or redact sensitive details based on user role (e.g., caregiver vs. admin) and consent status, and never reveal information about non-consenting co-residents. Align with existing auto-blur and redaction subsystems, displaying placeholders like "Hidden due to permissions" when necessary. Enforce data minimization in highlight payloads, encrypt data in transit and at rest, and log access for HIPAA-grade auditing. Recompute highlights when consent or role mappings change to prevent stale exposures.

Acceptance Criteria
Caregiver Role-Limited View
Given a user with role "Caregiver" is authenticated and opens a resident’s Delta Highlights When the highlights are rendered Then only data elements mapped to the Caregiver’s permissions are visible And then all non-permitted elements are redacted And then each redacted element is replaced with the exact placeholder string "Hidden due to permissions" And then no IDs, links, or metadata in the DOM or payload enable inference of the redacted values
Admin Role Visibility Within Consent
Given a user with role "Admin" and facility access is authenticated and opens a resident’s Delta Highlights When the highlights are rendered Then all data elements permitted by the resident’s current consent settings are visible And then any element restricted by consent remains hidden, regardless of Admin role And then visibility differences compared to Caregiver are limited to elements allowed by both role permissions and consent
Non-Consenting Co-Resident Redaction
Given a highlight references a group activity or shared context involving multiple residents and one or more co-residents lack consent When the highlight is generated or rendered for any user Then no names, photos, tags, or identifiers of non-consenting co-residents are present And then all non-consenting faces in associated images are auto-blurred prior to delivery And then text is resident-centric and contains no counts or descriptors that could identify a non-consenting co-resident
Standardized Placeholder Messaging
Given a field is hidden due to role permissions When rendering the highlight Then display the exact placeholder "Hidden due to permissions" in place of the value Given a field is hidden due to consent restrictions When rendering the highlight Then display the exact placeholder "Hidden due to consent" in place of the value Then all placeholders include accessible labels indicating the reason (permissions or consent)
Data Minimization and Encryption Compliance
Given the client requests Delta Highlights via API When the backend constructs the payload Then include only fields required to render the highlights (ids, types, timestamps, permitted changed fields, redaction flags) and exclude raw notes, full incident narratives, and raw media URIs unless explicitly requested and permitted And then payloads are transmitted over TLS 1.2+ and stored at rest using AES-256 (or FIPS-validated equivalent) And then automated tests verify restricted fields are absent for roles without permission
HIPAA-Grade Access Logging
Given any authenticated user views a resident’s Delta Highlights When the highlights are fetched or rendered Then an immutable audit log entry is recorded including user ID, resident ID, action "view_highlights", timestamp, fields accessed, redactions applied, and client IP/device fingerprint And then audit entries are non-editable by application users and are tamper-evident And then audit entries are queryable by compliance reporting within 5 minutes of the event
Recompute on Consent or Role Changes
Given a resident’s consent setting or a user’s role-to-permission mapping changes When an affected user opens or refreshes Delta Highlights Then highlights are recomputed using the new settings before display And then any cached highlight payloads for affected residents/users are invalidated within 60 seconds of the change And then the UI never reuses a previously fetched highlights payload without revalidating against current consent and permissions
Family Acknowledgment Sync & Audit
"As a caregiver, I want to see which families have acknowledged updates since my last shift so that I know who may need follow-up."
Description

Capture and display new family acknowledgments since the last period, including reads, reactions, and replies across email digests and the family app. De-duplicate events across channels, attribute acknowledgments to specific family members, and show timestamps with tap-through to the original update. Implement idempotent event ingestion with offline queueing on device and reliable webhook processing from the digest service. Maintain a searchable audit trail for compliance and follow-up, and handle late acknowledgments by updating current deltas without double-counting.

Acceptance Criteria
Idempotent Multi-Channel Acknowledgment Ingestion
Given an acknowledgment is generated for update U by family member F via any channel (family app or digest link) with correlation keys {ack_id, update_id, family_member_id, type} When the event is received or retried by the backend Then the system stores exactly one acknowledgment record per unique ack_id and ignores duplicates without incrementing any counts And duplicate attempts are logged with reason=duplicate and last_seen_at captured And the acknowledgment is durably persisted and queryable within 5 seconds (p95) of receipt And the record includes source_channel, created_at_utc, and facility_local_time fields
Attribution, Timestamping, and Tap-Through from Delta Highlights
Given new family acknowledgments exist for resident R’s updates in the last period When Delta Highlights renders the Family Acknowledgments section Then each item displays family_member_full_name, relationship, channel (App/Email), ack_type (Read/Reaction/Reply), and timestamp in facility timezone And tapping an item navigates to the original update detail in 1 tap And if the update is restricted or archived, the app shows an access message rather than a broken link And timestamps honor the viewer’s locale formatting while preserving UTC in the underlying record
Late Acknowledgments Update Current Delta Without Double-Counting
Given the previous period is closed and a family member acknowledges an older update When the late acknowledgment is ingested Then it appears under the current period’s Delta Highlights with a Late indicator And the prior period’s counts remain unchanged And delta counts are not incremented more than once for the same late acknowledgment even if the event is retried or arrives from multiple channels And the audit trail links both the original update timestamp and the acknowledgment timestamp
Offline Queueing and Ordered Retry for Client-Generated Acknowledgments
Given a client attempts to send an acknowledgment while offline When connectivity is unavailable Then the client persists the event to a durable offline queue with dedupe keys {ack_id, update_id, family_member_id} And upon reconnect, queued events transmit in original order, require 2xx confirmation before dequeue, and are safe to retry idempotently And the client retries automatically with exponential backoff for up to 24 hours And the UI surfaces a sending status and a warning if unsent after 5 minutes
Reliable, Secure Webhook Processing from Digest Service
Given the digest service sends a webhook for a read, reaction, or reply When the webhook arrives at KinLoop Then the request signature is verified; invalid signatures are rejected with 401 and no side effects And valid events are durably written before responding 2xx And transient failures (>=500 or 429) are retried with exponential backoff for up to 72 hours; exhausted retries are placed on a dead-letter queue with alerting And processing is idempotent based on ack_id or composite keys to prevent duplicate acknowledgment records and counts
Searchable, Exportable Acknowledgment Audit Trail
Given a staff user with Audit permission opens the Acknowledgment Audit view When they filter by resident, family member, time range, channel, and type Then results return within 2 seconds for up to 10,000 records and include fields: update_id, ack_id, resident_id, family_member_id, channel, type, source_ip (if available), created_at_utc, facility_local_time And exporting the filtered results to CSV yields a file with the same fields and a checksum footer And audit records are immutable and tamper-evident (hash chained) and can be retrieved by ack_id or update_id
Delta Highlights Summary Counts and Accessibility
Given new acknowledgments exist since the last period for a resident When Delta Highlights displays the resident card Then a New Since Last Shift badge shows the total new acknowledgments and per-type counts (Reads, Reactions, Replies) And counts are unique per family member per update per acknowledgment event and exclude cross-channel duplicates And visual indicators (arrows/badges) use approved design tokens and meet WCAG AA contrast And tapping the count reveals the acknowledgment list in reverse-chronological order
Briefing Mode & Batch Navigation
"As a Shift Relay Lead, I want a guided briefing mode that steps through delta highlights so that I can run fast, consistent handoffs."
Description

Provide a guided "Briefing Mode" that sequences through residents’ Delta Highlights in a carousel, supports gesture/keyboard navigation, and allows marking residents as briefed. Show progress indicators, estimated time to complete, and quick actions to add a handoff note or flag items for follow-up. Resume from the last position if interrupted, handle new incoming deltas mid-briefing, and sync completion metrics to the shift checklist. Work offline with queued state sync and maintain consistent ordering across devices when possible.

Acceptance Criteria
Start Briefing Mode from Delta Highlights
Given I am a Shift Relay Lead on the Delta Highlights view for an active shift When I tap or click "Briefing Mode" Then a full-screen carousel opens showing the first resident with un-briefed deltas And the card displays Delta Highlights with color-coded arrows and a "New Since Last Shift" badge And the header shows "1 of N" residents and an ETA in minutes And the resident list order matches the facility's configured sort with most-recent-delta as tie-breaker
Carousel Navigation via Gestures and Keyboard
Given Briefing Mode is open When I press Right Arrow or swipe left Then the carousel advances to the next resident within 500 ms And when I press Left Arrow or swipe right, it goes to the previous resident And keyboard-only navigation is supported with Left/Right Arrow and Esc to exit And focus is trapped within Briefing Mode until I exit
Mark Resident as Briefed with Progress and ETA Update
Given a resident card is in view When I mark the resident as "Briefed" Then the resident is marked briefed for the current shift and timestamped with my user ID And the progress indicator increments (X/Y) and percent updates And the ETA recalculates using the rolling average time per resident for this briefing session And completion metrics (briefed count, duration) sync to the current shift checklist And if all residents are briefed, Briefing Mode shows a completion state
Quick Actions: Handoff Note and Follow-up Flag
Given a resident card is in view in Briefing Mode When I add a handoff note Then the note saves to the resident timeline, is attributed to my user, and remains visible in Briefing Mode without exiting And when I flag an item for follow-up Then the flag is recorded with priority and appears in the follow-up queue for this shift And both actions are available offline and queue for sync if network is unavailable
Resume Briefing After Interruption
Given I have progressed to a specific resident in Briefing Mode When the app is closed, refreshed, or the device sleeps and I reopen within the same shift Then Briefing Mode resumes at the same resident with prior briefed/not-briefed state preserved And any unsent notes created in Briefing Mode are restored as drafts with a visual indicator And if the shift has changed, I am prompted to start a new briefing rather than auto-resume
Handle New Deltas Mid-Session
Given Briefing Mode is in progress When new deltas arrive for residents not yet briefed Then I see a non-blocking indicator showing the count of new items And the current in-session order remains unchanged until I choose Refresh Order And upon refresh, new or updated residents are inserted by the global sort without duplicating already briefed residents And if the current resident receives a new delta, the card shows an inline update badge without changing position
Offline Operation, Sync, and Cross-Device Ordering
Given the device is offline while in Briefing Mode When I navigate, mark residents briefed, add notes, or set flags Then all actions succeed locally and are added to a reliable queue for sync And when connectivity returns, queued actions sync within 30 seconds and reflect on the shift checklist And if a conflict occurs (same resident briefed by another user), the system records both with user and timestamp and keeps the resident as briefed And ordering is consistent across devices based on facility sort, then most recent delta timestamp, then resident last name; the session order remains stable once Briefing Mode starts

Priority Queue

Ranks Snapshot Cards by urgency using signals like missed routine tags, unacknowledged family updates, incident holds, and upcoming appointments. Provides a suggested handoff order and ETA per resident, helping supervisors focus high-impact reviews first and trimming minutes off every briefing.

Requirements

Urgency Scoring Engine
"As a shift supervisor, I want each Snapshot Card to have a clear urgency score so that I can review the most critical residents first."
Description

Compute an urgency score for each resident’s Snapshot Card by ingesting signals such as missed routine tags, unacknowledged family updates beyond a configurable time window, open incident holds, and upcoming appointments within set lead times. Normalize and weight signals to produce a single ranked score with deterministic tie-breaking, and expose the contributing factors for transparency. The engine runs event-driven recalculations on new signals and on schedule-based checks, persists scores with timestamps, and degrades gracefully if certain inputs are unavailable. Integrates with KinLoop’s Snapshot data model and audit logs to surface "why this is prioritized" badges. Benefits include directing supervisors to the highest-impact reviews first, reducing briefing time, and cutting inbound calls by ensuring timely follow-ups.

Acceptance Criteria
Event-Driven Recalculation on New Signal
Given resident R has a stored urgency score and an unacknowledged family update exceeds the configured threshold When the event is received by the engine Then R’s score is recalculated within 5 seconds, persisted with an updated_at timestamp, and an audit log is written with trigger="event", before/after values, and contributing factors
Schedule-Based Recalculation and Drift Correction
Given the scheduler interval is configured (e.g., every 5 minutes) When a scheduled tick occurs Then the engine recomputes scores for all residents with time-based signals, persists any changed scores with updated_at timestamps, and records audit entries with trigger="schedule"
Normalization, Weighting, and Deterministic Tie-Breaking
Given signal normalizers produce values in [0,1] and weights configured per signal sum to 1.0 When a score is computed Then total_score = round(100 * Σ(weight_i * normalized_i)) And if two residents have identical total_score, rank order is determined by resident_id ascending and is stable across runs
Transparent Contributing Factors Badge
Given a resident’s score is computed Then the engine outputs a factors array containing signal_key, normalized_value, weight, contribution (0–100), and human_readable_reason And Σ(contribution) equals total_score within ±0.5 And the factors array is persisted with the score for UI badges
Graceful Degradation on Missing Inputs
Given a required data source (e.g., appointments) is unavailable or times out When scores are recomputed Then the engine computes using available signals, sets degraded=true, includes missing_signals with the unavailable source, persists the resulting score, and writes a warning audit entry And processing continues for all residents without errors
Persistence, Timestamps, and Snapshot Model Integration
Given a recalculation changes a resident’s score or factors When persisting results Then snapshot_card.score, snapshot_card.score_updated_at (UTC ISO 8601), and snapshot_card.score_factors are updated atomically And repeated identical inputs do not create duplicate records (idempotent write)
Configurable Thresholds for Family Updates and Appointments
Given facility-level settings for unacknowledged_update_threshold_hours and appointment_lead_time_hours When an admin updates these settings Then the engine applies new values on the next scheduler tick or within 60 seconds, without service restart And subsequent computations reflect the new thresholds
Real-time Score Refresh & Sync
"As a supervisor, I want the queue to update in real time so that I never act on stale priorities."
Description

Keep the Priority Queue current by pushing score and order updates to clients within a target of ≤5 seconds after relevant signal changes. Implement lightweight push via WebSockets (with HTTP long-poll fallback) and client-side throttling/debouncing to avoid jitter. Display "Last updated" and optimistic UI when actions (acknowledge/snooze/escalate) occur. Provide offline resilience with cached last-known order and conflict resolution upon reconnect. Integrates with KinLoop’s notification and data layers to ensure supervisors on web and mobile see the same queue state. Benefits include preventing action on stale priorities and accelerating briefings in fast-changing shifts.

Acceptance Criteria
Real-time push within ≤5s of signal change
- Given a resident’s priority signals change, when the backend recalculates score/order, then connected clients receive and apply the new queue order and scores with p95 end-to-end latency ≤ 5s and p99 ≤ 7s (event to UI applied). - Given multiple signal changes within 1s, when updates are processed, then only the latest effective order is applied (no intermediate flicker). - Given an update payload arrives, when rendering, then the visible queue order updates within 200ms of payload receipt.
WebSocket primary with HTTP long-poll fallback
- Given a client supports WebSockets, when connecting, then a secure WS is established within 2s and heartbeats are sent every 30s with auto-reconnect (backoff 1s→30s). - Given WS fails or drops, when fallback engages, then HTTP long-poll starts within 2s and delivers updates with p95 latency ≤ 7s. - Given WS reconnects after fallback, when stable for 10s, then the client switches back to WS without user action and without duplicate updates.
Throttled, debounced UI to prevent jitter
- Given bursty updates (>3 updates within 1s), when applying to the queue UI, then reorder operations are debounced to a 300ms window and throttled to ≤ 2 visual reorders per second. - Given two updates arrive within the debounce window, when rendering, then they are coalesced into a single reorder. - Given an update with no effective order change, when processed, then no visual reorder occurs.
Last updated timestamp and optimistic actions
- Given a supervisor taps acknowledge/snooze/escalate, when the action is initiated, then the queue reflects the optimistic state locally within 200ms and shows a pending indicator. - Given the server confirms the action, when confirmation arrives, then the pending indicator clears and Last updated shows an ISO 8601 timestamp aligned to server time within 1s. - Given the server rejects or times out (>5s), when handling the result, then the optimistic change is reverted, an error toast is shown, and the previous order is restored.
Offline cache and reconnect conflict resolution
- Given the client goes offline, when detection occurs, then an offline banner appears within 1s and the cached last-known queue order/scores load from local storage in ≤ 500ms. - Given connectivity is restored, when sync starts, then the queue reconciles to server state with p95 ≤ 5s, preserving unprocessed optimistic actions via idempotent action IDs. - Given server state conflicts with local optimistic actions, when reconciliation completes, then server state prevails, a non-blocking Changes reconciled notice appears, and a change log is accessible.
Cross-device state consistency
- Given two supervisors view the same facility queue on web and mobile, when a relevant signal change or action occurs, then both devices converge to the same order and scores within p95 ≤ 5s (p99 ≤ 7s) using identical tie-breakers. - Given simultaneous actions on the same resident from two devices, when processed, then the final state is consistent and duplicates are de-duplicated via idempotency keys. - Given differing time zones/locales, when Last updated renders, then both devices display consistent timestamps relative to locale backed by the same server time.
Reliability, idempotency, and monitoring
- Given transient network errors, when retrying subscriptions or polls, then exponential backoff with jitter is applied (1s, 2s, 4s … up to 30s) without exceeding 1 attempt per connection path at a time. - Given duplicate or out-of-order update payloads, when applying, then the client discards them using a monotonically increasing version/ETag ensuring exactly-once application. - Given a 24h production window, when observing metrics, then update delivery success rate ≥ 99.9% and client sync error rate ≤ 0.5%, with alerts emitted on threshold breach.
Suggested Handoff Order UI
"As a supervisor, I want a clear, ordered list with reasons and ETAs so that I can run an efficient briefing."
Description

Present a ranked, scannable queue that lists residents with their urgency score, top contributing signals (as badges), suggested ETA per card, and an aggregate handoff time. Provide filters by unit, shift, and role; quick search; accessibility-compliant contrast and touch targets; and one-tap navigation into the Snapshot Card. Include a sticky header summarizing counts by urgency band and allow collapsing non-urgent items. Integrates with existing KinLoop briefing views to replace manual sorting and supports brief, high-signal readouts for tech-light caregivers. Benefits include trimmed briefing minutes and clearer, justification-backed prioritization.

Acceptance Criteria
Ranked Queue Displays Urgency, Signals, ETA, and Aggregate Time
Given the Priority Queue engine returns residents with urgency scores, signals, and ETAs When a caregiver opens the Suggested Handoff Order view Then the list renders residents strictly in descending urgency score order And ties are displayed in the deterministic order provided by the engine And each resident item shows: resident name, numeric urgency score, and up to the top 3 contributing signal badges And each resident item shows a suggested ETA in whole minutes with the label "ETA" And the aggregate handoff time shown at the top equals the sum of ETAs for all currently visible (not-collapsed) residents in the queue order And if no residents match, an empty state with "No residents to review" is shown
Filter by Unit, Shift, and Role Updates Queue
Given the caregiver has default unit, shift, and role When the Suggested Handoff Order view loads Then those defaults are applied as active filters and reflected in the filter controls When the caregiver changes any filter (unit, shift, role) Then the list updates to only include residents matching all selected filters And urgency band counts and aggregate handoff time recalculate to reflect the filtered set And the selected filters persist while the user remains in the app session and on returning from a Snapshot Card
Quick Search Locates Residents Instantly
Given the queue is loaded and optionally filtered When the caregiver types at least 2 characters into Search Then the list filters to residents whose name, preferred name, or room number contains the query (case- and diacritic-insensitive) And the search operates in conjunction with active filters And clearing the search restores the pre-search list And search results update within 300 ms for up to 200 residents on a supported device
Sticky Header Shows Urgency Band Counts and Collapsible Non-Urgent
Given the queue has more items than fit on screen When the caregiver scrolls the list Then the header remains visible (sticky) at the top And the header displays counts of residents per urgency band as provided by the engine and the current filters/search And the header displays the aggregate handoff time for currently visible, not-collapsed items When the caregiver toggles "Non-Urgent" to collapsed Then all non-urgent items are hidden from the list and excluded from the aggregate handoff time And the collapse state persists while the user remains in the app session and on returning from a Snapshot Card
One-Tap Navigation to Snapshot Card with State Preservation
Given a resident appears in the Suggested Handoff Order list When the caregiver taps anywhere on the resident row (excluding filter/search controls) Then the resident's Snapshot Card opens When the caregiver navigates back from the Snapshot Card Then the Suggested Handoff Order view is restored with the previous scroll position, active filters, search query, urgency band collapse state, and selection intact
Accessibility: Contrast, Touch Targets, and Screen Reader Support
Given the Suggested Handoff Order UI is displayed Then all text and badge labels meet WCAG 2.1 AA contrast (≥4.5:1 for body text, ≥3:1 for large text/icons) And all tappable controls (rows, badges, filters, search, collapse toggle) have touch targets ≥44x44 px/dp And focus order is logical: header summary → filters/search → list items in order And each resident row exposes accessibility labels that include resident name, urgency score, top signal names, and ETA And urgency band counts and aggregate time are announced via a polite live region when they change And the UI remains operable and readable at 200% text scaling without content loss or overlapping
Integration with Briefing Views and High-Signal Readout
Given the caregiver is in the existing Briefing view When they select "Suggested Handoff Order" Then the Suggested Handoff Order UI opens within the Briefing workflow And a visible label indicates "Suggested order" is active and manual sort controls from Briefing are not shown in this view And tapping Back returns to the Briefing view at its prior state And each resident row shows no more than 3 signal badges; if more signals exist, a "+N" overflow badge is displayed
Configurable Weights & Thresholds
"As an administrator, I want to tune priority rules so that the queue reflects our facility’s policies."
Description

Provide an admin console to tune signal weights, thresholds, and time windows per facility or unit, with preset templates (e.g., Memory Care, Skilled Nursing) and safe defaults. Include a preview mode that shows how proposed changes would re-rank current residents, effective-dating, rollback, and a full audit trail of configuration changes. Enforce role-based access and validation (e.g., caps on extreme weights) to prevent misconfiguration. Integrates with the scoring engine via a versioned policy service. Benefits include alignment with local policies, clinical priorities, and regulatory requirements without code changes.

Acceptance Criteria
RBAC: Admin-Only Configuration Access
Given a Facility Admin is authenticated and navigates to Priority Queue policy settings When they open the configuration page Then they can view and edit weights, thresholds, and time windows and the Save action is enabled Given a Supervisor is authenticated When they access the same configuration page Then they have read-only access, the Save action is disabled, and any save attempt is blocked server-side with HTTP 403 Given a Caregiver is authenticated When they attempt to access the configuration page or API Then they receive HTTP 403 and no configuration data is returned Given any denied access or save attempt When it occurs Then an audit entry is recorded with user ID, role, timestamp, IP, target scope, and outcome "Denied"
Per-Unit Tuning with Validation Caps and Persistence
Given a Facility Admin is configuring Unit A When they set 'Missed Routine Tag' weight to 7.5 (allowed range -10.0 to +10.0), threshold to 2, and time window to 24 hours Then client and server validations pass and the Save action is enabled Given an entry is out of range (e.g., weight 12.0, threshold -1, or time window 1 minute) When Save is attempted Then inline errors identify each invalid field and the server responds 422 with no changes persisted Given values include decimals When saved Then numeric values are rounded to one decimal place and persisted accordingly Given a successful save When the page is reloaded Then a new draft policy version exists for Unit A with the saved values and a unique version_id
Templates and Safe Defaults
Given a new Unit configuration is created When the 'Memory Care' template is applied Then weights, thresholds, and time windows populate to the template defaults and pass all validations Given the 'Skilled Nursing' template is applied When applied to an existing configuration Then existing fields are overwritten in draft state without affecting the live policy until published Given a user selects 'Reset to Safe Defaults' When confirmed Then all values revert to system safe defaults within allowed ranges and validation passes Given template application results in changes When the user attempts to navigate away without saving Then the user is prompted to save or discard draft changes
Preview Mode: Re-Ranking Impact
Given a draft policy exists for a facility or unit When the user clicks Preview Then the system computes a proposed ranking, score deltas, ETA deltas, and suggested handoff order without changing the live queue Given up to 500 residents in scope When generating the preview Then results are returned in <= 2 seconds at the 95th percentile Given the preview is displayed When the user toggles between Current and Proposed Then each resident row shows before/after rank, score change, ETA change, and top 3 contributing signals Given the user modifies a weight or threshold in the draft When they click Preview again Then the preview updates to reflect the new inputs
Effective-Dated Publish and Versioned Integration
Given a validated draft policy version When the Admin sets an Activation Time and clicks Publish Then an immutable policy version is created with version_id and effective_at timestamp and is delivered to the versioned policy service Given a scheduled activation exists When the current time reaches effective_at Then the scoring engine switches to the new version within 60 seconds and recalculates resident scores and queue order Given the policy service fails to acknowledge receipt When publish is attempted Then the system retries with exponential backoff up to 5 attempts, alerts the Admin, and the live engine continues using the last known good version Given overlapping schedules or conflicting scopes are detected When publishing Then the system prevents the publish or enforces a deterministic precedence rule and informs the user of the resolution Given the facility operates in a specific time zone When setting Activation Time Then the time is entered and displayed in facility local time and stored in UTC
One-Click Rollback to Prior Version
Given a list of prior policy versions is available When the Admin selects a target version and clicks Rollback Then the system creates a new version that mirrors the target, records a rollback reason, and schedules immediate activation Given a rollback is confirmed When it is executed Then the scoring engine switches to the rolled-back version within 60 seconds and the live queue is recalculated Given a rollback is initiated When viewing the change Then a Preview of expected rank changes is available before confirmation Given versions exist before and after rollback When reviewing version history Then no versions are deleted and re-rolling forward is supported without data loss
Comprehensive Audit Trail
Given any configuration action (create, update, template apply, preview, publish, schedule, rollback, access denied) When the action occurs Then an audit record is created capturing who, role, scope (facility/unit), before/after values, timestamps (created_at, effective_at), version_id, client IP, and outcome Given an Admin opens the Audit view When filtering by date range, actor, scope, outcome, or version_id Then results return within 2 seconds for up to 10,000 records and can be exported as CSV or JSON Given audit data retention requirements When records age Then audit records are retained for at least 24 months, are append-only (immutable), and include tamper-evident hashes with chain verification
ETA Estimation Model
"As a supervisor, I want accurate ETAs per card so that I can plan my handoff time."
Description

Estimate the time to review each Snapshot Card based on heuristic features (e.g., number of media items, voice-to-text length, presence of incident holds, upcoming appointment proximity, historical review durations by role). Show per-card ETAs and a total estimated handoff time, with caps, floors, and clear confidence indicators. Learn from actual completion times to improve estimates over time while preserving privacy (aggregate, de-identified telemetry). Provide sensible fallbacks if insufficient history exists. Integrates with the UI to guide scheduling and pacing during briefings. Benefits include more predictable handoffs and reduced overrun risk.

Acceptance Criteria
Per-Card ETA Calculation with Caps and Floors
Given any Snapshot Card with defined heuristic inputs When the ETA is computed Then the ETA is an integer number of minutes between the configured eta_floor_min and eta_cap_min (inclusive) Given two otherwise identical cards where media_count_A > media_count_B When ETAs are computed Then ETA_A >= ETA_B Given two otherwise identical cards where vtt_seconds_A > vtt_seconds_B When ETAs are computed Then ETA_A >= ETA_B Given identical inputs evaluated twice within one minute and no parameter update When ETAs are computed Then the outputs are equal Given a card with minimal feature values When the ETA is computed Then the ETA equals eta_floor_min
Total Estimated Handoff Time Rollup
Given a handoff list containing K Snapshot Cards with ETAs and status Pending When the Total ETA is displayed Then Total ETA equals the sum of ETAs for all Pending cards in the current handoff scope and is shown as integer minutes Given a card is marked Reviewed When the Total ETA is recalculated Then the Total ETA decreases by that card’s last-shown ETA within 500ms Given filters or resident scoping are applied When the Total ETA is displayed Then it reflects only the visible/in-scope Pending cards Given a new card is added to the handoff list When the Total ETA is recalculated Then it increases by the new card’s ETA within 500ms
Confidence Indicator Rendering and Logic
Given historical sample_count >= 20 for the same role and resident-type and coefficient_of_variation <= 0.20 When the confidence level is computed Then confidence = High Given historical sample_count between 5 and 19 inclusive or coefficient_of_variation between 0.21 and 0.40 When the confidence level is computed Then confidence = Medium Given historical sample_count < 5 or coefficient_of_variation > 0.40 or any fallback/default path is used When the confidence level is computed Then confidence = Low Given a confidence level of High, Medium, or Low When the card is rendered Then a matching badge is shown (High=Green, Medium=Amber, Low=Red) with accessible label "ETA confidence: <Level>" and a tooltip including sample_count and last_updated_at
Privacy-Preserving Learning from Completion Times
Given a review is completed When telemetry is persisted Then the record contains only de-identified fields: role, facility_id_hash, feature_buckets, duration_seconds, date_yyyy_mm_dd, app_version and contains no resident name/id, caregiver name/id, media content, or raw transcript text Given at least 10 new telemetry records for a role within a facility since the last update When nightly aggregation runs Then model parameters (e.g., per-role base minutes and feature multipliers) are updated and the model_version is incremented Given facility-level telemetry opt-out is enabled When reviews are completed Then no telemetry is stored and the model continues to use global defaults Given a model parameter update occurs When the audit log is queried Then an entry exists with previous_values, new_values, model_version, and updated_at
Fallbacks for Insufficient History
Given sample_count for the card’s role/facility < 5 When the ETA is computed Then the model uses global default parameters and sets confidence = Low Given no historical data and some features are missing When the ETA is computed Then ETA equals default_base_minutes bounded by eta_floor_min and eta_cap_min Given a fallback/default path is used When the UI is rendered Then an info icon is shown with text "ETA based on defaults due to limited history"
UI Integration of ETAs on Snapshot Cards
Given the Handoff view loads with N Snapshot Cards When cards are rendered Then each card displays an ETA chip (e.g., "ETA 3m") and a confidence badge, and a Total ETA indicator is visible for the list Given a card is marked Reviewed, added, or removed When the view updates Then the Total ETA and any affected per-card ETA values update within 500ms Given the device is offline When the Handoff view is open Then the last-known ETAs remain visible with an offline indicator, and ETAs refresh automatically within 2s of reconnect Given a screen reader is active When focusing a card or the Total ETA Then an accessible label announces the ETA and confidence level
Heuristic Feature Influence on ETA
Given an incident_hold = true on a card When the ETA is computed Then ETA increases by at least incident_penalty_min (configurable) versus an otherwise identical card without a hold Given an upcoming appointment within proximity_window_minutes When the ETA is computed Then ETA increases by at least appointment_penalty_min versus no upcoming appointment Given voice_to_text_duration bucketed as 0–30s, 31–120s, >120s When ETAs are computed Then ETA for higher buckets is monotonically non-decreasing Given additional media items are added up to max_media_influence_count When ETAs are computed Then ETA increases by at least media_increment_min per item and by no more than media_increment_max in total due to media
Workflow Actions: Acknowledge, Snooze, Escalate
"As a supervisor, I want to acknowledge, snooze, or escalate items so that the queue reflects real progress."
Description

Enable supervisors to mark items as Acknowledged (removes from active queue and logs reviewer), Snooze (temporarily lowers priority for a set duration with required reason), or Escalate (routes to designated clinical/admin roles and triggers notifications). Actions immediately re-score affected residents, update the UI, and write to the audit log and digest pipeline when appropriate. Support undo within a short window and concurrency-safe handling for multiple reviewers. Integrates with KinLoop’s activity stream and family digest schedules to keep stakeholders aligned. Benefits include visible progress, fewer follow-up calls, and faster resolution of critical items.

Acceptance Criteria
Acknowledge removes item and logs reviewer
Given a supervisor views the Priority Queue with an active Snapshot Card for a resident When the supervisor selects Acknowledge on the item Then the item is removed from the active queue within 2 seconds And the resident’s priority score, suggested handoff order, and ETA are recalculated and rendered within 2 seconds And the UI displays a confirmation showing the reviewer name and timestamp And an audit log entry is created with action=acknowledge, actorId, residentId, itemId, and timestamp And the resident’s activity stream records an Acknowledged event And the digest pipeline is enqueued with an Acknowledged marker according to organization settings
Snooze requires reason, lowers priority, and auto-reactivates
Given a supervisor views an active Snapshot Card When the supervisor selects Snooze Then a form requires selecting a snooze duration (e.g., 15m, 30m, 60m, custom up to 24h) and entering a reason of at least 5 characters And the Save action is disabled until both fields are provided And upon saving, the item is hidden from the active queue and its priority is lowered for the snooze duration And a Snoozed until <timestamp> badge is visible in the item detail to all users And the resident’s score, handoff order, and ETA recalculate and render within 2 seconds And an audit log entry and activity stream event are recorded with snooze reason and expiration And no outbound notifications are sent as a result of Snooze And when the snooze expires, the item automatically returns to the active queue and re-scores within 60 seconds of expiration
Escalate routes to designated roles and triggers notifications
Given a supervisor views an active Snapshot Card When the supervisor selects Escalate and chooses one or more designated clinical/admin roles Then the item is marked Escalated with visible role badges And in-app notifications are delivered to the selected roles within 10 seconds And email/push notifications are sent per recipient preferences within 60 seconds And the resident’s score, handoff order, and ETA recalculate and render within 2 seconds And an audit log entry is recorded with action=escalate, actorId, residentId, itemId, roles, recipients, and timestamp And the resident activity stream records an Escalated event And the digest pipeline flags the event for inclusion in the next family digest if the underlying item is family-visible and policy allows escalation visibility
Undo reverses recent action within 30 seconds
Given a supervisor has just Acknowledged, Snoozed, or Escalated an item When the supervisor selects Undo within 30 seconds Then the prior state of the item is restored, including queue presence and previous priority score And any queued outbound notifications from the original action are marked canceled if not yet delivered And the UI reflects the reversal within 2 seconds And an audit log Reverted entry is recorded linking to the original action And the activity stream records a reversal event And after 30 seconds from the original action, the Undo option is no longer presented
Concurrency control prevents conflicting actions
Given two supervisors open the same active Snapshot Card When Supervisor A completes an action (Acknowledge, Snooze, or Escalate) And within 5 seconds Supervisor B attempts a different action on the same item Then Supervisor B is shown a non-blocking alert that the item changed due to another action And Supervisor B’s attempted action is not applied And the item state is refreshed for Supervisor B within 2 seconds And only one applied action is recorded in the audit log, with an additional attempt entry for Supervisor B marked outcome=conflict And no duplicate notifications are emitted
Immediate re-scoring updates queue and ETA for all viewers
Given multiple supervisors have the Priority Queue open When any action (Acknowledge, Snooze, Escalate) is applied to an item Then the resident’s priority score, suggested handoff order, and ETA recompute and render for all viewers within 2 seconds And the affected item moves, disappears, or updates badges accordingly in all open sessions And aggregated counts and indicators reflect the new state with no stale values after refresh
Actions write to activity stream and family digest pipeline
Given an action is completed on a family-visible Snapshot Card When the next scheduled family digest job runs Then the digest payload includes action metadata according to organization-configured labels (e.g., Acknowledge as staff-reviewed, Escalate as escalated, Snooze excluded by default) And timestamps are presented in the resident’s local timezone And the resident’s activity stream shows the action immediately with actor, timestamp, and any reason/targets as applicable
Privacy & Compliance Safeguards
"As a compliance officer, I want the priority queue to respect consents and log changes so that we maintain dignity and meet regulations."
Description

Ensure the Priority Queue respects consent, privacy, and dignity requirements: honor auto-blur on media, suppress non-consenting faces from badges and previews, exclude PHI from visible signal text, and enforce role-based visibility for sensitive signals (e.g., incident holds). Provide an auditable trail of score changes with their contributing factors and configuration versions. Support data retention policies and export for compliance reviews. Integrates with KinLoop’s existing consent model and security controls (RBAC, encrypted storage). Benefits include regulatory alignment and trust with residents and families while maintaining operational effectiveness.

Acceptance Criteria
Auto-Blur Enforcement in Queue Media Previews
Given a Snapshot Card references media with one or more detected faces And consent states for each detected face are available from KinLoop’s consent model When the Priority Queue renders any thumbnail or hover preview for the card Then all faces where consent=false are blurred according to the active Blur Policy configuration version And faces where consent=true remain unblurred And no unblurred original frame containing non-consenting faces is transmitted to the client And any cached asset for the card exists only in its blurred form for non-consenting faces And an audit entry "auto_blur_enforced" with media_id, resident_id, and blur_policy_version is recorded
Badge and Thumbnail Suppression for Non-Consenting Faces
Given the Priority Queue displays resident badges/avatars and media thumbnails When the primary resident for a card has consent=false for face display Then the badge/avatar shows initials or a neutral placeholder with no facial pixels visible And if a thumbnail frame includes any non-consenting third-party face, the UI shows a blurred composite or neutral placeholder (never an unblurred frame) And ALT text, captions, or tooltips do not include the names of non-consenting persons And an audit entry "badge_suppressed" with resident_id and reason=non_consent is recorded
PHI-Free Signal Text in Queue and Notifications
Given the Priority Queue assembles and displays signal reasons (e.g., missed routine tags, unacknowledged updates, incident holds, upcoming appointments) When signal text is rendered in the Queue UI or sent via related notifications Then fields labeled PHI in the schema are excluded from the payload and presentation And free-text templates use only approved non-PHI tokens (e.g., relative time, generic categories) per Redaction Policy configuration And provider names, diagnoses, medication names, procedure types, room numbers, and contact details are not present in visible text, HTML attributes, ARIA labels, or analytics events And the /queue API response contains no PHI-tagged keys (contract test: 0 occurrences)
Role-Based Visibility for Sensitive Signals (Incident Holds)
Given user roles include Aide, Supervisor, and Admin per RBAC And a Queue item includes a sensitive signal such as an incident hold When an Aide views the Queue or queries the /queue API Then the sensitive signal is redacted to a generic placeholder (e.g., "Sensitive—see supervisor") with no link to details When a Supervisor or Admin views the same item Then the full reason details and link to the incident case are visible And any direct API request by an Aide to incident details returns HTTP 403 with no sensitive payload And each access decision is logged with user_id, role, resource_id, decision, and timestamp
Auditable Score Change Ledger with Config Versioning
Given the Priority Queue recalculates scores and order When any score changes for a resident card Then an append-only ledger entry is written with timestamp (UTC), resident_id, previous_score, new_score, delta, ordered list of contributing factor codes with weights, and scoring_config_version hash And entries form a tamper-evident chain via a previous_entry_hash And an admin can query by resident and time range and reconstruct the score and queue position at an arbitrary timestamp using the ledger and config version And ledger entries store factor codes and IDs only (no PHI or free-text) And attempting to edit or delete a ledger entry outside retention workflows is disallowed and logged
Data Retention and Compliance Export for Queue Artifacts
Given facility-level retention settings are configured When the scheduled retention job runs Then ledger and related audit entries older than the configured retention period are purged unless on legal hold, with a purge report of counts by type And all retained and exported artifacts remain in encrypted storage at rest; no temporary plaintext files are written When an Admin initiates a compliance export for a date range Then the system produces an encrypted CSV/JSON package containing ledger entries, audit events, scoring_config_version references, and consent snapshot IDs (no media binaries), and logs the export with user_id and timestamp And the export action requires MFA confirmation and is downloadable only by Admins
Fail-Closed on Consent/RBAC/Service Degradation
Given the consent or RBAC service is unavailable, times out, or returns an indeterminate state When the Priority Queue renders items or evaluates sensitive signals Then access decisions default to deny (HTTP 403 for protected endpoints) and sensitive details are redacted for all roles And faces are treated as non-consenting (blur applied) and badges fall back to placeholders And no new client-side caching of media or signal payloads occurs during the degraded state And a system health banner is shown to authorized users and an audit event "fail_closed" with error_cause is recorded

RoleView Cards

Adapts each card to who’s viewing it: Snapshot Aides get quick-tag buttons and capture prompts, Shift Relay Leads see approvals and team notes, and Privacy Stewards see consent scope badges and audit flags. Cuts noise, surfaces the right actions, and keeps sensitive details limited to the right roles.

Requirements

Dynamic Role-Based Card Renderer
"As a staff member with a defined role, I want cards to automatically adapt to my responsibilities so that I see the most relevant information and actions without distraction."
Description

Implements a configuration-driven rendering engine that adapts each card’s layout, components, and actions to the viewer’s role (Snapshot Aide, Shift Relay Lead, Privacy Steward, Administrator) and permissions. Uses JSON/YAML templates with server-provided policies to determine visible fields, action buttons, and badges. Supports cross-platform delivery (iOS/Android) with a shared schema, fallbacks when a role template is missing, and feature flag gating for gradual rollout. Enforces policy evaluation on-device and server-side for integrity, and gracefully degrades offline. Integrates with existing card data model, media capture, and auto-blur pipeline to ensure consistent behavior across roles.

Acceptance Criteria
Snapshot Aide RoleView Card Rendering
Given a signed-in user with role Snapshot Aide and a facility-configured aide template is available When the user opens any resident card Then the card renders only the components defined in the aide template (e.g., quick-tag buttons, capture prompts) and hides components not in the template And action buttons not permitted by policy are not rendered and not invokable via accessibility or deep links And the visible component count matches the template-defined count for that role And any restricted fields (e.g., approvals, audit flags) are absent from the client payload and UI
Shift Relay Lead RoleView with Approvals and Notes
Given a signed-in user with role Shift Relay Lead and a lead template is available When the user opens a resident card that has pending snapshots Then the Approve/Reject controls render as enabled if server policy grants approval permission and disabled otherwise And team notes panel renders with existing notes count and supports add/edit per policy And fields marked sensitive-for-leads=false are hidden And all actions taken (approve/reject/note add) are recorded with role metadata and appear in audit trail
Privacy Steward Consent Badges and Audit Flags
Given a signed-in user with role Privacy Steward and a steward template is available When the user opens any resident card with mixed consent statuses Then consent scope badges are rendered for each attached media per server policy And audit flags panel is visible with unread flag count And any media lacking consent for public faces shows auto-blur applied indicator and prevents unblur unless policy allows override And PII fields not in steward allowlist are omitted from payload and not present in the UI tree
Template Fallback and Feature Flag Gating
Given a user whose role template is missing or malformed When the user opens a resident card Then the renderer falls back to the default base template for that role group without app crash And a telemetry event "template_fallback" is emitted with role, template version, and facility id And if feature flag roleview_renderer=false for the user, the legacy card renders instead of the new renderer And toggling the feature flag at runtime takes effect on next card open without requiring app restart
Dual Policy Evaluation and Integrity Enforcement
Given server-side policy evaluation returns a permission set for the current user and card And device-side policy evaluator has the same policy version cached When the user attempts an action not in the granted permission set (e.g., approve without permission) Then the client does not render the action and blocks invocation via deep link intents And if a forged request is sent, the server rejects with 403 and reason code POLICY_DENIED And client displays a non-sensitive error toast and logs a "policy_denied" event without exposing restricted data And a policy version mismatch triggers a background policy refresh and action is re-evaluated before rendering
Offline Degradation and Sync Behavior
Given the device is offline and a role template and policy have been cached within the last 24 hours When the user opens a resident card Then the card renders using the cached template and policy And actions requiring server validation (e.g., approvals) are disabled with an offline badge And allowed local actions (e.g., capture + quick-tag) are queued with role metadata and retry automatically on reconnect And upon reconnect, queued actions are submitted in order and UI status updates within 2 seconds of server ack
Cross-Platform Schema Parity (iOS/Android)
Given the shared card schema version N and identical templates are deployed to iOS and Android When the same role opens the same resident card on both platforms Then the visible component set, ordering, and enabled/disabled states are identical And accessibility labels and actions map to the same IDs across platforms And any schema field not recognized by a client is safely ignored without crash, and is reported via telemetry as "schema_unknown_field" And UI snapshot tests per role pass with <1% diff across platforms for the same template
Snapshot Aide Quick-Tags & Capture Prompts
"As a Snapshot Aide, I want one-tap tags and prompts on the card so that I can capture quick, accurate updates without breaking my care flow."
Description

Provides one-tap contextual tags (e.g., Hydration, Mobility Assist, Mood) and voice-to-text capture prompts optimized for rapid documentation during care tasks. Includes configurable tag sets by facility, smart defaults per resident care plan, haptic feedback on save, offline queuing with conflict resolution, and instant linkage to photos with auto-blur applied. Ensures entries map to digest categories and are time-stamped with minimal input. Adds lightweight error states and retry logic to maintain speed while preserving data integrity.

Acceptance Criteria
Facility-Scoped Tag Sets and Resident Smart Defaults
Given I am a logged-in Snapshot Aide at Facility A And Facility A has a configured quick-tag set And Resident R has care plan smart defaults When I open Resident R’s RoleView card Then I see only Facility A’s configured quick-tags And the resident’s smart default tags appear in the first row And tag order matches facility configuration And no more than 12 quick-tags display without scrolling And updates to the facility tag set or resident care plan reflect in the UI within 5 minutes of publish
One-Tap Tag Save with Haptic Confirmation
Given network connectivity is available When I tap a quick-tag Then a new entry is created and time-stamped to the server within 2 seconds And I receive haptic feedback within 150 ms And the UI displays a Saved confirmation for at least 1 second And the entry maps to the correct digest category per tag configuration And duplicate taps within 2 seconds result in a single saved entry And an Undo action is available for 5 seconds to remove the entry
Contextual Voice-to-Text Prompts
Given I initiate voice capture from a resident’s card When the microphone is activated Then three context prompts appear based on the selected tag within 300 ms And I can dictate up to 60 seconds of audio And transcription returns within 3 seconds after speech ends when online And when offline the audio note is queued and transcribed automatically on sync And the transcribed text is inserted into the note field associated with the selected tag And I can accept or retry the transcription with a single tap
Photo Linkage with Auto-Blur and Consent Compliance
Given I am in the tagging flow for a resident When I capture or attach a photo to the entry Then the photo is linked to the entry immediately And auto-blur is applied to faces of non-consenting individuals per the facility consent list before the image is viewable or shareable And processing completes within 2 seconds for images up to 12 MP And an Audit badge is added if unrecognized faces are detected And if auto-blur fails the image is withheld from digest with a non-blocking warning and a Retry option
Offline Queueing and Sync with Conflict Resolution
Given the device is offline When I tap a quick-tag or save a voice note Then the entry is stored locally with its original creation timestamp and a Queued badge And haptic feedback triggers within 150 ms And I remain in flow without modal interruptions And when connectivity is restored queued items sync automatically within 30 seconds And if the server has a newer conflicting entry for the same resident and tag within a 5-minute window Then a conflict sheet appears within 10 seconds allowing Keep Both (separate timestamps) or Merge Notes (default selection)
Lightweight Error States and Retry Logic
Given a transient error occurs during save or sync When the operation fails Then the system retries up to 3 times with exponential backoff starting at 1 second And if still failing a compact inline error appears with Tap to Retry And no data is lost from local storage And a successful retry clears the error and removes the Queued badge automatically And failures are logged with timestamp, user ID, resident ID, and error code
Role-Scoped Visibility and Actions for Snapshot Aides
Given my role is Snapshot Aide When I open a resident’s RoleView card Then quick-tag buttons and voice-to-text capture prompts are visible and interactive And when my role is Shift Relay Lead or Privacy Steward Then quick-tags and capture prompts are hidden or read-only and I cannot create entries And server-side enforcement rejects create requests from non-Aide roles with a 403 response And role changes take effect on the next card load without app restart
Shift Relay Approvals & Team Notes Panel
"As a Shift Relay Lead, I want an approvals and notes panel on each card so that I can ensure quality and coordinate handoffs before updates reach families."
Description

Surfaces an approvals queue and inline team notes directly on cards for Shift Relay Leads. Allows batch approve/return for edit, quick edits to captions/tags, @mentions with notifications, and escalation flags for RN review. Displays provenance (author, timestamp, device) and pre-send visibility summary (which families will receive). Enforces role-based edit rights and records an audit trail of changes. Integrates with digest scheduling to prioritize items blocking outbound summaries.

Acceptance Criteria
Lead-Only Approvals Panel
Given a user authenticated as Shift Relay Lead, When they open a RoleView card with at least one pending item, Then an Approvals panel is displayed inline on the card listing the pending items with a visible count. Given a user without the Shift Relay Lead role, When they open the same card, Then the Approvals panel is not displayed. Given a RoleView card with no pending items, When a Shift Relay Lead opens it, Then the Approvals panel renders a collapsed "No pending items" state within 1 second of card load.
Batch Approve and Return for Edit
Given a Shift Relay Lead selects two or more pending items in the Approvals panel, When they click Approve, Then each selected item’s status changes to Approved, the items are removed from the queue, and the action completes within 2 seconds per 10 items. Given a Shift Relay Lead selects one or more pending items, When they click Return for Edit and optionally add a note, Then each item’s status changes to Needs Edit, the note is attached to the item’s team notes, and the original author is notified. Given any selected item was actioned by another user during the last 5 seconds, When the batch action runs, Then that item is skipped with a conflict message, and the remaining items are processed successfully.
Inline Quick Edits with Role-Based Rights
Given a pending item on a RoleView card, When a Shift Relay Lead clicks the caption or tags, Then an inline editor opens allowing edits to caption text and tags, and Save commits the changes without leaving the card. Given a user who is not a Shift Relay Lead, When they view the same fields, Then the fields are read-only and the inline editor cannot be opened. Given the Shift Relay Lead saves edits, When the page refreshes or the card is reopened, Then the updated caption and tags persist and are reflected in the pre-send visibility summary.
Team Notes: @Mentions and Escalations to RN
Given the team notes composer, When a Shift Relay Lead types @ and selects a colleague from the suggestion list and posts the note, Then the mentioned user receives an in-app notification with a deep link to the card within 10 seconds. Given a note with an @mention, When the mentioned user opens the card via the notification, Then the note is highlighted and the notification is marked read. Given a pending item requires clinical review, When the Shift Relay Lead toggles Escalate to RN in the panel, Then the item is flagged as Escalated, an RN user receives a notification, and the RN review queue displays the item. Given an item is escalated, When an RN marks it Reviewed, Then the Escalated flag clears and the item’s status remains otherwise unchanged.
Provenance and Pre-Send Visibility Summary
Given a RoleView card, When it renders for a Shift Relay Lead, Then the card displays the item’s author name, original capture timestamp in facility local time, and capture device identifier. Given current consent and tagging rules, When the card is viewed, Then a pre-send visibility summary shows the number of recipient families and their names who will receive the item on the next digest. Given the Shift Relay Lead edits tags or captions that affect audience rules, When they save, Then the pre-send visibility summary recalculates immediately to reflect the new recipient list.
Immutable Audit Trail for Approvals, Returns, Edits, and Escalations
Given any of the following actions occur on a card—Approve, Return for Edit, Caption edit, Tag edit, Escalate to RN, RN Reviewed—When the action is completed, Then an audit log entry is written recording actor user ID, role, action type, timestamp (UTC), previous values, new values, and device ID. Given an audit log entry is created, When queried by an authorized role (Privacy Steward or Administrator), Then the entry is retrievable, read-only, and time-ordered relative to other entries. Given an audit log entry exists, When a non-Administrator attempts to modify or delete it via UI or API, Then the operation is rejected and the original entry remains unchanged.
Digest Scheduling Prioritization of Blocking Items
Given the facility has a configured digest schedule, When a pending item on a card is due to be included in the next outbound digest, Then the Approvals panel marks the item as Blocking Digest and pins it to the top of the queue. Given a Blocking Digest item is approved, When the queue refreshes, Then the blocking indicator is removed and the item is no longer pinned. Given the digest schedule is updated, When the card is refreshed, Then the set of items marked Blocking Digest recalculates to match the next scheduled send, and the count aligns with the digest engine’s pending count.
Consent Scope Badges & Audit Flags
"As a Privacy Steward, I want consent badges and audit flags on cards so that I can quickly spot and resolve compliance risks before anything is shared."
Description

Displays consent scope badges (e.g., Photo: Allowed; Voice: Restricted; Family A only) and real-time audit flags (missing consent, conflicting tags, unblurred by exception) for Privacy Stewards and authorized roles. Provides in-card links to resident consent profiles, resolution actions (request consent update, mask additional faces), and rationale capture for overrides with justification. Ensures badges reflect the current policy cache and update on sync. Integrates with compliance export and logs all privacy-relevant actions for review.

Acceptance Criteria
Role-Based Visibility of Consent Badges and Audit Flags
Given a Privacy Steward is authenticated and opens a RoleView Card for Resident R When the card renders Then the card shows consent scope badges for Photo, Voice, and Audience matching the current policy cache for Resident R And the card shows any active audit flags for Resident R And a Snapshot Aide viewing the same card does not see consent badges or audit flags And a user without privacy_view permission accessing the badges/flags endpoint receives HTTP 403 with no badge/flag data And a Shift Relay Lead granted privacy_view permission sees the same badges and flags as a Privacy Steward
Real-Time Consent Violation Flagging on Content Capture
Given Resident R has Photo: Restricted in the policy cache And a Snapshot Aide posts a photo update tagging Resident R When the update is saved Then an audit flag "Photo capture against restriction" appears on the card within 2 seconds And the flag details include resident_id, card_id, content_id, policy_version, and detected_violation=photo_restricted And Resident R's face(s) in the photo are auto-blurred And the Photo badge remains "Restricted" And if the update is tagged to share with Family A while Resident R audience is "Family B only" Then an audit flag "Conflicting audience tag" is created within 2 seconds
In-Card Consent Profile Deep Link
Given a Privacy Steward views a RoleView Card for Resident R When they tap "Consent Profile" Then the resident's consent profile opens in-card within 1 second And it displays last_updated timestamp and policy_version And the displayed policy_version matches the version shown on the badges And unauthorized roles do not see the "Consent Profile" link And if the device is offline, tapping the link opens the cached profile with a visible "Sync pending" indicator
Resolution Actions and Override Rationale Capture
Given a card displays an audit flag requiring attention (e.g., missing consent, conflicting tags, unblurred by exception) When a Privacy Steward selects "Override and proceed" Then a justification text field is required with a minimum of 10 characters before submission is enabled And on submit, the system logs action_type=override, reason_text, user_id, resident_id, card_id, content_id, policy_version, timestamp_utc And the flag status changes to Resolved with resolution_type=override and the justification is visible to Privacy Stewards And when "Mask additional faces" is selected, the selected faces are blurred within 2 seconds and the related flag is cleared And when "Request consent update" is selected, a consent update request is queued and the card shows a "Pending Update" banner
Policy Cache Sync and Badge Refresh
Given the central consent policy for Resident R changes from Photo: Allowed to Photo: Restricted And the device completes a successful policy sync When a Privacy Steward opens a RoleView Card for Resident R after sync Then the Photo badge updates to "Restricted" within 60 seconds of sync completion And any previously non-compliant content on the card is re-evaluated and appropriate audit flags are generated And the badge shows "Synced at <timestamp>" matching the device policy cache timestamp And if the device is offline, the badge shows "Last synced <timestamp>" and does not indicate current until the next successful sync
Compliance Export Includes Privacy Badges, Flags, and Actions
Given an authorized user requests a compliance export for a date range including the card When the export is generated in CSV and JSON formats Then each privacy-relevant event (badge state at capture, audit flags, resolutions, overrides, face masking actions, consent update requests) appears as a record with fields: event_id, event_type, resident_id, card_id, content_id, actor_id, actor_role, policy_version, event_timestamp_utc, details And the number of exported records equals the number of events in the audit log for the selected range And values in the export match the corresponding audit log entries exactly And export generation completes within 30 seconds for up to 10,000 events
Immutable Privacy Action Logging
Given any privacy-relevant action occurs on a RoleView Card (view consent profile, create flag, resolve flag, override, mask faces, request consent update) When the action completes Then an audit log entry is persisted with event_id (UUID), event_type, resident_id, card_id, content_id (if applicable), actor_id, actor_role, policy_version, timestamp_utc, reason_text (if provided), before_state, after_state And the log entry is immutable; users cannot edit or delete entries, and any redaction creates a new append-only redaction event linked to the original And audit logs are queryable by resident_id, actor_id, date range, and event_type and return results within 2 seconds for up to 10,000 entries And logs are retained for at least 365 days
Cross-Role Access Control & Data Redaction
"As an Administrator, I want strict role-based access and automatic redaction so that sensitive details remain protected while staff can still do their jobs efficiently."
Description

Enforces fine-grained RBAC/ABAC so that sensitive fields, media, and actions are visible only to authorized roles. Implements server-validated policy checks with signed tokens, field-level redaction in API responses, and on-device guards to prevent UI exposure. Includes secure fallbacks (e.g., blurred media thumbnails, redacted captions) and denies actions gracefully with clear messaging. Provides comprehensive audit logging of access decisions, unit/contract tests for policy rules, and performance-conscious caching with automatic invalidation on role or consent changes.

Acceptance Criteria
Server-Validated Field-Level Redaction by Role
Given a Snapshot Aide with a valid signed token lacking the view_sensitive claim When requesting a resident’s RoleView Card via the API Then the API returns 200 with only non-sensitive fields and redacted placeholders for restricted fields And the response contains no media download URLs for restricted items Given a Shift Relay Lead with the view_sensitive claim When requesting the same card via the API Then allowed sensitive fields are present and no redacted placeholders are returned for those fields Given a request with a tampered or unsigned token When the server validates the token Then the request is rejected with 401 and no resource data is returned
On-Device Guards Prevent Unauthorized UI Exposure
Given a Snapshot Aide lacking the approve_updates permission When viewing a RoleView Card Then the Approve control is not rendered and cannot be triggered via accessibility focus, automation, or deep links Given the same user opens a deep link to approve an update When the app processes the link Then a permission error is displayed and no approve API call is made Given a Privacy Steward without the capture_media permission When interacting with capture gestures on the card Then capture controls and prompts do not appear
Consent-Based Media Redaction and Auto-Blur
Given media contains a face without recorded consent When generating the thumbnail Then non-consenting faces are blurred to an effective pixelation of at least 24x24 per face region Given media is consent-restricted to family-only When viewed by a Snapshot Aide Then the thumbnail is blurred and the caption is replaced with "Redacted by privacy policy" Given consent for a depicted person is revoked When the card is refreshed Then any previously cached clear thumbnails are purged and blurred versions are shown within 5 seconds across the device
Graceful Denial Messaging for Restricted Actions
Given a user attempts a restricted action (e.g., approve, view_sensitive) When the policy denies the action Then the app shows a non-technical message explaining the restriction and a suggested next step, localized to the device language Given the denial message is displayed When tested with a screen reader Then the message and the dismiss button are announced with appropriate labels and focus order Given a denied action occurs When inspecting the associated API response Then no sensitive fields are included in the response body or error payload
Comprehensive Audit Logging of Access Decisions
Given any policy allow or deny decision is made When the API returns a response Then an audit log entry is recorded with timestamp, actor_id, role, resource_id, action, policy_id, decision, reason_code, tenant_id, and request_id Given a bulk fetch of multiple cards When decisions are evaluated Then a separate audit entry exists per resource decision Given the log retention policy is enforced When querying decision logs at 365 days Then decision records are retrievable and unaltered
Caching Performance and Auto-Invalidation on Role/Consent Changes
Given a user requests the same card within the cache TTL When issuing a subsequent request Then the policy decision is served from cache and policy-layer latency is under 100 ms Given a role change or consent update occurs When the change is committed Then all relevant caches are invalidated and the next request reflects the new policy within 5 seconds across services and devices Given an expired or revoked token is presented When a cached allow decision exists Then the request is denied with 401 and no cached allow is reused
Policy Rule Unit Tests and API Contract Tests
Given the policy rule set When running unit tests in CI Then at least 95% branch coverage of allow/deny paths is reported for the policy module Given API redaction rules When contract tests run against redaction endpoints Then responses include required redaction placeholders for restricted fields and exclude disallowed fields Given a new or modified policy rule is merged When the regression suite runs in CI Then the pipeline fails if any previously passing redaction or denial tests regress
Card Template Console & Usage Telemetry
"As a Facility Administrator, I want to configure card layouts by role and monitor usage so that I can optimize staff workflows and maintain compliance."
Description

Delivers an admin console to manage per-role card templates, action ordering, labels, and prompts with versioning and staged rollout by facility. Supports remote config updates, safe rollback, and feature flags for A/B testing card variants. Collects privacy-preserving telemetry on card interaction rates, time-to-complete, approval turnaround, and error trends to guide optimization. Exposes dashboards and exports, and integrates with alerting when regressions or compliance anomalies appear.

Acceptance Criteria
Admin Publishes Versioned Role Card Template with Staged Rollout
Given an Admin with Template Manager permission, When they create a new role template with ordered actions, labels, and prompts and click Publish, Then the system saves it as a new version with required author, timestamp, and change note. Given the Admin selects Facility "Oak Ridge" with a staged rollout of 10% -> 50% -> 100%, When publishing to 10%, Then 10%±1% of eligible users in that facility and role receive the new version within 10 minutes and assignment is random and sticky per user. Given users outside the target facility or role, When the version is published, Then they continue to see their prior template version. Given the Admin initiates Rollback, When confirmed, Then all targeted users revert to the previous stable version within 10 minutes and the audit log records actor, reason, from/to versions, and timestamp. Given Preview-as-Role is used, When the Admin previews the template for each supported role, Then the card renders role-specific controls and badges and performs no writes to production data. Given publish validation, When required fields are missing or invalid, Then the Publish action is blocked with field-level errors and cannot proceed.
Remote Config Update Propagates and Falls Back Safely
Given a non-versioned configuration change (e.g., label text), When published, Then 95th percentile clients fetch and apply the new config within 5 minutes and report applied config/version in heartbeat. Given a client is offline, When it reconnects, Then it fetches the latest config within 60 seconds and applies atomically. Given an unknown or missing config key on the client, When processing, Then the client uses the documented default without user-facing error. Given client-side safeguard is enabled, When client error rate rises >5% over 15 minutes after a config change, Then the client reverts to the last good config and emits a rollback event. Given config service/Cdn outage, When clients attempt fetch, Then they continue operating with cached config for up to 24 hours and retry with exponential backoff.
A/B Test Flag Assigns and Tracks Card Variants
Given two variants A and B of a role card template, When the Admin sets a 50/50 split for a facility, Then eligible users are assigned deterministically and stickily to a variant for 30 days or until the test ends. Given the Admin applies an override for a user/facility/role, When saved, Then the override takes effect within 5 minutes and is reflected in assignment logs. Given the experiment is active, When telemetry events are emitted, Then each event includes template version and variant id for attribution. Given the Admin pauses variant B, When saved, Then new sessions route only to variant A within 5 minutes and existing B users migrate on next app start. Given the Admin ends the test and promotes a winner, When confirmed, Then all users receive the promoted version within 10 minutes and the experiment is archived with results and cohort sizes.
Telemetry Captures Privacy-Preserving Interaction Metrics
Given users open, act on, submit, and approve role cards, When events are sent, Then interaction rate, time-to-complete (open→submit), approval turnaround, and error events are captured with timestamps and role/facility/template version/variant identifiers. Given privacy requirements, When telemetry is transmitted, Then no resident names, images, audio, free-text content, or phone numbers are included; user/device ids are salted-hashed and rotated every 30 days. Given high load (>10k events/min/facility), When buffering occurs, Then 99% of events are delivered within 2 minutes with at-least-once semantics and idempotent deduplication by event id. Given data governance policy, When data is stored, Then it is encrypted at rest, retained for 13 months, and deletable per facility request within 7 days. Given a facility disables telemetry, When the setting is applied, Then clients cease analytics within 10 minutes and dashboards display an opt-out banner for that scope.
Dashboards and Exports Provide Version and Variant Insights
Given an Admin opens Analytics, When filtering by date range (last 30 days), facility, role, template version, and variant, Then charts for interaction rate, time-to-complete p50/p95, approval turnaround p50/p95, and error rate render within 3 seconds p95. Given the Admin clicks Export, When selecting CSV with current filters, Then a CSV with a data dictionary and UTC timestamps is generated within 60 seconds and available for download or delivered to the configured S3 bucket. Given access control, When a non-Admin attempts to view dashboards or exports, Then access is denied with 403 and the attempt is logged with user id, time, and resource. Given Metrics API is enabled, When an OAuth2 client queries with valid scopes and filters, Then the API returns results within 2 seconds p95 and enforces 60 requests/min rate limit per client.
Alerts Fire on Regressions and Compliance Anomalies
Given baseline metrics for a facility/role/version, When time-to-complete p95 increases by ≥20% over a 1-hour window versus 7-day baseline, Then a Regression alert is created, routed to Slack/email/on-call, and includes links to the impacted dashboard. Given error rate exceeds 3% for 15 consecutive minutes for any template version, When detected, Then an alert is fired and deduplicated to one notification per 30 minutes until resolved. Given a compliance anomaly (e.g., approvals outstanding >48h or a template published without required consent badges), When detected, Then an alert is created and escalates if unacknowledged after 15 minutes. Given an active staged rollout, When a Regression or Error alert triggers, Then the system automatically halts further rollout steps and notifies the Admin. Given maintenance windows, When within a defined window, Then non-critical alerts are suppressed and a post-window summary is sent instead.

ShareSafe Mode

One-tap toggle produces a family-safe version of a card that automatically omits staff-only sections (internal notes, room numbers) and respects consent scopes and incident freezes. Enables confident print/share without manual redaction, protecting dignity while keeping families informed.

Requirements

One-Tap ShareSafe Toggle
"As a caregiver, I want a single toggle to make a card family-safe so that I can share updates quickly without worrying about exposing internal or sensitive information."
Description

Adds a prominent, accessible toggle on each care card to instantly generate a family-safe version that hides staff-only sections and sensitive details. The toggle state is persisted per card and obeys site-level defaults and unit policies. When activated, ShareSafe produces a derived view optimized for quick sharing or printing without manual redaction, ensuring consistent compliance while minimizing caregiver effort. The control is available in compose, review, and history views, supports offline use with on-device processing, and clearly labels the card as ShareSafe in the UI.

Acceptance Criteria
Toggle Presence and Derived View Labeling
Given a care card is open in Compose, When the user toggles ShareSafe On, Then a derived ShareSafe view replaces the standard view, a "ShareSafe" badge is shown in the header, and the view renders within 500 ms on supported devices. Given a care card is open in Review or History, When the user toggles ShareSafe On, Then the same behavior occurs. Given ShareSafe is toggled Off, When the user views the card, Then the standard view is shown and underlying data remains unmodified.
Accessibility Compliance for ShareSafe Toggle
Given keyboard-only navigation, When focus reaches the ShareSafe toggle, Then it is operable with Space and Enter and shows a visible focus indicator. Given a screen reader is active, When the toggle is announced, Then its accessible name is "ShareSafe" and its state is announced as "On" or "Off". Given standard contrast settings, When rendered, Then the toggle’s text/icon and state indicator meet WCAG 2.1 AA contrast ratio of at least 4.5:1. Given OS Reduced Motion is enabled, When toggling ShareSafe, Then any animation is disabled or completes in under 200 ms.
Sensitive Fields Omission and Policy Enforcement
Given a card contains staff-only fields (e.g., internal notes, room number, staff tags) and ShareSafe is On, When the derived view is shown, Then those fields are omitted from the view and from any share/print export. Given a unit policy marks additional fields as staff-only, When ShareSafe is On, Then those policy-defined fields are also omitted. Given an incident freeze is active on the card, When ShareSafe is On, Then incident-related content is omitted and a non-shareable banner "Some content hidden due to incident review" is displayed. Given consent scopes limit sharing of specific data types, When ShareSafe is On, Then restricted data types are omitted from the derived view and exports.
Consent-Based Media Redaction in ShareSafe
Given a photo on the card includes a person without sharing consent, When ShareSafe is On, Then that person’s face is blurred on-device before display/export; if face detection confidence is below 0.8, Then the entire photo is omitted. Given an audio-to-text note contains a non-consenting person’s name, When ShareSafe is On, Then the name is replaced with "[redacted]" in the derived view and exports. Given a photo includes only consenting individuals, When ShareSafe is On, Then the photo is shown unaltered in the derived view and exports.
State Persistence and Default Policies
Given a caregiver enables ShareSafe on a specific card, When they navigate away and return on the same device, Then the ShareSafe state for that card remains as last set. Given the same card is opened on another signed-in device, When data sync completes, Then the ShareSafe state reflects the last saved state for that card within 60 seconds of connectivity. Given a site-level default of ShareSafe On for new cards in a unit, When a new card is created in that unit, Then the toggle initializes to On. Given a unit policy locks ShareSafe On or Off, When viewing cards in that unit, Then the toggle reflects the locked state and is disabled with an info tooltip explaining the policy.
Offline ShareSafe Generation
Given the device is offline, When the user toggles ShareSafe On, Then the derived view renders using on-device processing without showing network error messaging. Given the device is offline and consent/policy data is unavailable for an element, When ShareSafe is On, Then the element is treated as restricted and hidden, and a non-blocking banner "Some content hidden pending sync" is displayed. Given connectivity is restored, When the app syncs, Then previously hidden elements become visible within 10 seconds only if policies/consents permit them.
ShareSafe Print/Share Output
Given ShareSafe is On, When the user initiates Print or Share, Then the generated output excludes staff-only and restricted content, includes a visible "ShareSafe" label/watermark, and displays only consent-allowed resident identifiers. Given a typical card with up to 10 photos and 500 words, When generating the ShareSafe export, Then the file is produced within 2 seconds on supported devices. Given the ShareSafe export is reviewed, When checking for sensitive fields, Then no internal notes, room numbers, or redacted names appear in the output.
Consent-Aware Redaction Engine
"As an administrator, I want ShareSafe to automatically respect consent and privacy rules so that families only see appropriate, compliant information."
Description

Implements a rules-driven engine that applies resident consent scopes, incident holds, and privacy policies to automatically omit or transform sensitive content. The engine removes staff-only notes, room numbers, internal tags, and non-consenting faces via auto-blur, and suppresses mentions of other residents lacking consent. It handles text, images, and attachments, performs on-device where possible, and falls back to secure server processing when needed. Outputs include a sanitized payload plus a machine-readable map of redactions to drive UI previews and audits.

Acceptance Criteria
ShareSafe Toggle Omits Staff-Only Fields
- Given a care card containing staff-only fields (internal notes, room number, internal tags), When ShareSafe Mode is toggled on, Then the ShareSafe payload excludes these fields from the JSON output and print view. - And the visible layout compacts without leaving empty labels or gaps. - And automated tests confirm the excluded fields are absent by schema path: card.internalNotes, card.roomNumber, card.internalTags[*]. - And an audit record is written with redaction entries for each removed field, including ruleId and fieldPath. - And toggling ShareSafe Mode off restores full content for authorized staff views without loss of data.
Face Auto-Blur Respects Consent
- Given an image attached to a card containing detected faces and resident consent flags, When ShareSafe content is generated, Then faces of individuals without share consent are blurred with a minimum 20px radius (or equivalent strength at image resolution). - And faces of the primary resident with share consent remain unblurred unless an incident hold is active. - And the detection threshold is confidence >= 0.70; faces below threshold are left unblurred and logged as "undetected". - And the redaction map includes bounding boxes (x,y,w,h), faceId, and ruleId for each blurred face. - And on a validation set, precision and recall for non-consenting face blur are each >= 0.90.
Suppress Mentions of Non-Consenting Residents in Text and Attachments
- Given card text, captions, and attachment filenames that reference other residents, When generating ShareSafe, Then any reference to a resident without share consent is replaced with the neutral phrase "another resident". - And references to consenting residents are retained. - And replacements preserve sentence grammar and do not exceed +/- 2 characters in surrounding whitespace or punctuation changes. - And the redaction map records each replacement with fieldPath, originalStartIndex, originalEndIndex, replacementText, and ruleId. - And unit tests cover cases with first/last names, nicknames, room-based identifiers, and pronouns.
Incident Hold Blocks or Masks Sharing
- Given an active incident hold on a resident, card, or attachment, When ShareSafe is requested, Then held content is not present in the ShareSafe payload. - And if the hold scope is "card", Then the response includes shareBlocked=true with holdReasonCode and no content body. - And if the hold scope is "field" or "attachment", Then only those elements are redacted and replaced with "temporarily unavailable". - And an audit log entry is created containing holdId, scope, actorId, and timestamp. - And the UI can render a non-error state using the returned flags and redaction map.
Machine-Readable Redaction Map Output
- Given any redactions performed, When the sanitized payload is returned, Then a redactionMap array is included containing entries with: ruleId, type (field|textSpan|face|attachment), locator (fieldPath or attachmentId), and position data (charRange or boundingBox). - And each entry includes a reason code (consent, staffOnly, incidentHold, privacyPolicy) and timestamp. - And the redaction map allows the UI to highlight redacted regions in a preview without requiring original content values. - And the map passes JSON schema validation and is <= 50KB for typical cards.
On-Device First, Secure Server Fallback
- Given the device has the redaction model and sufficient resources, When ShareSafe is generated, Then processing occurs on-device and no media leaves the device. - And when on-device prerequisites are not met or processing exceeds 2s, Then processing securely falls back to the server using TLS 1.2+ with certificate pinning. - And server-side processing deletes transient media within 15 minutes and stores only the sanitized payload and redaction map. - And the response metadata includes processingMode (onDevice|server), processingDurationMs, and fallbackReason (if any). - And error conditions return a deterministic error code without exposing sensitive content.
Structure Preservation and Performance SLAs
- Given a card with <= 1,000 words of text, up to 5 images (<= 5MB each), and up to 3 attachments (PDF/doc <= 5MB each), When ShareSafe is generated, Then the sanitized payload preserves original field ordering and schema, with only redacted fields removed or transformed. - And cryptographic hashes (SHA-256) of non-redacted attachments remain unchanged between original and ShareSafe versions. - And processing completes within 2,000ms on-device or 4,000ms via server for the specified payload sizes, measured p95 over 200 trials. - And unit tests verify no leakage of staff-only values in the sanitized payload or print view. - And accessibility alt text is updated to reflect redactions without revealing sensitive content.
Staff-Only Field Segmentation
"As a caregiver, I want clear staff-only fields separated from family-visible content so that I can enter information confidently without risking accidental sharing."
Description

Extends the data model and composer to explicitly tag fields as staff-only or family-visible, enabling deterministic filtering during ShareSafe generation. Introduces schema flags for room number, internal notes, staff comments, and operational metadata, with migrations and backward compatibility for existing cards. The composer enforces correct field placement with clear labels and guardrails, reducing the risk of accidental disclosure and simplifying the redaction logic.

Acceptance Criteria
Visibility Flags on Sensitive Fields
Given a card containing room_number, internal_notes, staff_comments, and operational_metadata fields When the card is saved via API or UI Then each field persists a visibility value of STAFF_ONLY or FAMILY_VISIBLE And the default visibility is STAFF_ONLY for room_number, internal_notes, staff_comments, and operational_metadata And the default visibility is FAMILY_VISIBLE for standard family-facing fields (e.g., title, caption, photos, activities) And authorized staff API reads include the visibility attribute per field And attempts to set a sensitive field from STAFF_ONLY to FAMILY_VISIBLE without Admin role are rejected with 403 and audited
Composer Guardrails for Field Placement
Given a staff user composes or edits a card in the UI When they focus a family-visible input area Then a visible badge and helper text indicate Family-visible content And pasting content matching room number patterns (e.g., Rm 214, #214) into a family-visible field prompts a warning and offers Move to Staff Notes; accepting moves the content; declining keeps focus but blocks save until removed And dragging or converting a staff-only field to family-visible is blocked with an explanatory message And section headers clearly separate Family-visible vs Staff-only with WCAG AA contrast And the form cannot be submitted if any staff-only content is present in family-visible fields
Deterministic ShareSafe Filtering
Given a card with a mix of FAMILY_VISIBLE and STAFF_ONLY fields When ShareSafe mode is toggled in UI or API is called with projection=family Then only FAMILY_VISIBLE fields are rendered or returned And no placeholders or empty containers remain for removed staff-only fields And ordering of remaining fields matches the original card order And repeated generations with identical inputs produce byte-identical payloads And server-side processing time is ≤ 300 ms at P95 for cards with up to 30 fields
Legacy Data Migration and Defaults
Given a database snapshot from a pre-segmentation version When the migration script runs Then existing fields are assigned visibility per mapping: room_number, internal_notes, staff_comments, operational_metadata => STAFF_ONLY; known family-facing fields => FAMILY_VISIBLE; unknown custom fields => FAMILY_VISIBLE And zero data loss occurs (record counts before and after match) And the migration is idempotent (re-running makes no additional changes) And the migration completes within 5 minutes for 100k cards on staging hardware And a migration report is produced with counts per assignment and any exceptions
Backward-Compatible API Responses
Given a legacy staff client requests a card without projection parameter When the API responds Then response schemas remain backward-compatible (existing field paths unchanged; visibility metadata included as additive attributes) And clients that ignore visibility attributes still receive full content when authenticated as staff And family-authenticated clients always receive responses filtered to omit STAFF_ONLY fields without schema breaks And API versioning headers are present and correct
Role-Based Access Respects Visibility
Given a family-authenticated token requests GET /cards/{id} When the card contains STAFF_ONLY fields Then those fields are omitted from the response payload And attempts to POST or PUT STAFF_ONLY fields with a family token return 403 with an error code VISIBILITY_FORBIDDEN And the same operations with a staff token succeed per permissions And all access decisions are logged with user id, card id, field keys, and outcome
Incident Freeze Enforcement
"As a compliance lead, I want cards under incident freeze to be unsharable so that we maintain privacy and investigative integrity."
Description

Integrates incident and investigation states into the ShareSafe pipeline to automatically block sharing or exporting of cards and media under a freeze. Displays non-revealing explanations and guidance to staff, logs attempted shares, and provides admin-only override paths with justification. The enforcement applies uniformly across in-app sharing, print/export, and digests, preventing premature disclosure while preserving evidence and compliance.

Acceptance Criteria
In-App Share Blocked for Frozen Card
Given a card has Incident Freeze = Active When a caregiver toggles ShareSafe and attempts to share via any in-app channel (family thread, direct share, print, copy link) Then the action is prevented and no share artifact (message, link, PDF) is created And a non-revealing banner appears with generic guidance and a policy link And an audit event "share_blocked_freeze" is recorded with userId, role, residentId, cardId, mediaIds, channel, timestamp, and deviceId And the blocked attempt appears in the activity log within 5 seconds
Uniform Enforcement Across All Share Channels
Given any card or media is under Incident Freeze When a scheduled family digest is generated Then frozen items are omitted without placeholders, and families receive no indication of their existence And when a PDF export/print is requested for a range including frozen items Then frozen items are fully excluded and the requester sees a non-revealing summary that some items were not included And when a bulk export/media download is requested Then requests containing frozen items are blocked or the frozen items are excluded; no file includes frozen content And a single audit entry per job records counts of items omitted and identifiers of frozen content
Admin Override with Justification and Audit
Given a user has Admin role with Incident Override permission When they initiate sharing of frozen content Then an override flow is required with mandatory free-text justification (minimum 20 characters) and confirmation And the override applies only to the specific attempt and items selected; no global unfreeze occurs And an audit event "share_override_freeze" records adminId, justification, affected items, channel, timestamp, and reason code And a notification is sent to the compliance/audit inbox within 1 minute And when a non-admin attempts an override Then access is denied and the attempt is logged
Non-Revealing Staff Messaging
Given a share or export is blocked due to Incident Freeze When the staff-facing message is displayed Then the text contains no incident names, resident medical details, investigation identifiers, or incident timestamps And the message follows an approved generic template and includes a guidance link And the message is localized for supported languages and passes accessibility checks (readable by screen readers, sufficient contrast) And no blocked-state details appear in any previews, thumbnails, or generated artifacts
Server-Side Enforcement and API Hard Stop
Given a client or third-party integration requests a share/export that includes frozen content When the server processes the request Then it returns HTTP 423 Locked with error code FREEZE_ENFORCED and does not queue any job And the request/response are logged with correlationId, user/app identity, cardId/mediaIds, and timestamp, excluding incident details And retries or elevated client permissions do not bypass the enforcement And when the request excludes frozen items Then the operation succeeds (200) and returns only unfrozen content
Mixed-Content Card with Frozen Media
Given a card contains multiple media and at least one media item is under Incident Freeze When ShareSafe share/export/digest is executed Then the entire card is excluded from family-visible outputs And a single non-revealing explanation is shown to staff indicating the card cannot be shared while an investigation is active And audit logs reference the cardId and specific frozen mediaIds that triggered exclusion And auto-blur and other processing are not applied to frozen media while the freeze is active
Safe Print and Export Pipeline
"As a caregiver, I want to print or export a ShareSafe version of a card so that I can hand updates to families without manual redaction or risk."
Description

Generates printable and shareable outputs (PDF/JPEG) from the ShareSafe view with all sensitive content removed, non-consenting faces blurred, and metadata scrubbed. Adds optional watermarking, ShareSafe badge, timestamp, and resident initials while excluding PHI like room numbers. Integrates with AirPrint and native share sheets, ensures no EXIF geolocation or hidden layers persist, and maintains consistent layout for quick handoffs to families.

Acceptance Criteria
Export ShareSafe Card to PDF/JPEG Without Sensitive Content
Given a completed ShareSafe card with internal notes, staff-only sections, and room numbers When the user exports to PDF and JPEG from the ShareSafe view Then the exported files exclude internal notes, staff-only sections, and room numbers And the content matches the visible ShareSafe view fields in order and formatting And the export completes within 3 seconds for a single-page card on a reference device And the JPEG single-page file size is ≤ 2 MB and the PDF is ≤ 3 MB without watermark enabled
Automatic Face Blurring for Non-Consenting Individuals
Given a photo on a ShareSafe card with multiple faces where some individuals lack consent or are marked unknown And the consent roster is up to date When exporting to PDF or JPEG Then faces of non-consenting and unknown individuals are obfuscated by pixelation blocks ≥ 16×16 px (at 1080p equivalent) or Gaussian blur of equivalent strength, scaled with resolution And faces of consenting residents remain unobscured And obfuscation is baked into the export (flattened) and cannot be removed by layer deletion
Metadata Scrubbing on All Exports
Given an exported PDF or JPEG from the ShareSafe view When inspecting the file with metadata tools (e.g., exiftool for JPEG, a PDF object inspector for PDF) Then no EXIF GPS, DateTimeOriginal, camera make/model, or user comment tags are present And no XMP/IPTC/custom metadata persist except minimal required format fields (e.g., page size) And PDFs are single-layered and flattened with no annotations or hidden layers And no embedded thumbnails or previews contain unblurred faces or sensitive content
Optional Watermark, ShareSafe Badge, Timestamp, and Resident Initials
Given watermarking controls are enabled in settings When exporting a ShareSafe card Then the ShareSafe badge is present in the header And the timestamp uses facility local time in ISO 8601 format (YYYY-MM-DD HH:MM) matching the card's last updated time And resident initials (e.g., "JD") are displayed while full names and room numbers are excluded And when watermark is ON, a diagonal "For Family Use Only" watermark appears at ~15% opacity across the page; when OFF, no watermark appears And all overlays (badge, timestamp, initials, watermark) are flattened into the export and not removable via layer editing
AirPrint and Native Share Sheet Integration
Given an iOS device with an AirPrint-capable printer on the same network When the user taps Print from the ShareSafe export screen Then the iOS Print sheet opens with a preview matching the export and the job prints successfully Given an iOS or Android device When the user taps Share from the ShareSafe export screen Then the native OS share sheet opens with the generated PDF/JPEG attached and no auxiliary files And recipient apps receive a flattened file with no EXIF GPS or hidden layers
Consistent Layout and Pagination Across Formats
Given a ShareSafe card containing text, photos, and captions that exceed one page When exporting to PDF and to multi-image JPEG (one image per page) Then the visual layout, fonts, and alignment match the on-screen ShareSafe view within ±2 px tolerance and consistent font weights And page breaks occur at the same content boundaries across PDF and JPEG And captions remain paired with their images with no truncation or orphaned elements And badge/timestamp/watermark positions are consistent across pages
Incident Freeze Enforcement During Export
Given a ShareSafe card flagged with an active incident freeze When a user attempts to export or print Then export and print actions are disabled and a notice states "Export disabled during incident review" And if export is invoked via a deep link or queued background job, the request is rejected and no file is created And when the freeze is lifted, export and print are re-enabled without requiring app restart
Audit Logging and Admin Policies
"As an administrator, I want audit trails and policy controls for ShareSafe so that I can enforce standards and demonstrate compliance."
Description

Captures immutable audit events for ShareSafe actions, including toggle activations, redaction outcomes, exports, and blocked attempts due to freezes or consent. Provides admin controls to set unit-level defaults (e.g., ShareSafe on by default), enforce mandatory ShareSafe for specified content types, and review usage analytics. Exposes secure log export for compliance review with retention and access controls aligned to organizational policies.

Acceptance Criteria
Audit Log: ShareSafe Toggle Events
Given an authenticated caregiver views a resident card, When they toggle ShareSafe from Off to On, Then an audit event is appended with fields [tenant_id, card_id, resident_id, unit_id, actor_id, actor_role, event_type=sharesafe_toggle, previous_state=off, new_state=on, timestamp_utc (ISO-8601), device_id, app_version, request_id, success=true] and contains no PHI payload. Given ShareSafe is On, When the caregiver toggles it Off, Then an audit event is appended with previous_state=on and new_state=off and the same required fields. Given the device is offline at the moment of the toggle, When connectivity is restored, Then the queued encrypted audit event is uploaded within 5 minutes and stored server-side with an ingestion_timestamp. Given an audit event is written, When queried via admin API, Then it is retrievable by request_id and card_id and cannot be updated or deleted via any API.
Audit Log: Redaction Outcomes and Blocked Attempts
Given ShareSafe rendering runs on a card, When auto-redaction completes, Then an audit event event_type=redaction_summary is appended including counts [fields_removed, faces_blurred, attachments_excluded], list of field keys removed (not values), policy_version, timestamp_utc, and contains no PHI payload. Given a caregiver attempts share/print/export while an incident freeze exists, When the action is initiated, Then the system blocks the action and appends event_type=share_blocked with block_reason=incident_freeze, attempted_channel, card_id, resident_id, actor_id, unit_id, timestamp_utc, success=false. Given a caregiver attempts share/print/export without required consent scope, When the action is initiated, Then the system blocks the action and appends event_type=share_blocked with block_reason=consent_scope and the same required identifiers.
Admin Policy: Unit-Level ShareSafe Default
Given an admin with Policy:Manage selects a unit, When they set "ShareSafe default = On" and Save, Then a policy_change audit event is appended with [unit_id, setting_key=sharesafe_default, before, after, actor_id, timestamp_utc]. Given the policy is active for a unit, When a new card is created in that unit, Then the card initializes with ShareSafe enabled and an event_type=policy_applied is appended linking the policy id and card_id. Given the policy is active, When a caregiver manually toggles ShareSafe Off on a newly created card, Then the action is allowed and an event_type=policy_override is appended with reason=user_toggle, actor_id, card_id, timestamp_utc.
Admin Policy: Mandatory ShareSafe by Content Type
Given an admin marks content types [photo, med_note, voice_note] as Require ShareSafe, When a caregiver attempts export/share/print of a matching card with ShareSafe Off, Then the action is blocked and event_type=policy_enforcement is appended with rule_id, block_reason=mandatory_sharesafe, attempted_channel, card_id, actor_id, timestamp_utc. Given a card matches a mandatory type, When the caregiver enables ShareSafe and retries export, Then the export succeeds and event_type=export_created is appended with [export_channel, export_format, record_count, policy_enforced=true]. Given a card does not match any mandatory type, When exported with ShareSafe Off, Then the export proceeds and event_type=export_created is appended with policy_enforced=false.
Usage Analytics: ShareSafe Adoption and Enforcement
Given audit events exist for the selected period, When an admin opens Analytics and filters by [date_range, unit_id], Then metrics display: total_toggles, percent_shared_with_sharesafe, blocked_attempts_by_reason, redaction_counts, exports_by_channel, and totals equal aggregations of underlying audit events for the filter (tolerance = 0). Given the analytics view is loaded, Then data freshness is <= 15 minutes since last ingested audit event and a "last updated" timestamp is visible. Given the admin clicks Export CSV, When the export completes, Then a downloadable CSV containing the filtered metrics is provided and event_type=analytics_export is appended with record_count and filter criteria. Given a user without Analytics permission requests the dashboard, When access is attempted, Then the request is denied (HTTP 403) and event_type=access_denied is appended with resource=analytics.
Secure Log Export, Retention, and Access Controls
Given a compliance admin with Log Export permission submits a request with filters [date_range, unit_ids, event_types], When processed, Then an export file is generated in NDJSON format with schema_version, and a SHA-256 checksum and detached Ed25519 signature are produced for integrity verification. Given the export is generated, When a download URL is issued, Then it is a pre-signed URL that expires in 24 hours, enforces TLS 1.2+, and each download attempt appends event_type=log_export_download with requester_id, ip_address (redacted per policy), user_agent hash, timestamp_utc. Given the organization retention policy is set to N days within [90, 1825], When events exceed N days, Then they are purged automatically and event_type=log_purge is appended with [range_start, range_end, purged_count, policy_id] and no event payloads are exposed. Given a retention value is changed, When the admin saves, Then MFA is required and event_type=policy_change is appended with before/after, actor_id, timestamp_utc, and only users with role Compliance:Manage can perform the change. Given a non-privileged user attempts log export, When the request is made, Then it is denied (HTTP 403) and event_type=access_denied is appended with resource=log_export.
Audit Log Immutability Verification
Given the audit store is operational, When any event is appended, Then it includes sequence_number (monotonic per tenant), previous_hash, and event_hash (SHA-256), forming a tamper-evident hash chain. Given the nightly verifier runs, When it scans a date range, Then it returns integrity_status=pass if there are no sequence gaps or hash mismatches; otherwise integrity_status=fail with first_bad_sequence and reason, and appends event_type=integrity_check_result. Given an event requires correction, When a compensating event is created, Then it references the original via correlation_id and no update/delete endpoint exists for individual audit events.
ShareSafe Preview with Redaction Reasons
"As a caregiver, I want to preview the ShareSafe version with clear reasons for redactions so that I can share confidently and fix issues before sending."
Description

Adds a side-by-side preview that highlights exactly what will be hidden or transformed in ShareSafe mode, with inline reason tags (e.g., consent, staff-only, incident). Caregivers can quickly verify and, when permitted, adjust content placement before sharing. The preview uses the redaction map from the engine, improves caregiver confidence, reduces errors, and shortens handoff time.

Acceptance Criteria
Side-by-Side ShareSafe Preview Rendering
Given a caregiver has an open care card and toggles ShareSafe Preview, When the preview loads, Then the screen renders Original and ShareSafe panes side-by-side with synchronized scroll. Given a card with redacted and transformed elements per the redaction map, When the ShareSafe pane renders, Then all redacted elements are visually hidden and all transformed elements display their transformation and no unflagged element is altered. Given a card containing up to 10 media items and 50 content elements, When ShareSafe Preview is opened on a device meeting minimum spec, Then the first paint completes within 1200 ms and input becomes responsive within 200 ms thereafter.
Inline Redaction Reasons Display
Given elements are hidden or transformed by ShareSafe, When a caregiver taps or hovers the indicator on that element in either pane, Then an inline reason tag appears showing canonical labels drawn from the redaction map. Given an element has multiple reasons, When its reasons are displayed, Then all applicable reasons are shown as distinct tags in a stable, alphabetical order. Given N elements are redacted or transformed, When the preview renders, Then exactly N elements display at least one reason tag and zero non-redacted elements display a reason tag.
Permitted Content Placement Adjustments
Given the caregiver has Edit Preview permission, When Edit Layout is entered from ShareSafe Preview, Then the caregiver can move eligible elements between sections or positions allowed by policy and cannot move ineligible elements. Given an eligible element is repositioned, When the caregiver drops it, Then the ShareSafe pane updates within 300 ms and the redaction map is re-evaluated for that element. Given changes have been made, When Undo or Reset is invoked, Then the layout reverts to the last saved or default state without residual tags or artifacts.
Enforcement of Non-Overridable Redactions
Given an element is locked by consent revocation, incident freeze, or policy lock, When a caregiver attempts to move, reveal, or edit it in preview, Then the action is blocked with a toast or inline message stating the lock reason and no change is applied. Given repeated attempts to override a locked element, When audited, Then each blocked attempt is recorded with user, timestamp, element ID, and lock reason. Given policy configuration prohibits overrides, When the preview is used, Then there exists no path that results in locked content becoming visible in the ShareSafe pane or shared artifact.
Share/Print Output Fidelity to Preview
Given a finalized ShareSafe Preview, When the caregiver taps Share or Print, Then the generated artifact’s visible content exactly matches the ShareSafe pane content for text equality and image redaction state. Given the artifact is generated, When metadata is inspected, Then no internal notes, room numbers, staff-only fields, or reason tags are included in the output. Given automated regression tests, When a baseline preview and output are compared, Then DOM/PDF snapshot comparison passes at 100% for structure and at >= 99% pixel similarity for images.
Performance, Accessibility, and Usability
Given the ShareSafe Preview is open, When navigated via keyboard alone, Then all actionable controls and redacted elements are reachable in a logical order and exposed with appropriate ARIA labels including reason tags. Given visual indicators are displayed, When evaluated for contrast, Then all redaction highlights and tags meet WCAG 2.1 AA contrast ratios. Given a typical session editing up to 20 elements, When monitored, Then memory usage of the preview stays below 200 MB and frame rate remains >= 30 fps during interactions on minimum spec devices.
Real-Time Updates and Error Handling for Redaction Map
Given the redaction map changes due to consent or incident updates while preview is open, When the change event is received, Then the ShareSafe pane updates within 2 seconds and a non-blocking banner indicates the update occurred. Given the redaction map is unavailable, invalid, or stale, When ShareSafe Preview is requested, Then the preview fails gracefully with an explanatory message, Share/Print is disabled, and no unreviewed content is shared. Given connectivity is lost during preview, When the connection is restored, Then the redaction map is re-fetched and the preview reconciles differences without duplications or missed redactions.

Audio Brief

Generates a concise, natural voice recap of the card for huddles or quick reviews, so teams can keep eyes up while listening. Also attaches to family digests when appropriate, improving accessibility for tech-light relatives and reducing after-hours clarification calls.

Requirements

Card Summarization to Speech
"As a caregiver, I want a concise spoken recap of each card so that I can review updates hands-free during huddles."
Description

Service that converts each care card into a concise spoken recap using domain-tuned summarization followed by natural text-to-speech. Inputs include card title, voice-to-text note, tags (mood, vitals), and follow-ups; excludes fields marked internal-only. Target duration 15–45 seconds with a consistent structure (resident, shift highlights, next steps). Real-time for short cards; background for longer ones. Outputs encrypted audio file, waveform data for scrubber, and a transcript. Provides graceful fallback to reading the raw note if summarization fails, ensuring reliability and hands-free reviews.

Acceptance Criteria
Concise, Structured Recap Generation
Given a care card with resident name, title, voice-to-text note, tags (mood, vitals), and follow-ups, with at least one field flagged internal-only When the summarization service generates the recap Then the recap includes resident name, shift highlights (1–3 sentences), and explicit next steps And it includes mood and key vitals if present And it excludes all content from fields flagged internal-only And it contains no content not present in the visible card fields
Duration and Pacing Compliance
Given a batch of representative care cards When audio recaps are generated Then 95% of audio durations are between 15 and 45 seconds And no audio duration exceeds 60 seconds And average speech rate is between 140 and 180 words per minute And leading and trailing silence per file are each ≤ 300 ms
Real-Time for Short Cards; Background for Long Cards
Given a short card with combined visible text ≤ 120 words When a recap is requested Then a playable audio URL is returned within 2 seconds p95 And transcript and waveform are available with the audio Given a long card with combined visible text > 120 words When a recap is requested Then the job is queued and a completion event is emitted within 2 minutes p95 And the generated audio quality and structure match short-card outputs
Output Artifacts and Security
Given a generated recap When outputs are stored and retrieved Then an encrypted audio file is produced and stored encrypted at rest And delivery occurs over TLS And waveform data aligns to audio duration within ±100 ms at start and end And waveform amplitude values are normalized to [0.0, 1.0] And the transcript text exactly matches the TTS input text And all artifacts carry the correct card ID and resident ID metadata
Graceful Fallback on Summarization Failure
Given the summarization step times out or errors When a recap is requested Then the system falls back to reading the raw voice-to-text note And internal-only content remains excluded And audio, waveform, and transcript are still produced And latency targets for short (≤ 120 words) and long (> 120 words) cards are met as per real-time/background criteria
Family Digest Attachment Rules
Given a card marked shareable with families and with no internal-only content in visible fields When the recap is generated Then the audio and transcript are attached to the next family digest for approved recipients And the digest includes a playable audio link using the provided URL and waveform Given a card not shareable with families or containing internal-only fields When the recap is generated Then the audio and transcript are not attached to family digests and are available only to staff channels
Huddle Playback Controls
"As a shift lead, I want reliable playback controls and queues so that my team can listen through updates quickly without fumbling with the device."
Description

In-app audio player optimized for care huddles with play/pause, skip, and speed controls (0.75x, 1x, 1.25x, 1.5x), waveform scrubber, and a queue to play multiple cards by resident or shift. Supports Bluetooth headset buttons and large tap targets for gloved use. Works offline by caching the latest briefs per unit and syncs when connectivity returns. Provides captions via transcript toggle for noisy environments. Integrates with the existing card list and huddle view for seamless workflows.

Acceptance Criteria
Huddle Playback Basics & Large-Tap Controls
- Given a user is in Huddle view with at least one Audio Brief, when Play is tapped, then audio starts within 300 ms and the Play/Pause control updates its icon/state. - When Pause is tapped, then playback pauses within 300 ms and resumes from the same position when Play is tapped again with drift <= 1 s. - The player remembers per-card position within the current session; navigating away and back within 10 minutes resumes within +/-1 s. - Tap targets for Play/Pause, Skip, Speed, and Scrubber are >= 48 dp (Android) or >= 44 pt (iOS) with >= 8 dp spacing. - All primary controls expose accessible labels (Play, Pause, Next, Previous, Speed) and are operable via VoiceOver/TalkBack.
Playback Speed Controls at 0.75x–1.5x
- Speed options presented are exactly 0.75x, 1x, 1.25x, 1.5x with 1x as default. - Changing speed applies within 250 ms without restarting the current brief. - Pitch correction is enabled; perceived pitch deviation <= +/-3% at all supported speeds. - Selected speed persists across briefs in the queue and across app relaunch until changed. - On speed change, an accessibility announcement communicates the new rate (e.g., "Speed 1.25x").
Waveform Scrubber Seeking
- Waveform displays total duration and current timestamp in mm:ss. - Tapping a position on the waveform seeks to that time within 300 ms and resumes playback from that point. - Dragging the scrubber pauses playback and seeks with accuracy within +/-0.3 s of the release point; playback resumes within 300 ms. - Buffered vs. played progress is visually distinct and updates at least 4 times per second. - Hardware keyboard left/right arrows (where available) seek backward/forward by 5 s.
Resident/Shift Queue Playback & Integration
- From Huddle view or Card List, selecting Resident scope plays that resident’s briefs (newest to oldest); selecting Shift scope plays all briefs from the current shift for the unit in chronological order. - Queue header shows total item count and estimated total/remaining duration with error <= 5%. - Playback advances automatically to the next item with inter-item gap <= 500 ms; reaching the end stops and displays "Queue complete". - Next/Previous controls move between items within 300 ms; Skip resets position to 0:00 of the target item. - If an item fails to load, it is skipped after <= 1 s with a non-blocking notice; playback continues.
Bluetooth Headset Button Support
- Single-press of the headset multi-function button toggles Play/Pause within 300 ms when KinLoop audio is active (foreground, background, or locked). - Double-press skips to the next item in the queue within 500 ms on devices supporting AVRCP; unsupported actions fail gracefully without crash. - Headset connect/disconnect routes audio to/from the headset automatically and preserves play/pause state. - Incoming phone calls pause playback and auto-resume within 2 s after the call ends if playback was active. - Headset volume buttons adjust system media volume while KinLoop is active.
Offline Caching & Resilient Sync
- Entering Huddle view with connectivity preloads and caches the latest Audio Brief and transcript per resident in the current unit for the active shift, indicating progress until complete. - With no connectivity, cached briefs play fully; uncached briefs are labeled "Not available offline" and are excluded from queues. - Queue playback operates offline using only cached items; Skip and Scrub remain responsive (<= 300 ms action latency). - On reconnect, new/updated briefs sync automatically within 30 s without interrupting current playback; newly synced items appear in queues after the current item finishes. - Partially downloaded briefs resume from the last byte on reconnect to avoid re-downloading the full file.
Transcript Captions Toggle in Noisy Huddles
- Toggling Captions shows/hides the transcript within 200 ms; the toggle state persists per user on the device across sessions. - Transcript auto-scrolls in sync with playback and highlights the current line; cumulative sync drift <= 0.5 s over any 5-minute segment. - Captions are available offline for cached briefs; when offline without a cached transcript, the toggle is disabled with explanatory text. - When device volume is muted or in Silent Mode, captions remain visible and continue to auto-scroll. - Transcript region supports Dynamic Type/Font Scale up to OS maximum without truncation and is readable by screen readers in correct order.
Digest Attachment Rules
"As a family member, I want an optional audio version of my loved one’s updates so that it’s easier for me to keep up without reading long messages."
Description

Rule engine to attach audio briefs to family digests when consent and preferences permit. Evaluates resident consent flags, sensitivity labels, and per-family settings; enforces duration limits (≤60s) and adds transcript/alt text for screen readers. Converts audio to a lightweight format and delivers via secure links with expiry and download limits. Integrates with existing digest scheduling and channels (email, SMS link, app inbox) while respecting quiet hours and local time zones.

Acceptance Criteria
Attachment Based on Consent and Preferences
Given resident.share_audio=true And family.receive_audio=true And family.approval_status="approved" When the digest is assembled for that family Then the card's audio brief is attached to the family's digest And audit_log records attachment with reason="allowed"
Block on Sensitive Labels
Given card.sensitivity_label in policy.blocked_labels When the digest is assembled Then the audio brief is not attached to any family digest And audit_log records reason="sensitivity_block"
Enforce 60-Second Duration Limit
Given audio_brief.duration>60s When the digest is assembled Then the audio brief is not attached And audit_log records reason="over_duration" Given audio_brief.duration<=60s When the digest is assembled and other rules permit Then the audio brief is eligible for attachment
Transcript and Alt Text Included for Accessibility
Given the audio brief is attached When the digest is rendered in email, SMS, and app inbox Then a text transcript of the audio is available to the recipient in each channel And the audio link or player exposes an accessible label describing content and duration And transcripts include the correct language code If transcript generation fails Then a fallback accessible label is provided and audit_log records reason="transcript_unavailable"
Transcode to Lightweight Format
Given an audio brief eligible for attachment When preparing the digest assets Then the audio is transcoded to a lightweight, widely supported format per policy And the target bitrate and sample rate meet policy thresholds And the resulting file size <= policy.max_audio_size_kb And playback succeeds in app inbox and via email/SMS browser playback on iOS and Android
Secure, Expiring, Limited-Download Links
Given policy.expiry_days and policy.max_downloads are configured And a digest with an attached audio brief is generated When a recipient opens the secure link before expiry and below the download limit Then the audio brief streams or downloads successfully When the expiry time is reached or the download limit is exceeded Then subsequent requests return HTTP 410 and no audio content is served And each access attempt is logged with recipient_id, timestamp, and outcome
Scheduling Across Channels Respects Quiet Hours and Local Time
Given each recipient has a timezone and quiet_hours window configured And channels {email,SMS,app} are enabled for the digest When the scheduled send time falls within a recipient's quiet_hours Then delivery to that recipient is deferred to the next available time outside quiet_hours in their local timezone And the secure link's expiry countdown begins at the actual delivery timestamp And email contains a secure "Audio brief" link with duration And SMS contains a secure "Audio brief" link with duration And app inbox displays an inline player that streams the audio brief
Language & Voice Selection
"As an admin, I want audio briefs to play in the listener’s preferred language and a clear, respectful voice so that updates are understandable and comforting."
Description

Automatic and manual selection of language and voice based on listener preferences, device locale, and facility defaults. Launch support for US English and US Spanish with warm, natural voices; includes a pronunciation dictionary for resident names and medications, and SSML prosody for vitals, dates, and times. Allows per-facility default voice and per-brief override, with consistent application across huddles and digests. Falls back gracefully to English if a target language is unavailable.

Acceptance Criteria
Facility Default Voice Applied Across Outputs
Given a facility default is configured with language=es-US and voice=ES_Warm_A And no per-brief override is set And the listener has no explicit language preference When an Audio Brief is generated Then the brief is synthesized in es-US using ES_Warm_A And the same language/voice is used for both huddle playback and family digest attachment And the resolved language=es-US and voiceId=ES_Warm_A are recorded in the audit log for the brief And the selected voiceId is in the curated warm-voice allowlist
Per-Brief Override Precedence
Given facility defaults language=en-US, voice=EN_Warm_A And the device locale is es-US And the brief override is set to language=es-US, voice=ES_Warm_B When the Audio Brief is generated Then the brief is synthesized in es-US using ES_Warm_B for huddle and digest And if ES_Warm_B is unavailable, the system uses the facility’s es-US default voice And if es-US voices are unavailable, the system falls back to en-US facility default voice And the selection path (override -> es-US default -> en-US default) is captured in telemetry
Listener Preference Overrides Device Locale
Given a listener has preference language=es-US And the device locale is en-US And no per-brief override is set When attaching the Audio Brief to that listener’s family digest Then the brief is synthesized in es-US using the facility’s es-US default voice And if no es-US default is configured, use the system’s es-US warm voice And if es-US is unavailable at runtime, fall back to en-US facility default voice And the precedence order applied is: brief override > listener preference > device locale > facility default > en-US fallback
Pronunciation Dictionary Applied to Names and Medications
Given the facility pronunciation dictionary contains custom entries for resident names and medication terms referenced in the brief When the Audio Brief is synthesized in en-US or es-US Then the synthesis request includes the dictionary so that custom pronunciations are applied for all matching terms And where no dictionary entry exists, default TTS pronunciation is used And updates to the dictionary are honored on the next synthesis request without requiring app restart And the audit log lists which dictionary entries were applied for the brief
SSML Prosody for Vitals, Dates, and Times
Given an Audio Brief includes vitals (e.g., BP 120/80, O2 95%, Temp 98.6 F), dates, and times When the brief is synthesized in en-US or es-US Then the synthesis payload uses SSML to correctly render numbers, units, dates, and times with appropriate prosody And a short pause (200–400 ms) separates sections (e.g., between vitals) And the spoken output renders dates and times in the selected language’s convention And the SSML usage is consistent across huddle playback and family digest
Consistency Across Huddle Playback and Family Digest
Given a single Audio Brief instance When it is played in a staff huddle and attached to a family digest Then both outputs use the identical language and voiceId resolved for that brief And no re-synthesis occurs with a different language/voice for the digest And the digest metadata includes the language code used (en-US or es-US)
Supported Languages Restricted at Launch with Graceful Fallback
Given the system supports en-US and es-US at launch When a user attempts to select a language or when auto-selection runs Then only en-US and es-US are offered or auto-selected And if the device locale is not en-US or es-US, the system selects the facility default language if supported, else en-US And any attempt to set an unsupported language results in a non-blocking notice and automatic fallback to en-US And no error prevents brief generation due to language unavailability
Privacy & Redaction Guardrails
"As a compliance officer, I want automatic redaction and consent-aware audio so that we protect dignity and meet privacy obligations without manual review."
Description

Automated content filtering and redaction to remove non-consenting names, staff identifiers, room numbers, and other PHI per facility policy before synthesis. Mirrors photo auto-blur consent logic to avoid mentioning non-consenting residents; replaces with neutral phrasing when needed. Ensures internal-only sections are never voiced. All processing uses encrypted transport and no data retention by third-party TTS providers. Generates a verifiable hash linking source text to produced audio and logs redaction decisions for audit.

Acceptance Criteria
Pre-Synthesis PHI Redaction
Given a card text contains tokens matching the facility PHI policy (e.g., resident full legal names, staff surnames/IDs, room/bed numbers, MRNs, phone numbers) When an Audio Brief is generated Then all policy-matched tokens are removed or generalized to policy-approved neutral phrasing before any text is sent to TTS And the exact text submitted to TTS contains zero matches to the facility PHI detection patterns And an automated transcription of the produced audio contains zero matches to the same detection patterns And a redaction summary is produced listing category and count of redactions for the card
Consent-Aware Name Handling
Given the consent matrix marks Resident A as non-consenting and Resident B as consenting, and both are mentioned in the card When an Audio Brief is generated Then all mentions of Resident A’s identifiers (name, initials, nicknames, bed/room references) are replaced with neutral phrasing (e.g., “another resident”) And mentions of Resident B are preserved per policy And resulting grammar and plurality remain natural (no broken sentences) And the redaction log records each substitution with rule "non-consenting resident" and the consent matrix version used And the audio and its transcript contain no tokens that uniquely identify Resident A
Internal-Only Section Exclusion
Given a card contains one or more sections flagged as internal-only via metadata or markup When an Audio Brief is generated for any audience (staff or family) Then internal-only content is entirely excluded from the text passed to TTS and from the audio output And the redacted text and audio transcript contain zero tokens originating from internal-only sections And the audit log lists excluded section identifiers and byte ranges And if 100% of the card is internal-only, audio generation is skipped and the user is notified with a non-shareable reason code
Encrypted, No-Retention TTS Processing
Given the system must use a third-party TTS provider When submitting redacted text for synthesis Then the request uses HTTPS with TLS 1.2+ and validates the provider certificate (no downgrade) And the request sets the provider’s no-retention/no-store flag or equivalent parameter And the provider response indicates acceptance of the no-retention setting (e.g., acknowledged flag or header) And if the provider rejects or lacks no-retention, the request is aborted (fail closed) and no content is transmitted And the event is logged with provider name, region, TLS version, and no-retention acknowledgment status
Source-to-Audio Integrity Hash
Given redacted text T and produced audio bytes A When Audio Brief synthesis completes Then the system computes a SHA-256 hash over canonical(T) || A and stores it with card ID, timestamp, and pipeline version And a verification endpoint recomputes the hash from stored artifacts and returns Match/No Match And any modification to T or A results in No Match on verification And the hash value and verification result are recorded in the audit trail
Redaction Decision Audit Logging
Given any redaction, substitution, or exclusion occurs during Audio Brief preparation When the job completes (success or fail) Then an append-only audit record is written containing: timestamp, card ID, actor/service ID, rule IDs, token class, salted token fingerprint, replacement class, positions/ranges, consent source version, and prior-entry hash And authorized auditors (RBAC) can retrieve, filter by date/rule/category, and export the records And integrity checks over the log chain detect tampering and raise an alert on mismatch
Background Generation & Caching
"As a caregiver, I want audio briefs to be ready when I open the card so that I don’t have to wait during busy shifts."
Description

Asynchronous job queue triggers audio generation on card save/edit with debouncing to prevent churn. Exposes generation states (Processing, Ready, Failed) on cards, retries with exponential backoff, and caches the latest audio per card with invalidation on edits. Edge-caches audio for low-latency playback and sets SLOs (P95 generation <10s, start playback <1s on Wi‑Fi). Provides on-device TTS fallback when network is unavailable to maintain continuity in huddles.

Acceptance Criteria
Async Generation Debounced on Save/Edit
Given a caregiver saves or edits a card When one or more additional edits occur within the configured debounce window (default 10s) Then only one generation job is enqueued And the job uses the latest card content at debounce expiry And if no further edits occur, generation starts within 1s after the window ends And no more than one concurrent generation job exists per card
Generation State Visibility and Transitions
Given a card with audio generation pending When a job is enqueued Then the card's audioBrief.state = "Processing" When audio is successfully generated and cached Then audioBrief.state = "Ready" and audioBrief.url is non-null When all retries are exhausted without success Then audioBrief.state = "Failed" and audioBrief.errorCode is populated And the state is retrievable via API and reflected in UI within 2s
Exponential Backoff Retries
Given a transient generation failure occurs When retries are attempted Then the system retries up to 5 times with exponential backoff and jitter (≈1s, 2s, 4s, 8s, 16s ±20%) And successful generation at any retry updates the state to Ready And total retry duration does not exceed 5 minutes
Latest-Audio Cache With Invalidation on Edit
Given a card has Ready audio cached When the card is edited Then the prior audio asset is immediately marked stale and not served And audioBrief.state transitions to Processing And upon successful regeneration, the audioBrief.url points to the new asset And CDN and client caches of the prior asset are invalidated within 60s
Edge-Cached Low-Latency Playback
Given a device on Wi‑Fi with at least 25 Mbps down and <50 ms RTT When the user taps Play on a Ready audio brief Then playback start time (tap to audible audio) is P95 < 1.0s and P99 < 1.5s And cache hit ratio at CDN edge for the asset is ≥90% over a rolling 7-day window
P95 Generation Time Under 10 Seconds
Given cards with text content ≤1,000 characters When audio generation is triggered Then time from debounce-window end to Ready state is P95 < 10s and P99 < 20s measured over 7 days and ≥500 samples And median generation time is < 5s
On-Device TTS Fallback When Offline
Given a device is offline or the audio URL fails to load within 2s When the user taps Play on a card with Processing or Ready state Then on-device TTS reads the current card text aloud within 2s of tap And playback uses the device's default voice, correct locale, and volume settings And when network becomes available, subsequent plays prefer the cloud audio asset
Admin Controls, Metrics & Audit Trail
"As an administrator, I want controls and visibility into Audio Brief usage and quality so that I can manage risk and improve adoption."
Description

Facility-level controls to enable/disable Audio Brief, set default voices/languages, configure digest attachment policy, and define audio retention. Metrics dashboard tracks generation success rates, latency, listen-through for huddles and digests, opt-in/opt-out counts, and common error types. Exportable audit logs record who generated/listened, redactions applied, and delivery outcomes with timestamps and card IDs. Threshold-based alerts notify admins when error rates or latency exceed targets. Integrates with existing roles and reporting.

Acceptance Criteria
Global Enable/Disable Control
- Given an Admin user with Facility Admin role, When they toggle Audio Brief to Disabled, Then the Audio Brief generation UI and API are hidden/blocked for all non-admin users across the facility within 60 seconds, and any scheduled generations are canceled with a logged reason. - Given Audio Brief is Disabled, When a non-admin attempts to call the generation endpoint, Then the system returns HTTP 403 with error code AB_DISABLED and no audio is produced, and an audit entry is recorded. - Given an Admin toggles Audio Brief to Enabled, When a caregiver opens a card composer, Then the "Generate Audio Brief" action is visible and usable according to role permissions. - Rule: All enable/disable changes are timestamped, include actor ID, old/new values, and appear in the audit log within 15 seconds.
Default Voice and Language Configuration
- Given an Admin sets facility default voice and language, When a caregiver generates an Audio Brief without overriding settings, Then the output uses the facility defaults. - Rule: Supported voices and languages are limited to the catalog exposed by the system; invalid selections are prevented and validated client- and server-side with error AB_INVALID_VOICE or AB_INVALID_LANG. - Rule: Changes to defaults propagate to all new generations within 60 seconds; they do not retroactively alter existing audio files. - Rule: Only Admin and Editor roles with "Audio Config" permission can modify defaults; attempts by others are blocked and logged. - Rule: Defaults are included in configuration export and visible in reporting views.
Digest Attachment Policy Configuration
- Given an Admin selects a digest policy (Always attach; Never attach; Attach if resident family contact has audio-opt-in; Attach only for cards marked Shareable), When a digest is generated, Then the system attaches Audio Briefs according to the selected policy with per-recipient enforcement. - Rule: Per-family opt-in/opt-out status is honored; if opted-out, no audio is attached and the digest notes "Audio omitted (opt-out)." - Rule: Policies are evaluated per card and per recipient; decision and policy version are recorded in audit log with digest ID. - Rule: Delivery failures for audio attachments are captured as delivery outcomes with error type and retried up to N=3 times with exponential backoff. - Rule: Policy changes require Admin role and are effective for digests generated after the change timestamp.
Audio Retention Policy Enforcement
- Given an Admin sets retention to X days (X ∈ [7, 365]), When an audio file exceeds X days age, Then it is automatically purged within 24 hours and an audit entry is recorded with purge reason RETENTION. - Rule: Legal hold flag prevents purge until cleared by Admin with "Compliance" permission; holds are auditable. - Rule: Purged audio references are removed from playback UI; metrics exclude purged files from listen-through rates after purge. - Rule: Retention changes apply prospectively; existing future purge schedules are recalculated within 60 minutes. - Rule: Export API excludes purged audio content but retains metadata needed for audits.
Metrics Dashboard Accuracy and Freshness
- Given the metrics date range filter is set, When the dashboard loads, Then it displays generation success rate, average and P95 latency, listen-through rates for huddles and digests, opt-in and opt-out counts, and top 5 error types for the selected period. - Rule: Metrics are updated at least every 5 minutes and show a "Last updated" timestamp. - Rule: Values are consistent with underlying event logs within ±1% for counts and ±100ms for latency aggregates. - Rule: Users with Admin or Reports roles can view facility-wide metrics; others are denied and the attempt is logged. - Rule: Dashboard supports export to CSV for displayed metrics with the same filters applied.
Audit Log Completeness and Export
- Given events occur (generation requested/completed/failed, user listened, redactions applied, delivery outcomes), When an auditor queries the audit log by date range or card ID, Then each event includes timestamp (ISO 8601, facility TZ), actor ID or system, card ID, resident ID, event type, parameters (e.g., error code, redaction count), and IP/device where applicable. - Rule: Audit entries are immutable and retained for minimum 24 months regardless of audio retention. - Rule: Export produces a CSV and NDJSON within 60 seconds for up to 100k rows; larger exports stream and include continuation tokens. - Rule: Access is limited to Admin and Compliance roles; all exports are themselves logged with requester, filter, row count, and checksum. - Rule: Redactions applied are enumerated with before/after hash references; actual content is not exposed in logs.
Threshold-Based Alerts for Errors and Latency
- Given admins configure thresholds (e.g., error rate > 3% over 15-minute window or P95 latency > 3s), When a threshold is breached, Then an alert is sent via configured channels (in-app, email, SMS) within 2 minutes with metric, current value, window, and top error types. - Rule: Alerts respect a 30-minute cooldown per metric/facility to prevent noise, with de-duplication across channels. - Rule: Alert acknowledgement and mute actions are role-gated to Admins; actions are logged. - Rule: Alerts clear automatically when metrics fall below thresholds for one full window and a "recovery" notification is sent. - Rule: Misconfigured thresholds are validated at save time; invalid inputs are rejected with descriptive errors.

QR Deeplink

Every printed or shared card includes a time-limited, permission-aware QR/link that opens the resident’s timeline for approved viewers. Speeds drill-down during rounds, logs access for audits, and removes the need to hunt through menus on shared devices.

Requirements

Permission-Aware Tokenized Deeplink
"As a caregiver, I want QR links that only open for approved viewers and expire automatically so that resident privacy is protected while enabling fast access during rounds."
Description

Issue signed, time-limited deeplink tokens scoped to a specific resident and viewer role that open directly to the resident’s timeline. Server-side validation enforces expiration, revocation, and role-based permissions, including read-only for families and write-enabled for authenticated staff. Tokens are bound to organization policies (TTL, single-use vs reusable, geofence) and honor existing consent/auto-blur settings to prevent PHI leakage. Includes key rotation, error states for expired/denied access, and deterministic redirect to app or web based on platform.

Acceptance Criteria
Issue Signed, Scoped, Time-Limited Deeplink Token
Given a staff user with permission to share resident R’s timeline selects role Y and policy P When they request a deeplink token Then the server returns a signed opaque token scoped to org, resident R, role Y, and policy P And the token TTL equals the policy TTL And the token includes a single_use flag per policy (true/false) And the generated QR and URL embed only the opaque token and no PHI or resident name And issuance is denied with 403 if the requester lacks permission for resident R And issuance is logged with token_id, requester_id, resident_id, role, policy_id, and timestamp
Server Validation, Expiration, Revocation, and Single-Use Enforcement
Given any viewer opens a deeplink token When the server validates the token Then it verifies signature against the active signing key or permitted previous key And verifies the token is unexpired, unrevoked, and owned by the same org And enforces configured policy constraints (e.g., single-use, reuse window) And if single_use=true and unused, the token is marked consumed atomically before responding And if validation fails, respond 401 for invalid/expired or 403 for policy/permission violations with a machine-readable error code and human-readable message And p95 validation latency is ≤ 500 ms under normal load And every attempt (success or failure) is audit-logged with token_id, resident_id, org_id, role, outcome, reason, timestamp, and source IP/device
Role-Based Access: Family Read-Only, Staff Write After Auth
Given a valid family-role token opens resident R’s timeline Then the viewer can read timeline content and cannot create, edit, or delete updates; write actions are hidden client-side and rejected server-side with 403 Given a valid staff-role token opens resident R’s timeline When the user authenticates as staff within the same org Then the viewer can create updates for resident R consistent with RBAC and cannot access other residents via the token And any write attempt without completed staff authentication is rejected with 401/403
Consent and Auto-Blur Enforcement on Media
Given resident R’s timeline contains media with faces of non-consenting individuals When the media is rendered via a tokenized deeplink Then all non-consenting faces are auto-blurred according to facility policy before delivery And original unblurred assets are never exposed via URLs or client cache And delivered media URLs are time-limited/authenticated and strip EXIF location/PHI metadata
Deterministic Redirect to App or Web
Given a viewer opens the permission-aware link on a mobile device with the KinLoop app installed Then the native app opens directly to resident R’s timeline screen without intermediate pages Given the app is not installed Then the link opens the responsive web timeline for resident R Given a desktop environment Then the link opens the web timeline And in all cases, the same token is not leaked via HTTP referrers and only the opaque token appears in the URL
Organization Policy Geofence Enforcement
Given org policy P requires a geofence with radius G around facility F When a viewer opens a tokenized link Then access is granted only if the device location is within G of F And if location is unavailable or outside G, access is denied with a geofence-specific error state and no content is returned And geofence decisions are logged with distance, outcome, and timestamp
Signing Key Rotation Without Downtime
Given the signing key is rotated to a new active key K2 and previous key K1 is retained for a grace window W When validating tokens during W Then tokens signed with K2 or K1 are accepted if otherwise valid And tokens signed with keys older than K1 are rejected And new tokens are signed with K2 immediately after rotation And no service downtime or increase in validation error rate occurs during rotation
Dynamic QR Code Generation on Cards
"As an administrator, I want to print resident cards with secure QR codes so that staff can scan and jump to the correct timeline instantly."
Description

Generate high-contrast, error-corrected QR codes that embed the secure deeplink and are printed on resident cards and shareable materials. Codes are uniquely bound to a resident (and optionally location or unit) with support for re-issuance, revocation, and short-link fallbacks. The generator provides branded templates, printer-friendly layouts, and versioning so administrators can batch print, reprint, and invalidate cards without manual steps. All codes resolve through the KinLoop routing service to ensure policy enforcement and auditability.

Acceptance Criteria
High-Contrast, Error-Corrected QR Generation
Given an admin selects a resident and a standard or compact card template When the system generates the QR code Then the QR encodes the secure deeplink for that resident And error correction level is at least M And the quiet zone is at least 4 modules And the foreground/background contrast ratio is >= 7:1 And the printed module size is >= 0.8 mm at 300 dpi And the QR decodes successfully on reference iOS and Android devices from 6–18 inches with up to 5° skew and up to 10% area occlusion
Secure, Permission-Aware Deeplink Resolution via Routing
Given an approved viewer scans a valid, unexpired code When the KinLoop routing service resolves the deeplink Then the token is validated for signature, issuer, resident binding, and expiry And viewer permission is checked against facility policy And the resident timeline opens in <= 2.0 seconds at p95 latency And an access audit event is recorded with timestamp, viewer ID, resident ID, card version, entry method=QR, and outcome=success And no PII is present in the QR payload (tokenized only) Given an unapproved viewer or expired/revoked code When the routing service processes the request Then a 403/410 error page with no timeline data is returned And an audit event is recorded with outcome=denied
Resident/Unit Binding, Re-issuance, and Revocation
Given a QR is issued for a resident with optional unit/location scope When the code is generated Then the token is unique per resident and per unit scope And any previously active code for the same scope is revoked automatically upon re-issue And revocation propagates within 60 seconds And scans of revoked codes return HTTP 410 and display "Card expired" And issuance/revocation history records actor, timestamp, scope, and reason
Short-Link Fallback and Equivalence
Given a card includes a printed short URL fallback When a user types the short URL in a browser Then it resolves through the same routing service, token validation, and permission checks as the QR And the short URL slug length is <= 12 characters (excluding domain) and is case-insensitive And the short URL is uniquely bound to the same resident/scope as the QR And access events via short URL are logged with entry method=shortlink And the short URL is invalidated when the associated QR is revoked or expired
Branded Template Output and Batch Printing
Given an admin selects a branded template and a list of residents When batch card generation is initiated Then per-resident cards are rendered with branding, resident name, unit, version, issue date, QR, and short URL And output is a collated PDF in CMYK with embedded fonts, 300 dpi rasterization where applicable And margins, bleed, and safe areas match the template spec And barcodes/QRs are not clipped and maintain the required quiet zone And the export completes in one action without manual layout steps And the generated files are stored with version metadata and a downloadable link
Card Versioning, Batch Invalidation, and Reprint
Given card versioning is enabled When an admin publishes a new card design version or reissues cards Then the version identifier is printed on the card and stored in metadata And the system supports invalidating all cards of a selected version for a resident, unit, or facility with one action And scans of older versions display "Update available" without exposing timeline data And a one-click "Reprint latest" regenerates PDFs for the selected cohort using the newest version and data And all version and invalidation actions are logged with actor and timestamp
Configurable Expiry and Auto-Rotation
Given a default QR expiry policy is configured (e.g., 7/30/90 days) When a code is generated Then the token includes an expiry timestamp per policy And the system rejects expired tokens with HTTP 410 and "Card expired" And admins receive notification 3 days before a batch of issued cards is due to expire And an optional auto-rotation job reissues fresh codes for active residents ahead of expiry and invalidates old codes And rotation maintains audit linkage between old and new codes
Access Logging and Audit Trail
"As a compliance officer, I want a detailed audit of all QR link accesses so that I can demonstrate compliance and investigate incidents."
Description

Record every QR/link access attempt with timestamp, resident ID, viewer identity or device fingerprint, outcome (success/denied/expired), and source metadata (app version, IP, location if permitted). Provide an admin console to search, filter, and export logs by resident, unit, user, or time range, with retention aligned to compliance policies. Include anomaly detection signals (e.g., repeated failed scans, unusual geolocation) and alert hooks to downstream incident workflows. All events are immutable and mapped to existing KinLoop audit schemas for unified reporting.

Acceptance Criteria
Log Capture on QR/Link Access Attempt
Given a QR deeplink or access link is scanned or clicked When the access attempt is evaluated Then the system records a single log event containing: event_id (UUID), timestamp (UTC ISO8601 with milliseconds), resident_id, link_id, viewer_id if authenticated else device_fingerprint, outcome ∈ {success, denied, expired}, app_version, client_ip, user_agent, facility_id, unit_id if known, geo_location only if location_sharing_permitted=true And the log event is persisted before the HTTP response is returned or within 2 seconds of the access decision, whichever occurs first And the response includes a correlation_id matching event_id in headers for traceability
Outcome Determination: Success, Denied, Expired
Given an authorized viewer opens a valid, unexpired link When the system evaluates permissions and link state Then outcome=success, HTTP 200 is returned, and the resident timeline loads Given a viewer lacking approval opens a valid, unexpired link When the system evaluates permissions and link state Then outcome=denied and HTTP 403 with a non-revealing message is returned Given any viewer opens an expired or revoked link When the system evaluates link state Then outcome=expired and HTTP 410 is returned And each of these events is logged exactly once with the correct outcome value And time from request receipt to decision is ≤ 2 seconds for the 95th percentile
Admin Console: Search, Filter, and Export Logs
Given an admin with audit_view permission accesses the Audit Console When they filter by resident, unit, viewer (user), outcome, and time range Then the result set reflects the combined filters (AND logic) And results are sortable by timestamp and paginated (default 50 per page) And a timezone selector defaults to the facility timezone and can be changed per session And Export CSV generates within 10 seconds and contains only filtered results with columns: timestamp, resident_id, viewer_id/device_fingerprint, outcome, app_version, client_ip, geo_location(if present), facility_id, unit_id, event_id, link_id And the CSV follows RFC 4180 (header row, quoted fields as needed, UTF-8)
Retention Policy Enforcement
Given organization-level retention_days is configured When the scheduled retention job runs Then log events older than retention_days and not under legal_hold=true are purged from active storage And each purge operation is itself logged with event_type=retention_purge including count and cutoff_timestamp And purged events no longer appear in the admin console or exports And events with legal_hold=true are retained regardless of age And a change to retention_days takes effect on the next scheduled run
Event Immutability and Tamper Resistance
Given a log event exists When any API, console action, or background job attempts to update or delete the event Then the operation is rejected (HTTP 403/permission_denied) and no data is modified And only append-only corrective events are allowed, referencing the original event_id And storage enforces append-only semantics for the audit log And a daily integrity check runs and logs an integrity_report event if discrepancies are detected
Anomaly Detection and Alert Hooks
Given 5 or more denied outcomes for the same resident_id from the same /24 IP CIDR within 10 minutes When the threshold is met Then an anomaly_event with type=failed_scan_burst is logged and an alert webhook POST is sent containing resident_id, count, ip_cidr, window_start, window_end, and latest_event_id And webhook delivery retries up to 5 times with exponential backoff starting at 30 seconds on failure Given a success or denied outcome with geo_location more than 50 miles from the facility centroid and location_sharing_permitted=true When the event is logged Then an anomaly_event with type=unusual_geolocation is logged and an alert webhook POST is sent containing resident_id, distance_miles, facility_id, event_id And webhook delivery status (success/last_error/next_retry_at) is visible in the admin console And alert hooks can be enabled/disabled per facility; when disabled, anomaly_events are logged but no webhooks are sent
Schema Mapping to Unified Audit Reporting
Given a new access log event is created When validated against the current KinLoop unified audit schema Then the event passes schema validation and is queryable via the reporting API alongside other audit events And the event maps fields as: actor → viewer_id or device_fingerprint, subject → resident_id, action → timeline_access_attempt, outcome → outcome, context → {client_ip, app_version, geo_location if present, facility_id, unit_id} And the standard report "Access Attempts by Resident" returns correct counts when filtered by resident and time range
Admin Link Policy Controls
"As an administrator, I want to set how long links last and who can open them so that security matches our facility policies."
Description

Expose organization-level and unit-level controls for link behavior, including default and maximum TTL, allowed roles, single-use vs reusable tokens, rate limits, optional geofencing, and whether family access is permitted. Provide per-resident override and a one-click "Revoke all active links" action. Policies are enforced at token issuance and validation, surfaced in the admin UI and via API, and logged for change history. Sensible defaults are applied to new facilities to minimize setup while meeting security baselines.

Acceptance Criteria
TTL Policy Enforcement at Issuance and Validation
Given org defaultTTL=24h and maxTTL=72h When an admin issues a link without specifying TTL via UI or API Then the token.expiresAt = issuedAt + 24h and the response includes ttlSeconds=86400 Given org defaultTTL=24h and maxTTL=72h When an admin attempts to issue a link with TTL=120h Then the token.expiresAt = issuedAt + 72h, the response includes ttlClamped=true and ttlSeconds=259200 Given a token is presented after its expiresAt (with 60s clock-skew tolerance) When validation occurs Then access is denied with HTTP 401 and error="token_expired" and an audit log entry records residentId, tokenId, policyVersion, and reason="expired"
Allowed Roles and Family Access Gate
Given allowedRoles=[Caregiver, Admin] and familyAccess=false When a user with role=Family opens a valid link Then access is denied with HTTP 403 and error="role_not_allowed" and the attempt is audit logged with viewerRole=Family Given allowedRoles includes Family and familyAccess=true and the family user is approved for the resident When the user opens a valid, unexpired link Then the resident timeline loads and initial content renders within 2 seconds (p95) and access is logged with viewerRole=Family Given a link requires authentication When an unauthenticated user follows the QR deeplink Then the app redirects to sign-in and no timeline data is returned until authentication succeeds
Single-Use vs Reusable Token Behavior
Given tokenMode=single_use and a valid, unexpired token When the first access succeeds Then the token state is marked consumed and any subsequent access attempts return HTTP 410 and error="token_consumed" and are audit logged Given tokenMode=reusable and a valid, unexpired token When multiple accesses occur within TTL Then all accesses succeed and are individually logged Given tokenMode=reusable and the token expires When any access attempt occurs after expiry Then access is denied with HTTP 401 and error="token_expired"
Optional Guardrails: Geofencing and Rate Limits
Given geofencing=enabled with an allowlist polygon/radius of 100m When a request originates within the geofence (based on device location with user consent or IP geo if device location unavailable) Then access is permitted Given the same geofencing configuration When a request originates outside the geofence Then access is denied with HTTP 403 and error="outside_geofence" and the attempt is audit logged with approximate location Given rateLimit perToken=30 req/min and perIP=60 req/min When requests exceed the configured thresholds Then excess requests return HTTP 429 with a Retry-After header and throttling events are recorded in security logs Given geofencing=disabled When any access occurs Then no geofence evaluation is performed
Per-Resident Override and Policy Precedence
Rule: Effective policy precedence is Resident > Unit > Org for boolean gates (e.g., familyAccess, tokenMode); org.maxTTL always caps any lower-level TTL Given org.familyAccess=false, unit.familyAccess=true, resident.familyAccess=true When a Family user with resident approval opens a valid link Then access is allowed and logged with policySource="resident" Given resident.familyAccess=false regardless of unit/org settings When a Family user opens a valid link Then access is denied with HTTP 403 and error="family_access_disabled" Given resident.overrideTTL=96h and org.maxTTL=72h When a link is issued for that resident Then TTL=72h and the issuance response includes ttlClamped=true and effectiveTtlSeconds=259200
Revoke All Active Links Immediate Invalidation
Given an admin selects "Revoke all active links" for resident R and confirms When the action is executed Then 100% of resident R's active tokens are invalid within 60 seconds across all caches and subsequent requests return HTTP 401 and error="token_revoked" Then the Admin UI shows a success toast with revokedCount and timestamp, and an audit log entry records actorId, residentId, revokedCount, and action="revoke_all" Given API POST /residents/{residentId}/links/revokeAll When called multiple times within 5 minutes Then the endpoint is idempotent (HTTP 200) and returns revokedCount=0 on subsequent calls
Admin UI/API Surfacing and Secure Defaults
Given a new facility is created When the facility is provisioned Then default policies are applied: defaultTTL=24h, maxTTL=72h, tokenMode=single_use, allowedRoles=[Caregiver, Admin], familyAccess=false, rateLimit perToken=30/min perIP=60/min, geofencing=disabled Given an admin views Organization or Unit Policy screens When loading the page Then all policy fields display current effective values, indicate inherited vs overridden state, and prevent values exceeding caps (e.g., TTL > maxTTL) Given API GET /policies?scope=org|unit|resident When requested with proper auth Then the response includes effective values, sourceLevel, and cap fields; and PUT updates validate constraints, reject invalid values with HTTP 400, and on success create an immutable audit log entry with actor, scope, before/after values, timestamp, and reason
Context-Aware Viewer Experience
"As a caregiver on a shared device, I want scanning a QR to take me straight to the resident timeline in my signed-in session so that I don’t waste time searching."
Description

Resolve each deeplink into the correct experience based on platform, session state, and role: on shared facility devices, open the resident timeline in the signed-in staff app with write permissions; for families, route to a read-only web or app view after lightweight authentication. Present clear states for expired/denied links with a renewal or help path, and never display PHI until authorization completes. Defer to installed app via universal/app links with responsive fallback to web, and preserve the resident context through login flows to avoid re-navigation.

Acceptance Criteria
Staff on Shared Device Scans QR for Resident During Rounds
Given a shared facility device with the staff app installed and a signed-in staff user with write permissions When the user scans a valid, unexpired resident QR Then the app opens directly to that resident’s timeline in the staff app And write actions (photo upload, note, voice-to-text) are enabled And no re-authentication prompt is shown if the session is active And resident context persists if the app was backgrounded And an access event is logged with timestamp, staff ID, device ID, resident ID, and QR token ID
Family Member Opens QR Link on Personal Phone Without App
Given an approved family contact with a valid, unexpired QR link and no app installed When the contact taps the link Then a responsive web view opens to the resident’s timeline in read-only mode And a one-time passcode challenge is sent to the registered email/SMS And no PHI is loaded until the OTP is verified And upon successful OTP verification, only the resident’s timeline is visible with read-only controls And the session auto-logs out after 15 minutes of inactivity And the access event is logged with contact ID, channel, and outcome
Universal Link Defers to Installed App With Fallback to Web
Given a device with the KinLoop app installed and an approved family user for the resident When the user taps the QR deeplink Then the system attempts to open the app via universal/app link And if the app opens, it routes to the resident’s read-only timeline view And if the app does not open within 2 seconds, the link falls back to the web view And in both cases, the resident context is preserved without additional navigation
Expired or Revoked Link Handling
Given a QR/link that is expired or the viewer’s permission has been revoked When any user scans or opens the link Then no PHI or resident metadata is displayed And a clear state is shown indicating Expired or Access Denied And a renewal/help path is provided to request a new link or contact the facility And the attempt is logged with a reason code (expired/revoked) and no data exposure
Authentication Flow Preserves Resident Context
Given a valid QR/link to a resident’s timeline and the user is not authenticated When the user completes login or OTP verification Then the app/web redirects directly to that resident’s timeline And no intermediate menu navigation is required And the back action returns the user to the prior app/page state without losing the resident context
Permission-Aware Write vs Read Enforcement
Given a valid QR/link opened by a signed-in staff user with write permissions When the timeline loads Then write actions are enabled for that resident Given the same link opened by an approved family user When the timeline loads Then only read-only actions are available and write controls are hidden/disabled And any attempt to access write endpoints returns HTTP 403 and is logged
Audit Logging Completeness for QR Access
Given any QR/link open attempt, successful or failed When the event occurs Then an audit record is created with: timestamp, actor type (staff/family/unknown), user ID if known, resident ID, device/platform, app/web, IP, token ID, outcome (success/denied/expired), and actions performed And audit logs are immutable and queryable by resident and date range And logs do not store PHI in the record body
Offline and Poor Connectivity Handling
"As a caregiver in low-signal areas, I want QR scans to work reliably and complete when back online so that my workflow isn’t disrupted."
Description

Optimize QR scanning and link resolution for low-connectivity environments by minimizing payload size, retrying with exponential backoff, and queuing unresolved scans for background completion when connectivity returns. Provide clear, non-PHI placeholders while awaiting validation and prevent cached data from being displayed without authorization. Cache the resident directory index for faster resolution on authenticated staff devices, while ensuring tokens are always validated server-side before revealing content.

Acceptance Criteria
QR Scan in Airplane Mode
Given the device has no network connectivity When a user scans a valid KinLoop QR for a resident Then the app does not render any timeline content And shows a non-PHI placeholder message “Validating access…” within 300 ms And enqueues a resolve task containing only the opaque token, scan timestamp, and device ID hash And stores the task persistently to survive app restarts And no PHI is stored with the task And no cached resident or timeline data is displayed prior to validation
Exponential Backoff Retry Under Poor Connectivity
Given network requests to validate the QR token fail due to timeout or transient errors When the resolve task runs Then it retries with exponential backoff intervals of 1s, 2s, 4s, 8s, 16s (max 5 attempts) And each attempt has a 5s network timeout And retries cease immediately on HTTP 401, 403, or 410 And upon exhausting retries, a non-PHI error state is shown with a “Try Again” action And client telemetry records attempt counts, error codes, and total time to resolution
Background Completion of Queued Scans
Given a queued resolve task exists and connectivity is restored When the app is foregrounded or a background fetch event fires Then the task is attempted within 10 seconds And on successful server validation the resident timeline opens automatically if the app is foreground And if in background, a notification “Resident timeline ready” (no PHI) is posted And the task is removed from the queue upon success And if the same QR is rescanned within 10 minutes, resolution is idempotent (no duplicate opens)
Payload Minimization for QR and Resolve Call
Given a KinLoop QR/link is generated Then the QR/link payload contains only an opaque, signed, time-limited token of ≤ 256 characters with no resident-identifying fields And the initial resolve HTTP request payload is ≤ 10 KB over the wire (excluding TLS), compressed (gzip or br), and contains no images or media And the app defers any timeline/media requests until after a 200 validation response And invalid/expired tokens return 401/403/410 with no body containing PHI
Prevent Display of Cached Data Without Authorization
Given resident timeline data exists in local cache And a QR/link is scanned When server validation has not yet succeeded Then no cached timeline entries, media, or resident details are rendered And if validation returns 401/403/410, cached data remains hidden and is not displayed And a non-PHI error state is shown with options to retry or dismiss And cached data remains encrypted at rest and is only decrypted after a 200 validation that matches resident ID and the current authenticated user
Cached Resident Directory Index on Authenticated Devices
Given a staff user is authenticated When the resident directory index is fetched Then a minimal index (residentId, roomNumber, consent flags, avatar placeholder metadata) is cached encrypted at rest with a 24h TTL And the index is available offline to assist token-to-resident resolution but does not permit timeline content rendering And on user logout the cached index is securely wiped And on next online session a delta refresh runs within 5 seconds of app foregrounding
Server-Side Token Validation Before Content Reveal
Given a QR/link is scanned or opened When the server returns a 200 validation response Then the app logs access (token ID, user ID, device ID hash, timestamp) server-side And only then requests and renders the first page of the resident timeline And if validation exceeds 8 seconds, a progress indicator remains visible with no PHI And if validation returns 410 (expired), the app offers a flow to request a new link without exposing PHI

VoicePIN Shield

Secure, friction-light caller verification that binds each resident’s line to an authorized contact via PIN, with optional caller‑ID recognition and one‑time codes delivered by SMS or voice for landlines. Attempts and resets are logged for audits, giving families easy access without an app while protecting privacy and reducing staff time spent on identity checks.

Requirements

Secure PIN Enrollment & Binding
"As a community administrator, I want to bind each resident’s line to authorized contacts with a private PIN so that callers can be verified quickly without burdening staff."
Description

Provide staff-initiated or self-service enrollment that binds an authorized contact to a resident’s phone line with a unique numeric PIN. Admins trigger enrollment from the KinLoop console; contacts validate identity via SMS link or automated call before creating a 4–8 digit PIN. Store only salted, memory-hard hashes with KMS-managed salts; associate one or more phone numbers to the contact and resident; capture consent and terms. Support multiple authorized contacts per resident, revocation and re-binding, and real-time enrollment status via API. All steps must be recorded in the audit log.

Acceptance Criteria
Admin-Initiated Enrollment via Console
Given an admin with enrollment permission selects resident R and contact C in the KinLoop console When the admin clicks "Start Enrollment" and chooses SMS or Voice delivery Then the system creates an enrollment record with status "pending_validation" bound to R and C and logs "enrollment_initiated" Given an enrollment record exists When the delivery is triggered Then a one-time validation link (SMS) or one-time validation code (voice) is generated and sent to the selected phone number and the event "validation_sent" is recorded with a correlation ID Given a prior outstanding enrollment token exists for the same resident-contact pair When a new enrollment is initiated Then all prior tokens are invalidated and marked "superseded" in the audit log
Identity Validation via SMS Link or Automated Call
Given a contact receives the SMS validation link When they open the link from the same phone number it was sent to Then the system verifies the token is valid, unused, and unexpired and advances to the PIN creation step; otherwise the flow is blocked with an "invalid or expired" message and an option to resend Given a contact receives an automated validation call When they successfully enter the read-back one-time code from that call Then validation succeeds and advances to the PIN creation step; otherwise the attempt is recorded as a validation failure without advancing Given validation succeeds When the system updates the enrollment Then status changes to "validated" and the event "validation_success" is logged
PIN Creation Policy (4–8 Digit Numeric)
Given an enrollment is in "validated" state When the contact enters a numeric PIN between 4 and 8 digits and confirms with a matching entry Then the PIN is accepted and bound to the resident-contact pair Given a PIN entry contains non-numeric characters, is shorter than 4 digits, is longer than 8 digits, or the confirmation does not match When the contact attempts to proceed Then the system rejects the submission with specific validation errors and does not set a PIN Given a PIN is successfully set When the system completes enrollment Then no plaintext PIN is stored or logged and the event "pin_set" is recorded without the PIN value
Consent and Terms Capture
Given a contact is on the PIN creation step When the current Terms of Use and Privacy Notice (with version identifier) are presented Then the "Set PIN" action remains disabled until the contact explicitly agrees via a consent checkbox Given the contact provides consent When the PIN is set Then the system stores consent details (contact ID, resident ID, terms version, timestamp, consent method) and records the event "consent_captured" Given the terms version changes during an ongoing enrollment When the contact resumes the flow Then the latest version is presented and any captured consent reflects the actual version accepted
Secure Storage of PINs (Salted Memory-Hard Hashes via KMS)
Given a PIN has been accepted When persisting credentials Then the system stores only a salted, memory-hard hash of the PIN using a KMS-managed salt and never stores or transmits the PIN in plaintext Given the hash is created When recording metadata Then the system references the KMS key identifier and salt metadata and records "pin_hash_created" without exposing secret material Given a subsequent PIN verification is performed When the memory-hard hash check cannot be completed due to KMS or crypto errors Then verification fails closed and no PIN value or intermediate secrets are logged
Phone Number Association; Multiple Authorized Contacts per Resident
Given a resident-contact enrollment is active When the user adds one or more phone numbers for the contact Then each number remains "unverified" until ownership is validated via SMS or automated call and becomes "active" only after successful validation Given multiple authorized contacts exist for the same resident When each completes enrollment Then each contact has an independent PIN and phone associations and no actions by one contact alter another contact's credentials Given a phone number is removed by an admin When the change is saved Then the number is disassociated from the resident-contact binding, can no longer be used for validation or caller verification, and the event "number_removed" is logged Given a revoked contact is re-bound to the same resident When re-binding is requested Then prior tokens and PINs are invalidated, a fresh identity validation is required, and the event "rebound" links to the prior revocation in the audit trail
Real-Time Enrollment Status API and Audit Logging
Given an authorized client calls the enrollment status API for a resident-contact pair When the enrollment exists Then the API responds with the current status in {"pending_validation","validated","active","revoked"} and includes key timestamps and last_event; if none exists it returns a 404 Given any enrollment lifecycle action occurs (initiation, validation sent/success/failure, pin set, consent captured, number added/removed, revocation, re-binding) When the action completes Then an audit log entry is created with timestamp, actor (admin/contact/system), resident_id, contact_id, event_type, and correlation ID Given a PIN is successfully set When the status API is called Then it reflects status "active" without delay Given a revocation is performed When the status API is called Then it reflects status "revoked" and the audit log contains a reason and actor for the revocation
IVR Call Verification Flow
"As an authorized family member, I want a simple phone menu that verifies me by PIN so that I can reach updates without repeating identity checks."
Description

Implement an automated IVR that answers resident-associated lines, detects caller ID, and routes the caller to verification. If the caller ID matches a known number and policy allows, prompt for PIN; otherwise offer one-time code delivery or staff transfer. Support DTMF input, configurable retries, timeouts, and lockouts. Provide clear, concise prompts and low-latency routing. Surface verification outcomes to the KinLoop console and resident directory, and log reason-coded results. Multilingual prompts and graceful degradation on noisy or low-quality lines are required.

Acceptance Criteria
Known Caller ID: PIN Verification Path
Given an inbound call to a resident-associated line and the caller ID matches an authorized contact and policy allows CID-based PIN flow When the IVR answers the call Then the first prompt plays within 3 seconds of answer and requests a 4–8 digit PIN via DTMF Given the caller is entering a PIN via DTMF When each digit is pressed Then tones are accepted for 0–9,*,# and input is masked and no PIN value is read back Given the caller is entering a PIN When no input is received within 5 seconds Then the IVR reprompts and allows up to 3 PIN attempts per call Given the caller enters a correct PIN within 3 attempts When verification completes Then the caller is verified within 2 seconds and routed to the authorized menu for that resident and a reason code PIN_SUCCESS is logged with timestamp and caller ID and the console shows the verified status within 5 seconds Given the caller enters an incorrect PIN 3 times When the third attempt fails Then the caller is offered the one-time code option or transfer to staff and a reason code PIN_FAIL_MAX is logged
Unknown Caller ID: One-Time Code (SMS/Voice) Verification
Given an inbound call to a resident-associated line and caller ID does not match an authorized number or policy denies CID-based flow When the IVR answers Then the caller is offered verification by one-time code with options for SMS (mobile) or voice call (landline) Given the authorized contact has a mobile number on file When SMS is selected Then a 6-digit code is sent within 10 seconds and the code expires in 5 minutes and delivery outcome is recorded and reason code OTP_SENT_SMS is logged Given the authorized contact has only a landline on file or SMS delivery fails When voice delivery is selected or fallback occurs Then a TTS voice call delivers a 6-digit code within 20 seconds and reason code OTP_SENT_VOICE is logged Given the caller is entering the one-time code When the code matches within 3 attempts and before expiry Then verification succeeds and routing occurs within 2 seconds and reason code OTP_SUCCESS is logged and the console updates within 5 seconds Given the caller fails 3 OTP attempts or the code expires When verification cannot complete Then the caller is offered resend once and then transfer to staff and reason code OTP_FAIL_MAX or OTP_EXPIRED is logged
Lockouts, Rate Limiting, and Staff Transfer
Given repeated failed verification attempts across PIN and OTP in a single call When failures reach the configured maximum (default 5) Then the caller is temporarily locked out for 15 minutes and informed without disclosing resident details and reason code LOCKOUT is logged Given high-frequency calls from the same caller ID or to the same resident line When more than 10 verification attempts occur within 10 minutes Then subsequent attempts are rate-limited with a backoff message and reason code RATE_LIMIT is logged Given the caller requests human assistance or is locked out When the caller presses 0 at any prompt Then the IVR transfers to the staff line or queue within 15 seconds on average and reason code TRANSFERRED_TO_STAFF is logged Given the caller has not been verified When any failure or transfer occurs Then no resident name or PHI is played prior to verification
Multilingual Prompts and Degraded-Line Handling
Given an inbound call reaches the IVR When the greeting plays Then the caller is offered English and Spanish via DTMF and English is the default after 8 seconds of no input and the selection is remembered per caller ID for future calls Given the system detects two consecutive input timeouts or low DTMF confidence When degraded mode is triggered Then digit collection timeout increases from 5 to 8 seconds and TTS speech rate is reduced by 15% and key prompts are repeated once automatically Given the caller is interacting under degraded mode When inputs are received Then DTMF recognition accuracy is at least 99% at SNR ≥ 10 dB in test conditions and fallbacks do not exceed two repeats per step Given prompts are rendered in the selected language When validation is performed Then all mandatory prompts (greeting, verification choices, error, transfer, success) are localized and free of resident-identifying details pre-verification
Configurable Retries, Timeouts, and Policies
Given an admin with appropriate permissions updates IVR verification settings in KinLoop When values for PIN attempts, OTP attempts, input timeout, lockout duration, and rate limits are changed within allowed ranges (e.g., PIN attempts 1–5, OTP attempts 1–5, input timeout 3–10s, lockout 5–60m) Then the settings save with audit trail (who, what, when) and reason code CONFIG_UPDATE is logged Given configuration changes are saved When the IVR handles new calls Then new settings take effect within 5 minutes without dropping active calls and are applied per facility and resident line policy Given policy toggles exist for CID-based PIN path and OTP availability When a policy is disabled Then the corresponding option is not offered to callers and the flow follows remaining enabled methods
Verification Outcomes Surfaced to Console and Audit Log
Given any verification attempt occurs When the call ends or verification completes Then an immutable audit record is written containing call start/end timestamps, resident ID, caller ID (when available), selected method, attempt counts, outcome reason codes, and transfer flag Given a verification outcome (success or failure) When staff view the KinLoop console or resident directory Then the latest outcome appears within 5 seconds with status, method (PIN/OTP), caller ID (masked per policy), and timestamp and is filterable by date range and outcome Given an auditor requests history When exporting verification logs from the console Then a CSV export is available containing the last 365 days for the facility with reason codes including PIN_SUCCESS, PIN_FAIL_MAX, OTP_SENT_SMS, OTP_SENT_VOICE, OTP_SUCCESS, OTP_FAIL_MAX, OTP_EXPIRED, LOCKOUT, RATE_LIMIT, TRANSFERRED_TO_STAFF, CONFIG_UPDATE
One-Time Code Delivery via SMS/Voice
"As a family member using a landline, I want to receive a one-time code by voice when I call so that I can verify my identity without a smartphone or app."
Description

Generate single-use 6-digit verification codes with short expiry, rate-limited issuance, and replay protection. Deliver via SMS to mobile or text-to-speech voice calls for landlines, auto-detecting channel capabilities and falling back when delivery fails. Integrate through a provider-agnostic gateway with delivery receipts, regional formatting, and opt-in messaging compliance. Expose verify endpoints, mask numbers in logs, and record send/verify events with timestamps and outcomes.

Acceptance Criteria
6-Digit OTP Generation with Short Expiry and Single-Use
Given an authorized contact requests verification for a resident line When an OTP is generated Then a 6-digit numeric code is created And the code expiry is set to 5 minutes from issuance And any previously active OTP for the same contact–resident pair is invalidated And the raw OTP is never stored—only a salted hash is persisted
Issuance Rate Limiting and Abuse Prevention
Given a phone number and resident binding When more than 3 OTPs are requested within 15 minutes Then the API responds 429 Too Many Requests with a Retry-After header And no new OTP is generated And a daily cap of 10 OTPs per 24 hours per phone number is enforced And rate-limit counters reset after their respective windows elapse
Channel Auto-Detection with SMS Primary and Voice Fallback
Given the destination number supports SMS When an OTP is sent Then it is delivered via SMS using the recipient's locale template And if the provider returns Undeliverable or no Delivery Receipt within 60 seconds Then a voice call with TTS delivers the OTP within 30 additional seconds Given the destination number is a landline or SMS-disabled When an OTP is sent Then a voice call with TTS delivers the OTP on the first attempt And the message states the code digits clearly and repeats once
Provider-Agnostic Gateway with Delivery Receipts and Failover
Given a send request is made When the primary SMS/voice provider returns a 5xx or network timeout Then the system retries up to 2 times and fails over to a secondary provider within 10 seconds And idempotency ensures at most one user-facing message per request Given providers emit delivery receipts When receipts are received Then send events are updated to Delivered or Failed with provider message IDs and timestamps And undetermined statuses are marked Pending and resolved on timeout (max 5 minutes)
Verify Endpoint Responses, Attempt Limits, and Replay Protection
Given a correct, unexpired OTP for the phone/resident binding When the caller submits the code Then the API returns 200 Verified and marks the OTP as used (single-use) Given an incorrect OTP When the caller submits the code Then the API returns 400 Invalid_Code and increments the attempt counter Given an expired OTP When the caller submits the code Then the API returns 400 Expired_Code And after 5 failed attempts or upon expiry Then the OTP is locked and no further verification is accepted
Privacy and Security in Logs, Events, and Webhooks
Given send or verify actions occur When events are logged or exported Then phone numbers are masked to last 4 digits and E.164 stored only in encrypted storage And OTP values never appear in logs, traces, or analytics And provider webhooks are redacted/masked before logging And audit records include only masked phone, channel, timestamps, outcome, and provider IDs
Regional Number Formatting and Messaging Consent Compliance
Given a phone number is entered When processing begins Then the number is normalized to E.164 format with country detection Given SMS channel is used in regulated regions (e.g., US/CA/EU) When an OTP SMS is sent Then the message includes the brand name (KinLoop), purpose, expiry, and STOP/HELP instructions where required And SMS is only sent if opt-in consent exists with stored timestamp, source, and locale And if SMS consent is absent or revoked, the system uses voice call instead and records the reason
Caller ID Recognition & Linking
"As an authorized contact, I want my known phone numbers recognized when I call so that verification feels faster while staying secure."
Description

Maintain a mapping of authorized callers’ phone numbers to residents and contacts. On inbound calls, match ANI to known numbers and apply configurable trust policies, such as reduced friction within a recent successful verification window; otherwise require PIN or OTP. Allow contacts to add or remove numbers with secondary verification, support multiple numbers per contact, international formats, and number normalization. Notify admins on new number linking attempts and provide self-link flows with safeguards.

Acceptance Criteria
ANI Match Applies Trust Window
Given an inbound call arrives with ANI +15551234567 linked to Contact A for Resident R And a successful verification for Contact A occurred within the configured trust window (default 30 days) When the call is connected Then the system recognizes the caller as Contact A for Resident R And no PIN or OTP challenge is required And the decision reason "trusted_within_window" is stored with timestamp and call ID Given an inbound call arrives with ANI linked to a contact but no successful verification within the trust window When the call is connected Then the system requires PIN or OTP verification before any resident information is accessible And upon successful verification, the trust window timer is reset from the current timestamp for that contact-number pairing Given tenant configuration disables the trust window policy When any inbound call arrives, even with matched ANI Then the system always requires PIN or OTP verification
Unknown or Withheld ANI Requires Verification
Given an inbound call arrives with ANI missing, private/blocked, or not found in the mapping When the caller interacts with the IVR Then the caller must pass PIN or OTP verification prior to accessing any resident-specific information And OTP can be delivered via SMS for mobile numbers or text-to-speech voice for landlines, as selected by the caller And OTP sends are rate limited to a maximum of 3 per 15 minutes per candidate number, with exponential backoff on further requests And more than 5 failed verification attempts for the same ANI or candidate number within 24 hours place it on a temporary watchlist for 24 hours, blocking self-link attempts
Self-Link New Number with Secondary Verification
Given an authorized contact has at least one previously verified number on file When the contact initiates the IVR self-link flow to add a new number N Then the system sends a secondary verification OTP to one of the contact's existing verified numbers And only if the secondary OTP is verified within 10 minutes, the system normalizes N to E.164 and links it to the contact and resident And if N is already linked to another contact or resident, the system rejects the link with reason "number_in_use" and makes no changes And an admin notification of the attempt (success or failure) is generated within 60 seconds with masked number and reason code
Multiple Numbers Per Contact with E.164 Normalization
Given a contact submits numbers in formats such as "(555) 123-4567", "+1 555-123-4567", and "5551234567" When the numbers are saved Then they are normalized to the same canonical E.164 number +15551234567 and stored as a single linkage record without duplicates Given a contact has multiple distinct numbers across different country codes When an inbound call arrives from any of those numbers Then the system matches the canonical record for that contact and applies the configured trust policy consistently Given a number uses local formatting with leading zeros for a supported country When normalized Then the stored value is converted to E.164 with correct country code per tenant default country settings or explicit country prefix
Admin Notifications and Safeguards on Self-Link Attempts
Given any self-link attempt occurs for a resident (success or failure) When the attempt is submitted Then an admin dashboard alert is visible within 1 minute showing contact ID, resident ID, masked number, outcome, and reason code Given more than 3 failed self-link attempts for the same number occur within 30 minutes When the threshold is reached Then the number is flagged as "suspicious" and further self-link attempts are blocked for 24 hours, and admins are notified of the block Given the tenant setting "require_admin_approval_for_first_number" is enabled When a contact with no verified numbers attempts to link a first number Then the link remains in "pending_admin_approval" until an admin approves it, after which the number becomes active
Self-Unlink of Number with Secondary Verification and Last-Number Safeguard
Given a contact has two or more verified numbers linked When the contact initiates the IVR self-unlink flow for one number Then the system sends a secondary verification OTP to a different verified number on file And only upon successful secondary verification does the system immediately de-authorize the target number and update the mapping Given a contact has exactly one verified number linked When the contact attempts to self-unlink that last number Then the system blocks the action with reason "last_number_protection" and prompts for admin-assisted removal Given a number is successfully unlinked When the action completes Then admins receive a notification within 60 seconds and the event is visible in audit logs
Audit Trail Completeness for Caller ID and Linking Events
Given any of the following events occur: ANI match decision, PIN verification success/failure, OTP send, OTP verification success/failure, self-link attempt success/failure, unlink action, trust window application When the event completes Then an immutable audit entry is written with UTC timestamp, actor (system/contact/admin), resident ID(s), contact ID, masked phone (+E.164, last 4 visible), action, outcome, and reason code Given an admin with appropriate permissions views audit logs When the logs are requested Then new entries are visible within 5 seconds of event completion and are filterable by resident, contact, phone, action, and date range Given a compliance export is requested for a resident covering the past 24 months When the export is generated Then 100% of the resident's related call verification and link/unlink events in that period are included in machine-readable format
Audit Logging & Admin Console
"As a compliance officer, I want detailed, searchable logs of all verification attempts and resets so that I can audit access and investigate issues."
Description

Create centralized, tamper-evident logging for all VoicePIN events: timestamps, resident/contact references, masked phone numbers, method (PIN/OTP), attempt counts, outcomes, and admin actions (enrollment, reset, revocation). Build an admin console to search, filter, and export logs; view per-resident and per-contact histories; and configure retention policies. Enforce role-based access controls and least-privilege permissions, with alerts on anomalous activity patterns.

Acceptance Criteria
Tamper‑Evident VoicePIN Event Logging Completeness
Given any VoicePIN action occurs (PIN verification, OTP generation/verification, enrollment, reset, revocation) When the system records the event Then the log entry includes eventId (UUIDv4), timestampUTC (ISO‑8601), residentId, contactId, maskedPhone (XXX‑XXX‑1234), method (PIN|OTP), attemptCount (integer), outcome (Success|Failure) with failureReason (enum when Failure), and actor (system|adminUserId) And the entry is append‑only and contains prevHash and hash computed over immutable fields And hash‑chain verification over the most recent 10,000 entries completes with no gaps or mismatches When any stored entry is altered Then the next verification run (within 5 minutes) flags the chain break and creates an IntegrityViolation alert in the admin console
Admin Console Search, Filter, and Pagination
Given at least 50,000 log entries exist When an authorized user searches by residentId, contactId, last4 of maskedPhone, or adminUserId and applies filters (date range, eventType, method, outcome) Then results reflect the intersection of search and filters, sorted by timestampUTC descending, with an accurate total count And the first page renders within 2 seconds on cold cache and within 1 second on warm cache And pagination shows 50 results per page by default, preserving sort and filters across pages And invalid filter values are rejected with inline validation without executing the query
Log Export (CSV) with Masking and Audit Trail
Given filters are applied to the current log view When a user with role Auditor or Admin requests an export Then a CSV is generated containing only the filtered rows with columns: eventId,timestampUTC,residentId,contactId,maskedPhone,method,attemptCount,outcome,failureReason,actor,prevHash,hash And all phone numbers remain masked; no unmasked PII is present in the file And up to 100,000 rows are included per export; if more rows match, the user is prompted to narrow the range And the CSV filename encodes date range and an accompanying SHA‑256 checksum is provided And an ExportCreated action is logged with exporterUserId,rowCount,filterSummary,fileChecksum
Per‑Resident and Per‑Contact History Views
Given a resident profile is opened in the admin console When the VoicePIN History tab is selected Then a chronological list of that resident’s VoicePIN events for the last 90 days is displayed with totals (successes, failures, OTP sends) and admin actions And filters (date range, eventType) apply only to that resident And selecting an event opens a detail view with all fields for that log entry And a contact profile shows an equivalent history view scoped to that contactId
Retention Policy Configuration and Enforcement
Given a user with Admin role opens Retention Settings When the global retention is set to N days within 30–1825 and saved with a required reason Then the change is validated, versioned, and a RetentionUpdated action is logged with prior and new values And per‑facility overrides can be set within the same bounds and are applied ahead of the global value And a daily purge runs at 02:00 facility local time deleting entries older than the effective retention, excluding items under Legal Hold And when a Legal Hold is created for a residentId or date range, affected entries are excluded from purge and a LegalHoldCreated action is logged And purge runs emit a summary log with deletedCount and duration; no held entries are removed
Role‑Based Access Control and Least Privilege
Given roles are defined as Viewer, Auditor, and Admin When a Viewer accesses the console Then they can view logs and histories but cannot export or modify retention; attempted restricted actions return 403 and are logged as AccessDenied When an Auditor accesses the console Then they can view and export logs but cannot modify retention settings or roles When an Admin accesses the console Then they can view, export, modify retention, manage legal holds, and manage roles And all actions include requesterUserId and source IP; role changes are logged with before/after values And API endpoints enforce identical permissions as the UI
Anomalous Activity Alerts
Given failed authentication activity occurs When 5 failed PIN verifications for the same residentId happen within 10 minutes Then a ResidentBruteForceSuspected alert is created within 1 minute and visible in the admin console Alerts feed When failures from the same callerId affect 3 or more different residents within 15 minutes Then a CrossResidentAttackSuspected alert is created When 10 or more OTP sends to the same maskedPhone occur within 30 minutes Then an ExcessiveOTP alert is created And alerts are deduplicated (one active per pattern per 30‑minute window), require acknowledgment by an Auditor or Admin, and all alert lifecycle events (create, acknowledge, resolve) are logged
PIN Reset & Recovery Workflow
"As an authorized contact, I want an easy, secure way to reset my PIN if I forget it so that I can regain access without staff intervention."
Description

Provide secure flows for contacts to reset forgotten PINs via SMS/voice identity checks, with cooldowns, rate limits, and notifications to resident admins upon changes. Support staff-initiated resets with dual-approval for high-risk cases. Invalidate previous credentials immediately, require re-verification on next call, and maintain full audit trails. Include accessible prompts and simple guidance throughout the process.

Acceptance Criteria
Self-Service PIN Reset via SMS OTP
Given an authorized contact with a verified mobile number on file When they request a PIN reset and select SMS verification Then the system sends a 6-digit OTP via SMS to the number on file And the OTP expires after 10 minutes And OTP entry is limited to 3 attempts before a 15-minute lockout applies And upon correct OTP entry, the user is required to set a new 4–8 digit numeric PIN that does not match any of the last 4 PINs And the previous PIN becomes invalid immediately upon successful reset And resident admins receive a notification within 1 minute containing masked contact info, resident ID, and timestamp And an audit log entry is recorded with event type, actor (contact ID), channel (SMS), timestamp, masked destination, and outcome
Self-Service PIN Reset via Voice Call OTP (Landline)
Given an authorized contact with a landline number on file and no SMS capability When they request a PIN reset and select voice call verification Then the system places an automated call to the number on file and reads a 6-digit OTP twice And the caller may press 1 to repeat or 2 to slow playback; the system supports digit-by-digit readback on request And the OTP expires after 10 minutes and is limited to 3 entry attempts before a 15-minute lockout applies And upon correct OTP entry, the caller must set a new 4–8 digit numeric PIN via DTMF, confirmed by re-entry And the previous PIN becomes invalid immediately upon successful reset And resident admins receive a notification within 1 minute containing masked contact info, resident ID, and timestamp And an audit log entry is recorded with event type, actor (contact ID), channel (Voice), ANI, timestamp, and outcome
Cooldowns and Rate Limits on PIN Reset Attempts
Given any contact attempts PIN reset via SMS or Voice When multiple reset requests are made Then the system enforces a maximum of 2 reset requests per 15 minutes and 5 per 24 hours per contact and per phone number And after 3 consecutive lockouts within 24 hours, further attempts are blocked for 24 hours And the user is shown/heard a clear message with the next eligible time for retry without revealing account existence beyond what is already verified And rate-limit and lockout events are recorded in the audit log with correlation IDs And rate limits apply across all resident lines bound to the same phone number
Staff-Initiated High-Risk Reset with Dual Approval
Given a staff member with Reset Initiator role selects a high-risk PIN reset for a contact When they submit the reset request with a reason code Then a staff member with Reset Approver role (not the initiator) must approve within 30 minutes for the reset to proceed And both initiation and approval require authenticated staff credentials and are recorded with staff IDs, timestamps, and reason codes And upon approval, the contact’s previous PIN is invalidated immediately and the contact is required to verify via OTP on next use before setting a new PIN And resident admins and the contact receive notifications within 1 minute indicating a staff-initiated reset occurred And if approval is not granted within 30 minutes, the request expires and no changes occur; an expiry event is logged
Immediate Credential Invalidation and Next-Call Re-Verification
Given a PIN reset (self-service or staff-approved) is completed When the same contact attempts to authenticate using the prior PIN on any resident-bound line Then the prior PIN is rejected with a generic failure message that does not disclose reset details And the contact is prompted to re-verify via OTP before using or creating the new PIN And after 3 failed authentication attempts, a 15-minute lockout applies And all failed attempts are logged with timestamps, channel, and outcome
Comprehensive Audit Trail for Reset and Recovery Events
Given any reset-related event occurs (request, OTP sent, OTP verified, PIN changed, lockout, notification, staff actions) When the event is processed Then an immutable audit record is created containing resident ID, contact ID, event type, channel (SMS/Voice/Staff), timestamps (request, send, verify, change), masked destinations, IP/ANI, actor/approver IDs, reason codes, correlation ID, and outcome And audit records are tamper-evident and retained for a minimum of 7 years And authorized admins can export filtered audit logs (CSV) by date range, resident, or contact And audit access is permission-gated and access events themselves are logged
Accessible Guidance in SMS and Voice Reset Flows
Given a contact engages with the reset flow via SMS or Voice When prompts and instructions are presented Then instructions use clear, plain language at or below 8th-grade readability without jargon And SMS messages are ≤160 characters each, include step-by-step next actions, and avoid sending full PINs or sensitive data And Voice prompts support repeat, slower playback, and digit-by-digit OTP readback; total prompt length per step ≤20 seconds And all error messages state what went wrong and exactly how/when to try again without disclosing sensitive account details And localized English/Spanish support is available, with the user’s preferred language applied if on file
Security Controls & Abuse Prevention
"As an operations manager, I want protections against brute-force and fraud so that residents’ privacy is safeguarded and staff time isn’t wasted."
Description

Implement layered defenses: per-number and per-resident rate limits, exponential backoff, temporary lockouts after consecutive failures, and anomaly detection on verification attempts. Encrypt data in transit and at rest; manage secrets and keys via KMS; and make PIN length, retry, and expiry policies configurable. Provide monitoring dashboards, health checks, and alerting for failures and abuse signals. Document data minimization and retention to support privacy requirements.

Acceptance Criteria
Per-Number and Per-Resident Rate Limiting with Exponential Backoff
- Given default configuration, when the same phone number attempts verification for the same resident more than 5 times within 5 minutes, then subsequent attempts are rejected with a throttle response and Retry-After metadata and are not evaluated. - Given default configuration, when the same phone number attempts verification across any residents more than 20 times within 60 minutes, then subsequent attempts are blocked for 60 minutes. - Given repeated failures for a number-resident pair, when additional attempts are made, then exponential backoff is enforced at 1s, 2s, 4s, 8s, capped at 30s between prompts or API responses, and the remaining wait is communicated to the caller. - Given a successful verification for a number-resident pair, then backoff counters and rolling windows for that pair reset immediately. - Given an admin updates the policy to 10 attempts per 5 minutes via the configuration API, then the new threshold takes effect within 60 seconds and is reflected in the monitoring dashboard. - Then all throttled/blocked attempts are audit-logged with timestamp, residentId (pseudonymous), caller identifier (hashed), reason code, and correlationId.
Temporary Lockouts After Consecutive Failures
- Given 6 consecutive failed PIN/OTP entries for a number-resident pair within 15 minutes, then the pair is locked out for 15 minutes and further attempts return code VLOCK-15 with remaining time. - Given 3 or more lockouts for the same pair within 24 hours, then subsequent lockouts escalate to 60 minutes until 24 hours pass without further lockouts. - Given a lockout is active, then PIN/OTP reset requests via an alternate previously verified channel are allowed and fully audit-logged (actor, channel, outcome, correlationId). - Given an authorized staff member with MFA issues an override, then the lockout is cleared immediately and the override is audit-logged with userId and justification. - Given configuration updates for thresholds/durations, then values outside allowed ranges are rejected with validation errors and no partial updates are applied.
Anomaly Detection and Auto-Mitigation for Verification Attempts
- Given more than 3 distinct caller numbers attempt verification for the same resident within 10 minutes, then an anomaly is flagged (severity=medium) and OTP is required for that resident for the next 60 minutes even if caller-ID is recognized. - Given more than 50 verification attempts originate from the same network ASN or geo region within 15 minutes across residents, then stricter backoff (+100% delay cap) is applied globally for that source and a security alert is sent to on-call within 60 seconds. - Given an anomaly is flagged, then a dashboard marker and case record are created aggregating related events and mitigations. - Given no further triggering events occur for 30 minutes, then mitigations auto-expire and the case is closed with a closure note and metrics snapshot.
Transport and At-Rest Encryption with KMS-Managed Keys
- Given any client or service connection, then TLS 1.2+ with modern ciphers and HSTS is enforced; connections failing policy are refused and logged. - Given sensitive data (PIN hashes, attempt logs, phone identifiers), then it is encrypted at rest using AES-256-GCM with keys managed in KMS; PINs are stored only as Argon2id hashes with per-record salt and a KMS-stored pepper; plaintext PINs/OTPs are never persisted. - Given key rotation at least every 90 days, then rotations occur without downtime; prior keys remain decrypt-only for 180 days; all rotations are audit-logged. - Given application secrets access, then least-privilege KMS policies are enforced; secret values never appear in logs or metrics; any access is logged and visible in audits.
Configurable PIN/OTP Policies and Administrative Auditability
- Given an admin sets PIN length to 6 digits, then new PIN creations must be 6 digits; existing 4-digit PINs continue to validate until the next reset; the policy change is audit-logged with actor and before/after values. - Given OTP expiry is set to 120 seconds, then OTPs older than 120 seconds are rejected with code OTP-EXPIRED; clock skew tolerance is ±30 seconds. - Given max retries per verification session is set to 3, then after 3 failed entries the session requires a new OTP and further entries are refused. - Given an invalid policy value is submitted (e.g., PIN length 3 or 12), then the update is rejected with 400 and field-level error details; no partial policy changes are applied. - Given a policy change is made, then the new policy is propagated and effective across all services within 60 seconds and is visible on the admin policy dashboard.
Monitoring, Health Checks, and Alerting for Abuse and Failures
- Given /healthz and /ready endpoints, then they report dependency checks for KMS, datastore, and SMS/voice providers; any failing dependency sets /ready to 503 with component details. - Given verification volume exceeds 500 attempts per minute or error rate exceeds 5% for 5 consecutive minutes, then alerts are sent to on-call via the configured channels within 2 minutes and include links to dashboards and recent logs. - Given operational dashboards, then they display near real-time (<30s latency) metrics for attempts, success rate, throttles, lockouts, OTP delivery failures, KMS latency/errors, and anomaly counts. - Given an alert is acknowledged or resolved, then an annotation appears on the dashboards with incident ID, timestamps, and actor.
Data Minimization and Retention Controls
- Given verification attempts, then only minimal data is stored: hashed phone identifiers (SHA-256 + unique salt), last 10 attempt timestamps, outcome codes, and reason; raw PINs/OTPs and full caller-ID content are never stored. - Given retention policies, then attempt telemetry older than 90 days is purged automatically; audit logs are retained for 365 days; backups purge matching records within 30 days of source deletion. - Given a data erasure request for an authorized contact, then all identifiers and associations for that contact are deleted within 30 days across primary and backup stores, with a completion report available to admins. - Given a data export request, then the system produces a minimally scoped export limited to documented fields within 7 days, excluding secrets and cryptographic material.

Voice Digest

Natural‑sounding, TTS summaries of the latest approved updates organized by time period and topic (e.g., meals, activities, mood). Callers can skip, replay, or drill into items with simple keypad presses, getting the gist in under a minute. Tech‑light relatives stay informed quickly, cutting routine after‑hours questions.

Requirements

Summarized Digest Generation by Topic & Time Window
"As an approved family member, I want to hear a quick summary of my loved one’s recent updates organized by time and topic so that I can get the gist in under a minute without opening the app."
Description

Automatically generates concise spoken digests from the latest approved resident updates, grouped by configurable time windows (e.g., last 24 hours, today, this week) and topics such as meals, activities, health/mood, and notes. Uses templated natural-language generation to ensure consistent structure, brevity (gist under 60 seconds), and clarity over the phone. Integrates with KinLoop’s updates datastore and approval pipeline, pre-computes and caches per-resident digests on a schedule and on-demand, and exposes an API for IVR playback. Handles empty states (no new updates) gracefully with helpful prompts and optional fallback to the most recent prior window.

Acceptance Criteria
Rolling and Fixed Time Window Selection Works by Facility Timezone
Given a facility timezone is configured and current time is known in that timezone When a digest is generated for window=last_24h Then it includes updates whose approvalTimestamp >= now(tz) - 24h and < now(tz) and excludes all others And when a digest is generated for window=today Then it includes updates with approvalTimestamp >= local midnight(tz) and < now(tz) And when a digest is generated for window=this_week Then it includes updates with approvalTimestamp >= local week start (Mon 00:00 in tz) and < now(tz) And the window start/end timestamps are returned in the response in ISO-8601 with the facility timezone offset
Topic Grouping and Ordering in Digest
Given approved updates exist across topics meals, activities, health/mood, and notes When a digest is generated for any supported window Then the spoken/text digest groups sentences by topic in the fixed order: meals, activities, health/mood, notes And topics with zero updates are omitted from the digest And each included topic section mentions the count of updates for that topic and the most recent timestamp in spoken-friendly form (e.g., "at 3:15 p.m.") And no topic section exceeds 2 sentences
Only Approved Updates Included and Retracts Excluded
Given updates exist with statuses approved, pending, rejected, and retracted When a digest is generated Then only updates with status=approved at generation time are included And retracted updates are excluded And if an approved update is retracted or edited after caching, the resident+window cache entry is invalidated and the change is reflected in subsequent requests within 60 seconds
Digest Brevity: <=60s Spoken Duration
Given a resident has many approved updates within the selected window When a digest is generated using the default TTS voice and speed Then the estimated TTS duration of the digest is <= 60 seconds And if the initial estimate would exceed 60 seconds, the generator collapses each topic to a single sentence summarizing counts and the latest highlight until the estimate is <= 60 seconds And the final digest contains <= 120 words
Empty Window Handling with Optional Fallback
Given there are no approved updates in the selected window When a digest is generated Then the system returns a clear message: "No new updates for [window]." And the digest offers a prompt to hear the most recent prior period if IVR context is provided And when fallback=true is specified, the digest appends the most recent prior window range and summary, explicitly stating the alternate date range used
Precompute, Cache, and Invalidate Digests
Given digest precompute scheduling is enabled via configuration When the scheduler runs on its configured interval Then digests are precomputed and cached per resident per (window, locale, voice) And cache hits are served without regeneration And when a new update transitions to approved, the corresponding resident+window cache is invalidated within 60 seconds And when the API is called with forceRebuild=true, the digest is regenerated and the cache refreshed for that key
IVR Playback API Response Contract and Performance
Given an authenticated client calls GET /v1/digests with residentId, window, and locale (optional voiceId, forceRebuild) When the request is valid and resident exists Then respond 200 with application/json containing: text, ssml, topics[], window {type,start,end,timezone}, generatedAt, and caching metadata And respond 400 for invalid window, 404 for unknown resident, 401/403 for unauthorized/forbidden And the ssml field is valid per SSML schema And p95 latency is <= 300 ms for cached responses and <= 1500 ms for rebuilds
Approved-Only Content Filter & Redaction
"As a facility administrator, I want digest content to include only approved, non-sensitive information so that we protect privacy and remain compliant while keeping families informed."
Description

Ensures only updates explicitly approved for family sharing are included in digests, enforcing resident- and contact-level permissions. Redacts protected health information and references to non-consenting residents, converts staff jargon to family-friendly language, and strips internal-only notes. Applies rules-based and ML-assisted redaction for names, room numbers, medications (if restricted), and incidental identifiers, with audit logs for each digest output. Provides configuration for facilities to define sensitive terms and topics to exclude.

Acceptance Criteria
Include Only Approved Updates in Voice Digest
Given the system has updates across multiple statuses for a resident within the selected time window When a voice digest is generated for a family contact Then only updates with ApprovedForFamilyShare = true are included And updates with statuses Draft, PendingApproval, Rejected, or InternalOnly are excluded And updates with an approvalExpiry before the digest generation time are excluded And the digest topics and counts reflect only the included updates And if no updates remain, the digest states "No new updates for this period" and ends within 10 seconds
Enforce Resident and Contact-Level Permissions
Given a contact has permissions for Residents {A} and Topics {Meals, Mood} but not Activities When a voice digest is generated Then only approved updates for Residents {A} and Topics {Meals, Mood} are included And updates for residents or topics outside the contact's permissions are omitted without placeholder references And keypad actions (skip, replay, drill-in) never reveal omitted content And multi-resident updates are split; if splitting would expose non-permitted context, the item is omitted entirely
Redact PHI and Incidental Identifiers
Given an included update contains PHI such as names of non-consenting individuals, room numbers, phone numbers, addresses, IDs, or incidental identifiers When the digest transcript is prepared Then such entities are redacted using rules and ML with confidence threshold ≥ 0.85 And replacements use natural generalizations (e.g., "another resident", "their room") in audio rather than literal tokens like "[REDACTED]" And no unredacted PHI appears in the generated audio, transcript, SSML, or metadata payloads And a redaction entry is recorded for each entity with type, method (rule|ML), and confidence
Convert Staff Jargon to Family-Friendly Language
Given an included update contains staff jargon or abbreviations present in the facility's glossary (e.g., ADLs, q2h, PRN) When preparing the digest text Then jargon terms are replaced with approved family-friendly equivalents or expansions And the resulting copy scores at or below 8th-grade reading level (Flesch-Kincaid) while preserving who, what, when, and outcome And clinical abbreviations not in the whitelist are expanded or removed
Strip Internal-Only Notes
Given an update contains sections or fields marked InternalOnly = true or delimited as internal (e.g., [[internal]]...[[/internal]]) When generating the digest Then those sections are completely excluded from the transcript and audio And no placeholders or indirect references to internal content are emitted And the final digest contains no tokens like "internal", "for staff", or bracket artifacts
Facility-Defined Sensitive Terms and Topic Exclusions
Given an admin adds terms or topics to the SensitiveExclusions list When a new digest is generated at least 1 minute after the change Then updates containing those terms or topics are excluded or generalized per policy And matching is case-insensitive and supports stemming (e.g., "fall", "fell", "falling") And the exclusion list change is versioned and the applied version is recorded in the digest audit And a preview shows which updates would be affected before saving changes
Audit Logging for Each Digest Output
Given a voice digest generation request completes When the audit subsystem records the event Then the audit record includes: digestId, contactId, residentIds included, timestamp, configVersion, modelVersion, includedUpdateIds, excludedUpdateIds with reason codes, and per-redaction details (type, method, confidence, token hash) And an SHA-256 checksum of the audio file and transcript is stored And the record is immutable, queryable by admin within 2 seconds, and retained for at least 1 year And access to audit records is restricted to Admin and Compliance roles and all access is itself audited
IVR Keypad Navigation (Skip, Replay, Drill-Down)
"As a tech-light relative calling after hours, I want to press simple keys to skip, replay, or hear more details so that I can quickly find what I care about without navigating a complex menu."
Description

Provides an accessible phone interface that plays the digest and supports DTMF keypad controls to replay the last item, skip to the next topic, repeat the current topic from the start, or drill into details for a specific item (e.g., today’s meals). Announces simple, consistent prompts and minimizes cognitive load for tech-light callers. Supports timeouts, barge-in, and resume-on-reconnect. Integrates with the digest API for indexed items, maintains call session state, and records interaction analytics (e.g., most-skipped topics) for optimization.

Acceptance Criteria
Skip and Replay During Digest Playback
- Given a caller is connected and digest playback has started When the system plays the interaction prompt Then the prompt is exactly: "Press 1 to replay, 2 to skip, 3 to repeat topic, 4 for details, 9 for help." And the prompt duration is <= 5 seconds And no more than 4 options are offered excluding Help - Given the caller is hearing a digest item summary When the caller presses 1 Then the last item summary restarts from the beginning within 500 ms And any overlapping audio is cleanly stopped And DTMF is accepted for press durations from 70–500 ms - Given the caller is hearing a digest item summary When the caller presses 2 Then playback jumps to the next topic’s first item within 500 ms And a "skip_item" analytics event is logged with topic_id and item_id
Repeat Current Topic From Start
- Given the caller is within any item of a topic When the caller presses 3 Then the current topic header is announced and the topic’s items replay from their beginning in original order within 500 ms And playback position resets to the topic’s first item And an analytics event "repeat_topic" is logged with topic_id - Given the current topic has zero items When the caller presses 3 Then the system says "No updates in this topic" and returns to the previous playback position within 2 seconds
Drill Down Into Item Details And Return
- Given the caller is listening to an item with details available (item_id present from the digest API) When the caller presses 4 Then the system fetches the item details from the digest API within 1 second And begins playing the details in TTS within 1.5 seconds of the keypress And an analytics event "drill_down" is logged with item_id and topic_id - Given the caller is in details playback When the caller presses 0 Then the system returns to the digest at the next item after the drilled item within 500 ms And an analytics event "return_from_details" is logged - Given the item has no additional details When the caller presses 4 Then the system says "No further details for this item" and continues with the next item - Given the details API call fails or times out When the caller presses 4 Then the system says "Sorry, details are unavailable right now" and resumes from the same digest position without crash or dead-end - Rule: The item and topic order followed in digest and details respects the API-provided index and metadata mapping (topic_id, item_id)
Barge-In Responsiveness and Invalid Input Handling
- Given any prompt or content is playing When a valid DTMF key (0,1,2,3,4,9) is pressed Then playback is interrupted within 300 ms and the associated action begins within 500 ms - Given the caller presses an invalid key (any not in 0,1,2,3,4,9) When the system detects the input Then it plays "Invalid choice. Press 1 to replay, 2 to skip, 3 to repeat topic, 4 for details, 9 for help." in under 3 seconds And the playback position does not advance - Rule: DTMF debounce prevents duplicate actions; only one action fires per 1-second window for continuous tones or long presses
Timeout Handling and Safe Reprompts
- Given no input is received for 5 seconds during a prompt or item summary When the timeout elapses Then the system plays a brief reprompt: "You can press 1 to replay, 2 to skip, 3 to repeat topic, 4 for details" and resumes playback - Given two consecutive timeouts during the same topic When the second timeout elapses Then the system announces "Skipping ahead" and advances to the next topic And logs an analytics event "auto_skip_timeout" with topic_id - Given three consecutive timeouts or total idle time reaches 30 seconds When the threshold is met Then the call ends gracefully with "We’ll send a summary by text. Goodbye." and the session state is saved - Given playback is paused due to barge-in awaiting follow-up input When 5 seconds elapse without input Then playback resumes from the paused position
Resume On Reconnect With Session State
- Given a call drops mid-digest with a stored session_id and last playback position (topic_id, item_id, offset_ms) When the same caller reconnects within 10 minutes Then the system resumes at the last playback position within 2 seconds of answer And an analytics event "resume_session" is logged with session_id - Given the disconnect occurred during details playback When the caller reconnects within 10 minutes Then the system resumes at the beginning of the details for the same item - Given the reconnect occurs after 10 minutes or from a different caller identity When the call is answered Then a new session starts from the beginning of the digest And an analytics event "new_session_on_reconnect" is logged
Interaction Analytics Logging and Aggregation
- Given any keypad action occurs (replay, skip_item, repeat_topic, drill_down, return_from_details, invalid, auto_skip_timeout, resume_session, new_session_on_reconnect) When the action is executed Then an analytics event is persisted within 1 second with fields: session_id, caller_hash, timestamp_iso, event_type, topic_id, item_id (nullable), position_index - Given a call ends When the session is closed Then a session summary record is stored with total_duration_ms and counts per event_type - Given a request for "most_skipped_topics" for the last 30 days When the analytics aggregation is queried Then the system returns the top 5 topic_ids with skip counts and percentages that reconcile with raw events within ±1% - Rule: Duplicate events are de-duplicated by (session_id, event_type, item_id, timestamp rounded to 1s)
Natural TTS with SSML, Voice Options, and Caching
"As a family member listening over the phone, I want a natural, easy-to-follow voice so that I can comfortably understand updates without straining."
Description

Delivers clear, natural-sounding speech optimized for telephone audio, using SSML to control pronunciation, pacing, emphasis, and pauses. Offers selectable voices and speaking rates per facility or caller preference, and supports multiple languages/accents. Pre-renders and caches audio for common digests to reduce latency and costs, with intelligent cache invalidation on new approvals. Includes graceful degradation and vendor fallback if the primary TTS provider is unavailable.

Acceptance Criteria
SSML Rendering for Telephone-Optimized Voice Digest
Given a sample digest containing SSML tags: <prosody rate="90%">, <break time="300ms">, <say-as interpret-as="date">, <phoneme ph="...">, and <emphasis level="strong"> When synthesized for PSTN playback Then the output: (a) applies prosody rate within ±5% of target, (b) includes a pause of 250–350 ms at the break, (c) pronounces the name per provided phoneme, (d) speaks the date per the say-as rule, (e) is encoded G.711 μ-law, 8 kHz mono, and (f) has true peak ≤ -1.0 dBFS with no clipping
Per-Caller Voice and Rate Preference Override
Given a facility default voice=Calm-Female (en-US), rate=1.0x, and a caller profile override voice=Warm-Male (en-US), rate=0.9x When the caller requests the Voice Digest Then playback uses the caller’s voice and rate; if the selected voice is unavailable, fallback to the facility default within the same language; the resolved selection (voiceId, rate, language) is audit-logged with callerId, facilityId, and timestamp
Multi-Language and Accent Selection
Given a caller language preference es-US and a digest with Spanish translations available for all items When the digest is synthesized Then an es-US Spanish voice is used; dates and numerals are localized (e.g., “28 de agosto de 2025”); pronunciation reflects es-US accent; if any item lacks Spanish, that item is synthesized in en-US using appropriate lang tags, and non-Spanish items comprise ≤ 10% of the digest
Pre-Rendered Audio Caching for Frequent Digests
Given a digest template for resident R with voice parameters V and a cached audio rendered within TTL (12h) with no newer approvals When a caller requests that digest Then audio is served from cache; time-to-first-audio ≤ 300 ms (p95 across 100 consecutive requests); the cache key includes digestId, language, voiceId, and speakingRate; a cache-hit event is recorded
Smart Cache Invalidation on New Approvals
Given a cached digest for resident R covering 06:00–12:00 and a new approved update at 09:15 after cache creation When the next caller requests the digest Then only the affected segment is re-rendered and stitched; time-to-first-audio ≤ 1.5 s; the new item is included; unchanged segments remain byte-identical to prior cache; the stale cache entry is invalidated
TTS Vendor Fallback and Graceful Degradation
Given the primary TTS vendor returns 5xx or exceeds a 2 s timeout during synthesis on a cache miss When rendering is attempted Then the system retries once and fails over to a secondary TTS within 5 s; SSML features are mapped to supported equivalents without synthesis error; playback starts within 8 s (p99); if all vendors fail, a concise fallback message plays within 3 s and the call remains connected
SSML Marks for Item Navigation
Given a digest composed of N items When audio is synthesized Then an SSML <mark> with a unique id is placed at each item boundary; keypad skip/back jumps to the nearest mark within 200 ms of DTMF input; mark ids map 1:1 to item ids with 100% correctness on the test set
Secure Caller Authentication & Access Control
"As a compliance-conscious administrator, I want only verified, approved family members to access voice digests so that resident privacy and consent are respected."
Description

Authenticates callers via resident selection plus PIN/OTP and maps them to approved contact records before allowing digest playback. Enforces per-caller access to specific residents and topics, rate-limits attempts, and blocks suspicious activity. Logs access events for auditing and provides configurable session timeouts. Integrates with KinLoop’s contact management, consent records, and notification preferences.

Acceptance Criteria
Resident Selection + PIN Authentication
Given a caller selects a resident via DTMF and enters a 4–8 digit PIN, When the PIN matches the approved contact’s record within 3 attempts, Then the system maps the caller to that contact and grants digest access. Given 3 consecutive incorrect PIN entries for a caller–resident pair, When the next attempt occurs within 15 minutes, Then the system denies authentication and enforces a 15‑minute lockout for that pair. Given an invalid resident selection or non-existent pairing, Then the system returns a generic failure message without disclosing whether the resident or contact exists, and logs the attempt with reason "invalid_pairing".
OTP Delivery and Verification
Given OTP is required, When the caller chooses SMS or voice to a verified number on file, Then the OTP is delivered within 30 seconds for at least 95% of requests. Given a delivered OTP, When the caller enters the correct 6‑digit code within 5 minutes and within 3 attempts, Then authentication succeeds and the OTP becomes single‑use and invalid thereafter. Given both SMS and voice are available, When sending an OTP, Then the system uses the caller’s notification preference; if unavailable, Then it falls back to SMS then voice. Given an expired code or max attempts exceeded, Then authentication fails, a 5‑minute cooldown is enforced before a new OTP can be requested, and the event is logged with reason "otp_expired_or_max_attempts". Given no verified number is on file, Then the system denies OTP authentication and plays an instruction to contact the administrator; no OTP is generated.
Per-Caller Access by Resident and Topic Consent
Given an authenticated caller, When generating the digest, Then only residents and topics for which the caller has active consent are included. Given a topic lacks consent or is restricted by policy, Then those items are excluded from playback and are not enumerated in counts. Given an admin updates a caller’s access or consent, When the change is saved, Then access decisions reflect the update within 60 seconds. Given a caller lacks access to the selected resident, Then playback is denied with a generic unauthorized message and the event is logged with reason "access_denied".
Rate Limiting and Suspicious Activity Blocking
Given authentication attempts from the same caller ID (ANI), When failures exceed 5 within 10 minutes, Then further authentication is blocked for that caller ID for 30 minutes and the event is logged with reason "rate_limited". Given failed attempts span 3 or more different residents within 5 minutes from the same caller ID, Then the caller ID is blocked for 60 minutes and a security alert is sent to admins. Given a blocked caller dials in, Then the system plays a generic unavailable message without revealing block status and terminates the session.
Audit Logging and Traceability
Given any call interaction, Then the system logs: timestamp (UTC), caller ID (ANI), mapped contact ID (or null), resident ID selected, auth method (PIN/OTP), outcome (success/fail/blocked), reason code, topics accessed, session duration, and a correlation ID. Given a log entry is created, When queried by an authorized admin, Then it is retrievable within 60 seconds and contains no secrets (e.g., PIN/OTP values redacted). Given a 365‑day retention policy, Then logs are stored immutably for 365 days and purged thereafter with a verifiable deletion record.
Session Timeout and Re-Authentication
Given an authenticated session, When no keypad input occurs for 60 seconds, Then the session times out, requires re‑authentication, and logs reason "inactivity_timeout". Given an authenticated session, When total call duration exceeds 10 minutes, Then the session ends with a polite timeout message and logs reason "max_duration". Given 45 seconds of inactivity, Then a single warning prompt is played; When input is received within the next 15 seconds, Then the session continues without re‑authentication.
Admin Configuration for Digest Policies & Prompts
"As a facility admin, I want to configure how digests sound and what they include so that the experience matches our policies and family expectations."
Description

Allows administrators to configure default time windows, topic ordering, maximum digest length, voice and language settings, sensitive-topic exclusions, and IVR prompt wording. Supports per-resident overrides (e.g., exclude mood), facility-wide templates for phrasing, and A/B testing of prompt variations. Provides a preview tool to review the generated script and audio before enabling changes.

Acceptance Criteria
Configure Default Time Windows and Topic Order
Given I am an authenticated facility administrator on the Voice Digest settings page When I define non-overlapping digest time windows with valid 24-hour start/end times and reorder topics to a specified sequence And I click Save Then the configuration persists and is visible after page reload and via configuration API And Preview uses these time windows to select updates and outputs topics in the saved order And validation prevents overlapping or malformed time ranges and displays inline errors until corrected And newly added residents inherit these defaults upon creation
Set Maximum Digest Length and Enforce in Preview
Given I set the Maximum Digest Length to 60 seconds When I click Preview for a selected resident and time period Then the estimated duration displayed is ≤ 60 seconds And the generated TTS playback does not exceed 60 seconds by more than 2 seconds And content boundaries are respected (no mid-word cutoffs; truncation at sentence boundaries) And if the limit is set below 15 seconds, a validation error blocks saving until adjusted
Configure Voice and Language with Fallbacks and Overrides
Given I select Language = Spanish (es-ES) and Voice = "Lucia" at the facility level When I click Preview Then the preview script is localized to Spanish and the audio plays in the selected voice And the selection persists after reload and is returned by the configuration API And if Resident Y has an override Language = English and Voice = "Mark", their preview and live calls use the override And if the selected voice becomes unavailable, the system falls back to the facility default voice and shows a non-blocking notice in the UI
Sensitive Topic Exclusions and Per-Resident Overrides
Given the facility excludes topics: Mood, Medications When I preview or generate a digest for any resident Then items tagged Mood or Medications do not appear in the script or audio Given the facility includes all topics When Resident C has a per-resident override to exclude Mood Then Mood is omitted for Resident C only and remains included for other residents And removing the per-resident override restores the facility defaults And exclusions apply consistently in both Preview and live IVR
IVR Prompt Templates and A/B Testing of Variations
Given I create a facility-wide prompt template with Variant A (control) and Variant B (alternative wording) When I set an allocation of A=50% and B=50% and start the test Then callers are assigned to variants according to allocation with ≤5% deviation after 200 calls And I can pause or end the test, selecting a winning variant as the active template And variant-level metrics (e.g., call completion rate, average time to first keypad input) are recorded and viewable And Preview renders the DTMF prompt flow for the selected variant accurately
Preview Script and Audio Before Enabling Changes
Given I adjust settings (time windows, topic order, max length, voice/language, prompt template) without enabling When I click Preview for a resident and period Then the generated script and audio reflect the draft settings and are labeled as Draft And live IVR continues using the previously enabled configuration When I click Enable Changes and confirm Then the new configuration becomes active for subsequent calls within 60 seconds And I can revert to the previous configuration in one action, restoring prior behavior
Digest Analytics & SLA Monitoring
"As a product owner, I want visibility into how families use voice digests and whether we hit the under-one-minute goal so that we can improve the experience and prove value."
Description

Captures metrics on digest generation latency, call connection rate, time-to-gist, topic completion rates, skips, and drop-offs. Surfaces dashboards and alerts to ensure the core promise (gist in under 60 seconds) is consistently met. Provides per-resident and aggregate insights to refine topic order and script length, and flags content issues that trigger excessive skips. Exposes exportable reports for operations and compliance review.

Acceptance Criteria
SLA Alert: Time-to-Gist 60s Compliance
Given live call analytics ingestion for the last 60 minutes When the 95th percentile time-to-gist exceeds 60 seconds across ≥ 30 eligible calls or any resident with ≥ 10 eligible calls Then an alert is sent to Slack and email within 60 seconds and a red SLA badge appears on the dashboard for the affected scope And Given the condition clears (95th percentile ≤ 60s for the next 30 eligible calls) When the system recomputes metrics Then the alert is auto-resolved and the badge returns to green within 60 seconds
Digest Generation Latency Capture
Given a digest is generated (prebuilt or on-demand) When generation completes Then latency from request to ready is recorded with timestamps and resident_id and appears in the dashboard within 30 seconds And Given a user selects a date range and scope (resident or all) When viewing latency metrics Then p50, p90, p95, min, and max are displayed and match underlying event logs within ±1%
Call Connection Rate and Failure Reasons
Given an inbound digest call attempt When the call connects or fails Then the outcome, carrier error code, IVR entry/exit timestamps, and call duration are recorded And Given at least 20 calls in a day When viewing the dashboard Then the daily connection rate is displayed as connected/(connected+failed) and matches raw events within ±1% And Given a CSV export for a date range is requested When the export completes Then each row includes call_id, resident_id, ts_start, ts_connect, outcome, error_code, and duration_ms
Topic Completion, Skips, and Drop-offs Tracking
Given a caller navigates a digest When a topic begins and ends or is skipped Then start_ts, end_ts, completed_flag, skip_flag, and seconds_listened are recorded per topic item And Given at least 100 topic plays in a 24-hour window When viewing analytics Then topic completion rate, skip rate, and average seconds_listened per topic are displayed with drill-down by resident and aggregate And Given any topic’s skip rate exceeds 35% with ≥ 50 plays in the last 24 hours When metrics compute Then the topic is flagged “Content Issue” and appears in the Issues panel with a link to sample content
Per-Resident and Aggregate Insights with Topic Order Suggestions
Given a resident is selected in the dashboard When viewing insights Then their time-to-gist p95, average call duration, topic order, and topic completion/skip rates are shown for the selected date range And Given aggregate view is selected When viewing insights Then the same metrics are shown across all residents and highlight top 5 topics by skip rate And Given the Reorder Suggestion feature is enabled When a topic ranks in the bottom quartile for completion and contributes >10 seconds to time-to-gist across ≥ 3 consecutive days Then the system suggests moving it later with a one-click preview of the new script
Exportable Reports for Operations and Compliance
Given a user with Reports permission requests an export When a date range and scope are specified Then CSV and JSON downloads are produced within 60 seconds containing digest latency, time-to-gist, connection outcomes, topic metrics, SLA breaches, and issue flags And Given the export is generated When opened Then fields include resident_id, resident_unit, call_id, caller_relationship, timestamps (UTC ISO8601), metrics (latency_ms, t2g_ms, duration_ms), topic metrics, and alert_ids; PHI beyond resident_id is excluded And Given the same data is queried via API When the client paginates Then stable ordering by ts_start and a next_cursor are provided and totals match the dashboard within ±1%

Touch-Tone Ack

One‑press acknowledgments from the phone (“Press 1 to confirm you received today’s update; Press 2 to send thanks”). Acks post back to the resident timeline for staff visibility and feed Delta Highlights, reducing follow‑up calls and giving caregivers instant signal that families are up to speed.

Requirements

DTMF Acknowledgment IVR
"As an approved family member, I want to press a number during an automated call to acknowledge today’s update so that staff immediately know I’m up to speed without needing a follow‑up call."
Description

Implement an interactive voice response flow that allows approved family members to acknowledge a specific resident’s update via touch‑tone (Press 1 to confirm receipt, Press 2 to send thanks). The IVR plays a concise, privacy‑safe prompt that identifies the resident and update date/time, captures DTMF input, confirms the selection, and associates the action with the correct resident and update. The system posts the result in near‑real time to the caregiver dashboard and resident timeline, providing immediate visibility and reducing follow‑up calls. Supports per‑contact language preference, replay, and graceful hang‑up handling; logs call metadata for audits and troubleshooting.

Acceptance Criteria
Approved Contact Acknowledges Update (Press 1)
Given an approved contact receives an IVR prompt for a specific resident update (residentId, updateId) When the prompt plays the resident’s first name and last initial and the update date/time in the contact’s timezone and the caller presses 1 Then the system records a “Receipt Confirmed” acknowledgment linked to residentId and updateId and attributed to the contactId And the acknowledgment appears on the caregiver dashboard and resident timeline within 10 seconds of DTMF entry And the IVR plays a confirmation message and ends the call And the acknowledgment event is available to Delta Highlights within 2 minutes
Approved Contact Sends Thanks (Press 2)
Given an approved contact receives an IVR prompt for a specific resident update (residentId, updateId) When the caller presses 2 Then the system records a “Thanks” acknowledgment linked to residentId and updateId and attributed to the contactId And a timeline entry labeled “Family sent thanks” with the contact’s display name appears within 10 seconds of DTMF entry And the IVR plays a confirmation message and ends the call
Privacy-Safe Prompt with Per-Contact Language Preference
Given an approved contact has a saved language preference and timezone When the IVR plays the prompt Then the prompt language matches the contact’s preference, falling back to English if unavailable And the prompt includes only the resident’s first name and last initial and the update date/time adjusted to the contact’s timezone And the prompt excludes medical details, room numbers, or other PHI beyond identifiers noted above And pressing 9 replays the prompt (max 2 replays per call)
Unapproved Number and Unknown Caller Handling
Given an inbound or answered outbound IVR session from a number not mapped to an approved contact for the targeted resident update When the IVR attempts to identify the caller Then the caller hears a generic message that verification failed without revealing the resident’s name or update details And no acknowledgment is recorded or posted And the call ends gracefully and is logged with outcome “unauthorized”
Invalid/No Input and Graceful Hang-Up Handling
Given the IVR has played the prompt When the caller presses a key other than 1, 2, or 9 Then an “invalid selection” message plays and the prompt is re-offered, up to 2 retries; after 3 invalid attempts, the call ends with no post and outcome “invalid_input” logged When no DTMF is received within 5 seconds Then a reminder plays and the prompt is re-offered once; after 2 timeouts, the call ends with no post and outcome “no_input” logged When the caller hangs up before making a selection Then no acknowledgment is posted and outcome “hangup_early” is logged When the caller hangs up after a valid selection is received Then the selected acknowledgment is still posted and the outcome “posted_before_hangup” is logged
Idempotent Acknowledgments and Duplicate Suppression
Given the same approved contact attempts to acknowledge the same resident update more than once within 24 hours When the IVR receives a subsequent valid input (1 or 2) Then only one visible acknowledgment event exists on the timeline and dashboard counts And subsequent attempts are logged with duplicate_of=<eventId> and do not create additional visible events And the caller hears a message indicating the update was already acknowledged
Comprehensive Call Metadata Logging for Audit and Troubleshooting
Given any IVR call related to a resident update When the call completes for any outcome Then an audit record is stored containing: callId, direction, callerNumber (hashed), contactId, residentId, updateId, language, timezoneUsed, promptVersion, dtmfReceived, outcome, startTimestamp, endTimestamp, durationSec, postLatencyMs (if applicable), and errorCode (if any) And authorized admins can query the record within 60 seconds of call end And logs retain at least 90 days and at most 365 days and exclude raw audio unless explicitly enabled for debugging
Caller Verification & Access Control
"As an administrator, I want acknowledgments restricted to verified, approved family members so that resident information remains private and compliant with our access policies."
Description

Ensure only approved family contacts can submit acknowledgments by verifying identity before accepting touch‑tone input. Map calls to contacts via signed, per‑recipient callback links/numbers and recognized caller ID, with fallback to a short one‑time PIN. Block or discard inputs from unrecognized numbers, expired tokens, or revoked contacts. Tie every acknowledgment to a verified user, resident, and update, and record the verification method for auditing. Respect per‑resident access lists and role permissions to prevent cross‑resident visibility.

Acceptance Criteria
Verified Callback Link Maps to Contact and Resident
Given a signed per-recipient callback number/link for Contact A and Resident R with embedded update ID U and token T And token T is valid and unexpired When Contact A places the call via that number/link and presses "1" or "2" Then the system verifies the session using token T without additional input And creates a single acknowledgment tied to contact_id=A, resident_id=R, update_id=U And records verification_method="Signed Callback Token" And posts the acknowledgment to Resident R’s timeline
Recognized Caller ID Auto-Verification
Given Contact B’s verified phone number is on file and mapped to Resident R’s update U When the system receives a call from that number and Contact B submits "1" or "2" Then the system verifies identity via caller ID match And creates an acknowledgment tied to contact_id=B, resident_id=R, update_id=U And records verification_method="Caller ID"
One-Time PIN Fallback Verification
Given Contact C initiates an acknowledgment from an unrecognized number for update U on Resident R And the system issues a 6-digit one-time PIN valid for 5 minutes and up to 3 attempts When Contact C enters the correct PIN within validity and submits "1" or "2" Then the system verifies identity and creates an acknowledgment tied to contact_id=C, resident_id=R, update_id=U And records verification_method="One-Time PIN" And masks the PIN from all call logs and analytics outputs
Block Unverified or Spoofed Calls
Given an inbound call with no valid token and caller ID not matching any approved contact for the target resident/update When the caller submits DTMF "1" or "2" Then the system rejects the input and terminates the flow without creating an acknowledgment And logs an audit event with reason="Unverified Caller"
Token Expiration and Access Revocation Enforcement
Given token T for Contact D and Resident R expires at t_exp, and Contact D’s access may be revoked at any time When a call uses token T after t_exp, or Contact D has been revoked prior to the call Then the system rejects the action, creates no acknowledgment, and reveals no resident or update details in prompts And logs an audit event with reason set to "Expired Token" or "Revoked Access" accordingly
Complete and Immutable Audit Trail
Given any acknowledgment is accepted When the record is persisted Then it includes contact_id, resident_id, update_id, verification_method, verification_timestamp, caller_id, call_sid, token_id (if used), and acl_version And the record is immutable and retrievable by authorized admins via reporting endpoints
Access Control Prevents Cross-Resident Acknowledgments
Given Contact E has access only to Residents R1 and R2 When Contact E attempts to acknowledge an update for Resident R3 via any verification path (callback link, caller ID, or PIN) Then the system denies the action and exposes no information about Resident R3 And when Contact E successfully acknowledges R1’s update, that acknowledgment is visible only on R1’s timeline and to staff per role permissions
Timeline & Delta Highlights Posting
"As a caregiver, I want acknowledgments to appear on the resident timeline and feed Delta Highlights so that I can instantly see which families are current without chasing confirmations."
Description

On successful acknowledgment, create a structured event on the resident timeline (actor, action, timestamp, channel, optional note for ‘thanks’) and update Delta Highlights metrics (e.g., first‑ack of the day, response time, outstanding families). De‑duplicate repeat inputs for the same update, maintain idempotency across retries, and surface status in caregiver views and shift digests. Provide webhook/event hooks so downstream components can react (e.g., suppress follow‑up reminders once acknowledged).

Acceptance Criteria
Record Timeline Event on Successful Touch-Tone Acknowledgment
Given an approved family member with caller_id mapped to actor_id F receives update U for resident R When they press 1 to confirm receipt during the IVR Then a timeline event is created within 5 seconds with fields: resident_id=R, actor_id=F, action="acknowledged", channel="phone", timestamp=server_utc, source_update_id=U, note=null And the event is retrievable via Timeline API and visible in the resident R UI within 10 seconds of creation Given the same family member presses 2 to send thanks during the IVR for update U When the DTMF input is received Then the timeline event has action="acknowledged_thanks", channel="phone", and note populated with a non-empty string
Update Delta Highlights Metrics on First Acknowledgment
Given update U for resident R has dispatch_timestamp T0 and no acknowledgments recorded on calendar day D in the facility timezone When the first acknowledgment for U is recorded at timestamp T1 Then Delta Highlights sets first_ack_of_day_for_resident[R,D]=T1 And sets response_time_ms_for_update[U]=max(0, T1 - T0) And decrements outstanding_families_count_for_update[U] by 1 for actor F And subsequent acknowledgments for U do not change first_ack_of_day_for_resident or response_time_ms_for_update
De-duplicate Repeat Acknowledgments and Ensure Idempotency
Given duplicate acknowledgment attempts occur for the same update U by actor F with the same ack_type within 24 hours When the system receives multiple events with the same dedupe_key "U|F|ack_type" Then exactly one timeline event exists for that dedupe_key And Delta Highlights metrics reflect a single acknowledgment for F on U And API responses for subsequent duplicates return 200 with the same idempotent result and no additional side effects
Surface Acknowledgment Status in Caregiver Views
Given a caregiver opens resident R's timeline after an acknowledgment for update U by actor F at timestamp T1 When viewing the update U card in the app Then an "Acknowledged via phone" badge is shown with actor display name and relative time And the outstanding_families_count for U reflects the latest value And the badge appears within 10 seconds of event creation
Include Acknowledgment Summary in Shift Digest
Given a shift digest is generated for shift window [S,E] for a roster that includes resident R When one or more acknowledgments for R's updates occur within [S,E] Then the digest includes for each resident: total acknowledgments count, first_ack_timestamp, average_response_time, and count of outstanding families per relevant update And residents with no acknowledgments show zero counts without errors
Emit Webhook to Suppress Follow-up Reminders
Given a subscriber is registered for event "acknowledgment.recorded" with a valid endpoint When an acknowledgment for update U by actor F is recorded Then a webhook is POSTed within 5 seconds containing: event_id, event_type="acknowledgment.recorded", resident_id, update_id=U, actor_id=F, ack_type, timestamp, dedupe_key And the request includes an Idempotency-Key header set to dedupe_key and a signature header for verification And on 2xx response, the system marks reminders for (U,F) as suppressed And on non-2xx, delivery retries with exponential backoff for up to 24 hours without duplicating side effects
Handle Out-of-Order and Retry Events Without Skewing Metrics
Given acknowledgments for update U arrive out of order or are retried When computing Delta Highlights Then first_ack_of_day_for_resident[R,D] uses the earliest valid acknowledgment timestamp for that resident/day And response_time_ms_for_update[U] uses max(0, earliest_ack_timestamp_for_U - dispatch_timestamp) And duplicate or late-arriving acknowledgments do not alter previously emitted webhooks or timeline events beyond deduplication rules
Admin Prompt Customization & Scheduling
"As a facility admin, I want to tailor prompts, languages, and call windows so that acknowledgments are clear, culturally appropriate, and never intrude on quiet hours."
Description

Provide facility‑level controls to customize IVR prompts (wording for options 1 and 2, optional ‘connect to staff’ transfer), select TTS voice and language, and manage quiet hours and call windows. Allow enabling/disabling phone acknowledgments per resident or contact, selecting which update types trigger phone calls, and setting contact‑level preferences (language, preferred channel). Honor quiet hours by queueing or deferring calls, and expose overrides for urgent notifications. Store versions of prompt configurations for traceability.

Acceptance Criteria
Facility admin customizes IVR prompt wording and enables optional staff transfer
Given I am a facility admin with permissions When I update the wording for options 1 and 2 and save Then subsequent outbound IVR calls play the new wording and the preview reflects the saved text And the changes are effective for calls initiated after the save timestamp When I enable the optional "connect to staff" transfer and enter a valid E.164 destination number Then outbound IVR calls announce a transfer option and pressing the announced key connects to the configured number within 5 seconds When the destination number is invalid or missing Then the setting cannot be saved and a validation error is shown
Facility selects default TTS voice and language with contact-level overrides
Given a facility default TTS voice and language are configured When placing an IVR call to a contact without a language preference Then prompts synthesize using the facility’s default voice and language When the contact has a language preference set Then prompts synthesize using the contact’s preferred language and the facility-selected voice for that language (or closest available) When a selected voice or language is unavailable at call time Then the system falls back to the facility defaults and logs a warning on the call record
Quiet hours and call window enforcement with queueing and urgent override
Given quiet hours are set to 21:00–08:00 and the call window is 08:00–20:00 in the contact’s local timezone When an eligible update occurs at 22:15 without urgent override Then no call is placed and a call job is queued with the contact’s timezone noted And the queued call is placed within 15 minutes after the window opens at 08:00 When an eligible update is marked with urgent override Then the call is placed immediately regardless of quiet hours And an override reason is required and stored with the call record and audit log
Enable/disable phone acknowledgments per resident and contact
Given phone acknowledgments are disabled at the resident level When any eligible update occurs for that resident Then no phone acknowledgment calls are initiated to any contacts for that resident Given phone acknowledgments are enabled for the resident but disabled for a specific contact When an eligible update occurs Then no phone call is initiated to that contact while other eligible contacts receive calls When a call is placed and the contact presses 1 Then a "Received" acknowledgment is recorded on the resident timeline with timestamp, contact identity, and call ID When the contact presses 2 Then a "Thanks" acknowledgment is recorded with the same metadata
Update-type triggers determine which events initiate phone calls
Given the facility selects specific update types to trigger phone calls When an update of a non-selected type is posted Then no phone call is initiated for that update When an update of a selected type is posted Then exactly one phone call is initiated per eligible contact And duplicate calls for the same update-contact pair are prevented within a 24-hour deduplication window
Contact-level preferred channel and language are honored
Given a contact’s preferred channel is SMS or Email When an eligible update occurs Then no phone call is initiated for that contact and the update is delivered via the preferred channel Given a contact’s preferred channel is Phone When an eligible update occurs Then a phone call is initiated using the contact’s language preference if set, else the facility default When a contact has no preferences at all Then the system defaults to Phone and the facility default language
Prompt configuration versioning and audit trail with rollback
Given an admin saves changes to IVR prompts When the save completes Then a new immutable configuration version is created with version ID, editor, timestamp, and change note And a diff summary of changed fields is stored When viewing configuration history Then prior versions are listed with metadata and can be restored When a previous version is restored Then it becomes the active configuration and subsequent calls use that version And each call record stores the configuration version ID used
Consent, Opt‑in/Opt‑out & Compliance
"As a compliance manager, I want consent and opt‑out controls with audit trails so that automated acknowledgments meet legal and policy requirements."
Description

Capture and enforce communication consent for each contact and channel, including TCPA‑compliant disclosures for automated calling. Provide easy opt‑out mechanisms (e.g., Press 9 to stop calls) and maintain a do‑not‑call list that the dialer respects. Log consent state changes with timestamps, actor, and source for auditability. Ensure prompts avoid protected health details and use minimal necessary information. Retain call recordings or transcripts of prompts and results per policy to support compliance reviews.

Acceptance Criteria
TCPA Consent Capture via Touch-Tone IVR
Given a contact has no recorded phone consent for automated calls When a consent IVR is initiated for that contact Then the call plays a TCPA-compliant disclosure before any request or update content And when the contact presses 1 to consent, the system records Phone=Opted In with timestamp (UTC), actor (contact), source (IVR), and disclosure version And when the contact presses 2 to decline, the system records Phone=Opted Out and adds the number to the do-not-call list And until Phone=Opted In is recorded, no Touch-Tone Ack update calls are attempted to that number And the consent outcome is visible in the contact profile and resident timeline
Immediate Opt-Out via Press 9 During Call
Given a Touch-Tone Ack call is in progress to a consenting contact When the contact presses 9 at any time Then playback stops within 2 seconds and the call ends And the system records Phone=Opted Out with timestamp (UTC), actor (ANI), and source (IVR) And the number is added to the do-not-call list immediately And no acknowledgment is posted for that call, and the resident timeline notes the opt-out event And future Touch-Tone Ack calls are suppressed for that number
Do-Not-Call List Enforcement in Dialer
Given a contact’s phone number is on the do-not-call list When the dialer builds the outbound queue for Touch-Tone Ack Then the number is excluded with suppression reason DoNotCall and zero call attempts are placed And when an API or user attempts to enqueue a call to that number, the request is rejected with an error code DO_NOT_CALL And no carrier traffic is generated to that number And a suppression entry is recorded with timestamp, initiator, campaign, and reason
Per-Channel Consent Management for Contacts
Given a contact has per-channel consent states (Phone, SMS, Email) When Phone=Opted In and SMS=Opted Out Then Touch-Tone Ack calls are permitted, and any SMS confirmations or digests are suppressed And when a staff member updates consent via UI or API Then the new state takes effect immediately for the next delivery attempt And an audit log records old state, new state, channel, actor, source, and timestamp And when Phone changes to Opted Out, the number is added to do-not-call; when it changes to Opted In, it is removed
Minimal Necessary Content in Voice Prompts
Given a Touch-Tone Ack prompt template is configured When an outbound call is played Then the prompt contains only facility name, resident first name, date, and generic language about an update and acknowledgment options And no diagnosis, treatment details, room numbers, or other protected health information are included And an automated content check passes before the call is enqueued; if it fails, the call is blocked and the user is shown a remediation message And the played prompt version is logged with the call record
Consent and Call Artifact Logging & Retention
Given any consent change or Touch-Tone Ack call completes When the event is stored Then the system logs contact id, resident id, channel, old state, new state, timestamp (UTC ISO8601), actor, source, and disclosure/prompt version And for calls, the audio recording or speech-to-text transcript of the disclosure and keypad responses is stored and linked to the call record And artifacts are retained for the configured retention policy duration and are retrievable by authorized admins And each artifact is tamper-evident (hash recorded) and exportable for audit review
Delivery, Retries & Failover
"As a caregiver, I want the system to retry calls and fall back to SMS if needed so that families still have a simple way to acknowledge updates even when calls don’t connect."
Description

Implement reliable call delivery with retry policies for busy/no‑answer, voicemail detection to avoid false inputs, and exponential backoff up to a configurable limit. Provide automatic fallback to an SMS acknowledgment link when calls fail or a contact prefers text, and surface final delivery status to staff. Monitor provider health, support multi‑carrier failover, and expose operational metrics and alerts (failure rate, connection time, DTMF capture errors) to ensure high availability and fast remediation.

Acceptance Criteria
Busy/No-Answer Retries with Exponential Backoff
Given an outbound Touch‑Tone Ack call returns busy or no‑answer When the system schedules a retry Then it applies exponential backoff starting at a configurable base delay with a configurable multiplier and jitter, up to a configurable max attempts or max elapsed time And retries stop immediately upon human answer or valid DTMF acknowledgment And each attempt is logged with timestamp, outcome (busy/no‑answer/answered), provider used, and next scheduled delay And the final outcome is set to Success or Failed after retries upon completion
Voicemail Detection Prevents False Acks
Given an outbound Touch‑Tone Ack call connects to an answering machine or voicemail When automated detection classifies the callee as a machine at or above the configured confidence threshold Then the system suppresses DTMF collection and does not record any acknowledgment input And plays the non‑interactive voicemail message variant, then ends the call And marks the attempt as Voicemail Detected and schedules the next retry per policy (unless limits reached) And any DTMF tones received prior to the interactive prompt are ignored and not posted to the resident timeline
Automatic SMS Fallback on Failure or Text Preference
Given a contact has a preference set to SMS for acknowledgments OR all call attempts have failed up to the configured limit When fallback is triggered Then the system sends a personalized SMS containing a secure, single‑use acknowledgment link (tokenized, expiring) And no further call retries are made after SMS fallback for that update And when the link is tapped and acknowledgment is submitted, the ack posts to the resident timeline with channel=SMS And duplicate acknowledgments across call and SMS are idempotently de‑duplicated, preserving the earliest valid ack
Final Delivery Status Visible to Staff
Given an update with attempted Touch‑Tone Ack delivery When delivery completes via call, SMS fallback, or exhausts retries Then staff can see the final delivery status on the resident timeline and staff dashboard within 60 seconds And the status includes channel used, number of attempts, last error/reason, timestamps of first and final attempt, and provider identifiers And staff can filter the dashboard by status (Delivered via Call, Delivered via SMS, Failed after Retries, Pending) And data exports include the same fields for auditing
Provider Health Monitoring and Multi‑Carrier Failover
Given active outbound calling through Provider A When Provider A’s failure rate exceeds the configured threshold within a rolling window OR median connection time exceeds the configured ceiling Then new calls are automatically routed to Provider B (failover) within 2 minutes, and the event is logged with reason and timestamp And in‑flight calls are allowed to complete without interruption And automatic recovery returns traffic to Provider A only after metrics remain healthy for the configured stabilization period And all failover and recovery events are exposed in ops logs and alerts
Operational Metrics and Alerting
Given the delivery pipeline is running When metrics are collected Then the system exposes at minimum: call success rate, retry rate, average time to connect, average time to acknowledgment, DTMF capture error rate, voicemail detection rate, and provider‑specific failure codes And metrics are viewable on an internal dashboard and exportable via a /metrics endpoint for external monitoring And alerts are emitted when thresholds are breached (e.g., success rate below threshold, DTMF error rate above threshold, connection time above threshold) with severity and runbook links And metrics are retained for at least 30 days for trend analysis
Ack Posting Integrity and Audit Trail
Given an acknowledgment is received via DTMF or SMS link When the system processes the ack Then exactly one timeline entry is created with contact identity, channel, timestamp (UTC), correlation/call ID, and outcome And repeated or late acks for the same update are safely ignored with no duplicate timeline entries (idempotency key enforced) And a complete audit trail is stored including provider call IDs, DTMF digits received, detection decisions, and delivery channel transitions And all stored data complies with access controls and redacts PII from logs by default
Ack Analytics & Reporting
"As a community director, I want reports on acknowledgment performance and time‑to‑ack so that I can measure engagement and adjust our outreach strategy."
Description

Deliver dashboards and exports showing acknowledgment rates, time‑to‑ack by resident and contact, engagement by channel (phone vs SMS/email), and cohorts with persistent non‑acknowledgment. Highlight residents or families requiring outreach and trend reductions in inbound calls post‑launch. Provide filters by community, unit, shift, and timeframe, with drill‑downs to raw events for QA. Feed summary metrics into Delta Highlights and admin reports to quantify time saved and engagement gains.

Acceptance Criteria
Dashboard: Ack Rate & Time-to-Ack by Resident/Contact
Given a user with Analytics permission selects a timeframe and applies Community/Unit filters with a grouping of Resident or Contact When the Acknowledgments dashboard loads Then it displays Ack Rate (%) and Time-to-Ack (median and 90th percentile) for each group And Ack Rate is computed per grouping: - Resident: distinct updates with ≥1 ack / total updates delivered for the resident within the timeframe - Contact: distinct update–contact pairs with ack / total updates delivered to the contact within the timeframe And Time-to-Ack per record = ack_at − update_sent_at for the matched update–contact pair; aggregates shown as median and 90th percentile And totals and group subtotals reconcile with overall totals within ±0.1% And all timestamps display in the community’s timezone in the UI And a data freshness indicator shows last refresh time and is ≤ 15 minutes ago And clicking a group opens a drill-down of raw events scoped to that group And exporting the visible table to CSV yields identical counts and aggregates And summary metrics (Ack Rate, median Time-to-Ack) are published daily to Delta Highlights and admin reports
Engagement by Channel Breakdown
Given the user selects the Channel dimension with applied timeframe and location filters When the Engagement by Channel widget renders Then it shows counts and percentages of acks by channel: Phone (DTMF touch-tone), SMS, Email And channel attribution logic is: - Phone: DTMF keypress events captured during voice calls - SMS: tracked SMS replies that register an acknowledgment - Email: tracked link-click or action that registers an acknowledgment from email And the sum of channel counts equals total acknowledgments in scope (±0.1%) And toggling a channel filter updates totals, percentages, and charts consistently And drilling into a channel segment shows only raw events from that channel And exported channel breakdown matches on-screen values and raw event counts (±0.1%)
Non-Ack Cohorts & Outreach Highlights
Given default thresholds of Persistent Non-Ack = (Ack Rate < 20% over the last 30 days) OR (0 acks on the last 10 delivered updates), excluding paused/invalid contacts When the user opens the Cohorts view Then a list of Persistent Non-Ack contacts is displayed with contact, resident, community, last-ack date, delivered updates, and ack rate And residents with > 50% of active contacts in Persistent Non-Ack are flagged as Requires Outreach And thresholds (percentage, window days, delivered-updates count) are admin-configurable per community within allowed ranges And snoozing or dismissing an Outreach flag requires a reason and records an audit entry (user, timestamp, reason) And cohort and flag membership are filterable and exportable to CSV And daily summary counts of Persistent Non-Ack contacts and Outreach-flagged residents are fed to Delta Highlights and admin reports
Global Filters: Community/Unit/Shift/Timeframe
Given the analytics workspace supports filters for Community, Unit, Shift, and Timeframe When a user applies any combination of these filters Then all widgets, tables, drill-downs, and exports reflect only in-scope data And Shift filter supports presets (Day 07:00–15:00, Evening 15:00–23:00, Night 23:00–07:00) that are timezone-aware and correctly handle spans across midnight; presets are admin-adjustable per community And multi-select is supported for Community and Unit; selections are displayed as removable chips And the active filter set persists for the user across sessions and can be reset with Clear All And empty-state messaging appears within 200 ms when no data meets the criteria And page load and filter changes complete within 2 seconds for datasets up to 1 million events over 90 days
Drill-Down to Raw Ack Events for QA
Given a user clicks any aggregate metric, table row, or chart segment When the drill-down view opens Then a raw events table appears with columns: Event ID, Resident, Contact, Community, Unit, Update ID, Channel, Ack Type (Confirm/Thanks), Update Sent At, Ack At, Time-to-Ack (seconds), Delivery Status, Source (Phone/SMS/Email) And default sort is Ack At (descending) with pagination (25/50/100 per page) And timestamps display in community timezone, with UTC shown on hover And Export (CSV/JSON) includes exactly the same rows and columns as the filtered result set across all pages And the export row count equals the server-reported total for the drill-down And PII for non-consenting residents is masked according to policy in both UI and exports
Trend: Inbound Call Reduction Post-Launch
Given inbound call logs are integrated per community and a Launch Date is configured per community (or resident where applicable) When the Inbound Calls trend widget is viewed Then it displays a pre-launch baseline (average weekly inbound calls in the 4 weeks prior) and a post-launch weekly time series for 12 weeks after launch And % Reduction per week = (baseline − week_calls) / baseline, shown per week and as a 12-week average And the chart annotates the Launch Date and optionally overlays a 3-week moving average (toggle) And calls from test numbers or staff lines tagged as internal are excluded And filters (Community/Unit/Shift/Timeframe) apply to the trend and underlying logs And weekly counts reconcile with raw call logs within ±1 call per community per week
Exports: Metrics & Events
Given a user has selected an export type (Summary Metrics, Grouped Metrics, Raw Events) and applied filters When the user requests an export Then a downloadable CSV is generated within 60 seconds for up to 1,000,000 rows, with documented column headers and community timezone applied And scheduled exports can be configured (daily/weekly) to email or SFTP delivery with encryption (SFTP or password-protected ZIP) And each export includes a metadata header with generation time (UTC), filter set, row count, and checksum (SHA-256) And export aggregates and counts match the on-screen results within ±0.1% And failed exports surface a descriptive error with retry and are logged for support triage

Smart Callback

If a caller flags something as urgent or requests a person, the system creates a context‑rich callback ticket (who called, what was played, timestamp) and routes it to the Shift Relay Lead’s Priority Queue. Quiet‑hour rules prevent unnecessary ring‑throughs while ensuring true escalations get a timely, well‑informed response.

Requirements

Caller Identity Resolution & Permissions
"As a Shift Relay Lead, I want caller identity automatically matched to approved contacts so that tickets include the right resident context and respect privacy permissions."
Description

Automatically identify the caller and map them to approved family contacts and associated residents using caller ID, secure PIN/DTMF verification, or account linking. Enforce role-based access so only authorized contacts can create callback tickets and view resident-related details. Handle edge cases (blocked numbers, shared phones, multiple residents per caller) with graceful fallbacks and clear prompts. Persist identity confidence and permission scope on the ticket to ensure privacy-compliant routing and response. Integrates with KinLoop’s resident directories and contact approvals to maintain a single source of truth.

Acceptance Criteria
Auto-Map Caller ID to Approved Contact
Given an inbound call with caller ID matching exactly one approved KinLoop contact linked to exactly one resident and role includes "Callback Creator" When the caller initiates a callback request via DTMF or voice intent Then the system resolves identity with identityConfidence="high" and verificationMethod="CallerID" And the ticket is created within 2 seconds containing callerContactId, callerName, residentId, callTimestamp (UTC), callFlowStepId, permissionScope=["callback:create"], sourcePhone And the caller is not prompted for PIN and no data for non-linked residents is exposed And an audit log entry is recorded with mappingSource="CallerID" and outcome="success"
PIN Verification for Unknown or Blocked Numbers
Given an inbound call with blocked/unknown caller ID or no exact contact match When the caller enters a valid 6-digit PIN associated with an approved contact within 3 attempts Then the system links the call to that contact with identityConfidence="verified" and verificationMethod="PIN" And a resident-scoped ticket can be created only within the contact’s approved permissions And an audit log entry captures attempts=1..3, outcome, and contactId on success Given 3 failed PIN attempts or 30s of inactivity When the caller cannot be verified Then no resident-scoped ticket is created, no resident names are played, and the caller is offered a general message option; identityConfidence="low"; audit outcome="failed_verification"
Disambiguate Shared Phone Numbers
Given an inbound call with caller ID matching multiple approved contacts (shared phone) When the system prompts for PIN to disambiguate and the caller provides a valid PIN Then the system selects the specific contact, sets identityConfidence="verified", and proceeds without revealing resident data prior to disambiguation Given disambiguation fails after 3 invalid PIN attempts or 30s timeout When identity remains ambiguous Then the system prevents resident-scoped ticket creation, offers a general message route, and logs outcome="ambiguous_number" with the caller ID hash
Multiple Residents Per Caller Context Selection
Given an identified contact linked to multiple residents and permitted to create callbacks for them When the caller initiates a callback request Then the system prompts the caller to select a resident from their approved list via DTMF And upon selection the ticket includes residentIdSelected and only that resident’s context is visible to staff Given no selection after 2 prompts or 30s total timeout When the caller does not choose a resident Then a ticket is created with residentIdSelected=null, privacyScope="contact-only", residentSelectionRequired=true, routed to the non-PHI queue; no resident names are played or displayed
Enforce Role-Based Permissions on Ticket Creation
Given an identified contact lacks the "Callback Creator" role or is not approved for the selected resident When they attempt to create a callback ticket Then the system blocks resident-scoped ticket creation and plays a permissions notice with next-step options (front desk or general message) And any ticket that is created in this flow is scope="general" with no resident identifiers And an audit entry records reason="permission_denied", contactId, and attempted residentId (redacted in playback)
Privacy-Compliant Ticket Metadata and Visibility
Given any callback ticket created by the system When it is placed into the Shift Relay Lead’s Priority Queue Then the ticket contains callerContactId, callerName (if present), verificationMethod, identityConfidence, permissionScope, residentIdSelected (or null), callTimestamp (UTC), sourcePhone (hashed for UI), and ivrPromptIdLastPlayed And only staff with access to residentIdSelected can view resident-specific fields; others see redacted values And tickets with identityConfidence="low" or missing mandatory fields are rejected by the backend and not enqueued, with an error audit logged
Single Source of Truth Sync with Directories & Approvals
Given contact approvals or resident-directory mappings are updated in KinLoop When the next inbound call occurs after up to 5 minutes Then identity resolution and permission checks reflect the latest data (cache TTL <= 5 minutes) And revoked contacts cannot create resident-scoped tickets and are informed of removal And audit entries reference the data version used for the decision
IVR Urgency and Person-Request Capture
"As an approved family member, I want to press a simple key to mark my call as urgent or request a specific staff member so that I can get timely help without navigating complex menus."
Description

Provide a simple IVR that lets callers flag an issue as urgent or request a specific person via DTMF (e.g., press 1 for urgent) and speech recognition (e.g., say "urgent" or a staff member’s name). Confirm selections, handle misrecognitions with quick reprompts, and support multilingual prompts. Persist urgency level, requested person, and any short voicemail message to enrich the callback ticket. Minimize friction so tech-light callers can act with one or two taps while keeping interaction latency low.

Acceptance Criteria
Urgent Flag via DTMF (English)
Given a caller reaches the IVR in English When the caller presses 1 at the first prompt or replay Then the system plays a confirmation of "Marked urgent" within 1.0 seconds of keypress And a Smart Callback ticket is created with fields: urgency=urgent, caller_id (if available), language=en, ivr_version, and timestamp And the total keypresses required are <= 2 And the DTMF capture success rate is >= 99% across 100 test calls with valid input
Urgent Flag via Speech (English)
Given a caller says "urgent" or a clear equivalent at the urgency prompt When speech is detected and ASR completes Then a confirmation is played within 1.5 seconds from end of speech And a callback ticket is created with urgency=urgent and asr_confidence >= 0.80 And if asr_confidence < 0.80 or no speech is detected within 3 seconds, the system reprompts once and offers "press 1 for urgent" And after 2 failed speech attempts, the DTMF fallback path is presented and functions as intended
Request Specific Staff by Name (Speech)
Given a caller says a staff member’s name that exists in the active directory When ASR completes Then the system repeats the recognized name and requests confirmation And on confirmation (press 1 or say "yes"), the ticket contains requested_person_id, requested_person_display_name, and match_confidence >= 0.75 And if multiple matches are possible, the system asks for disambiguation (e.g., unit/role) and resolves within one additional prompt And after 2 failed recognitions or two negative confirmations, the system offers DTMF selection or records requested_person="unknown" upon skip
Multilingual Prompts and Capture (English/Spanish)
Given a caller selects Spanish by pressing 9 or saying "español" When prompts are played and inputs are captured Then all prompts, confirmations, and reprompts are in Spanish And ASR uses the Spanish model and recognizes "urgente" and staff names pronounced in Spanish And the ticket metadata includes language=es And if no language selection occurs within 3 seconds, the IVR proceeds in English while offering the option to switch language on the next prompt
Short Voicemail Attachment and Persistence
Given the caller has flagged urgency or requested a person When prompted to leave a short message and the caller records up to 30 seconds Then the recording is saved and linked to the ticket with fields: voicemail_url, voicemail_duration, and voicemail_transcript (if available) And if silence > 5 seconds occurs, the system reprompts once and then saves what was recorded And if the caller hangs up after >= 2 seconds of audio, the partial recording is saved and linked And save/attachment latency is <= 2 seconds after the caller hangs up or completes recording
Quiet-Hours Ticket Routing and Notification
Given the call occurs during configured quiet hours When the caller flags urgent or requests a person via DTMF or speech Then no live ring-through occurs And a context-rich callback ticket is created and routed to the Shift Relay Lead’s Priority Queue And the Lead receives an in-app notification within 30 seconds of ticket creation And the ticket contains who_called (caller ID or "unknown"), what_was_played (IVR path), timestamp, urgency level, requested_person (if captured), and voicemail link (if recorded)
Playback Context Trace Capture
"As a caregiver, I want the callback ticket to show exactly what the caller just heard and when so that I can respond with full context and avoid repeating information."
Description

Capture and attach precise context about what the caller just heard: update/digest IDs, resident(s) referenced, staff author, timestamps, and playback offsets. If multiple updates were played, list them in order with timecodes. Store references to content instead of duplicating media, and include a short transcript snippet when available. This context-rich trace is bundled into the ticket to eliminate guesswork, speed responses, and reduce back-and-forth.

Acceptance Criteria
Single Update Playback Trace Completeness
Given a caller listens to a single update during one IVR session When a Smart Callback is triggered for that call Then the system captures and attaches to the ticket a context trace containing: updateId, optional digestId, residentIds[], staffAuthorId, playbackStartTimestamp (ISO 8601 UTC), playbackEndTimestamp (ISO 8601 UTC), playedOffsetStartSec, playedOffsetEndSec And the captured fields are non-null and correctly typed; digestId may be null if not applicable And timestamps reflect the actual call timeline within ±1 second And the trace validates against the defined JSON schema
Multi-Update Playback Ordering and Timecodes
Given the caller listens to multiple distinct updates in a single IVR session When a Smart Callback is triggered Then the context trace includes an ordered array "segments" where each element contains updateId, optional digestId, residentIds[], staffAuthorId, segmentStartTimestamp (ISO 8601 UTC), segmentEndTimestamp (ISO 8601 UTC), segmentStartOffsetSec, segmentEndOffsetSec And the order of "segments" matches the exact playback order And segment timecodes are monotonically increasing and non-overlapping And the sum of segment durations is within ±2 seconds of the total listened duration
Smart Callback Ticket Bundles Context Trace
Given a caller presses "urgent" or requests a person during or immediately after playback When the system creates the Smart Callback ticket Then the ticket payload includes the full context trace as a single JSON attachment and a rendered preview in the Priority Queue And the ticket appears in the Shift Relay Lead’s Priority Queue with context visible within 2 seconds of ticket creation And Quiet Hour rules suppress outbound ring-through but do not suppress creation or attachment of the context trace
Reference-Based Storage, No Media Duplication
Given updates referenced by the trace include photos and/or audio When the context trace is persisted Then the trace stores only stable references (contentId and versionId) to media and text, not the media binaries And no media bytes or base64 blobs are present in the trace payload And dereferencing a reference retrieves the current permitted asset without requiring duplicate storage And access to dereferenced assets honors existing authorization/consent controls
Transcript Snippet Inclusion and Redaction
Given a machine or human transcript exists for the played update segments When the context trace is generated Then the trace includes a "transcriptSnippet" per segment of up to 200 characters drawn from the played interval And snippets are omitted when no transcript exists for a segment And snippets are passed through the platform’s redaction rules to remove PII and names for non-consenting residents
Immutable Versioning and Post-Change Integrity
Given an update referenced in a previously created trace is later edited or deleted When a Shift Relay Lead opens the ticket Then the trace continues to resolve to the exact version that was played at the time of the call (via versionId or immutable pointer) And if the asset has been deleted or access revoked, the UI/API shows the stored metadata and a clear "asset unavailable" state without error And the trace remains readable and exportable for auditing
Callback Ticket Generation & Routing
"As a Shift Relay Lead, I want tickets automatically created and routed to my priority queue so that I can triage and respond efficiently."
Description

On confirmed urgency/person-request, create a structured callback ticket containing caller identity, contact info, resident linkage, urgency level, requested person, playback context, and call metadata (start/end time, ANI). De-duplicate tickets created within a short window for the same caller/resident and merge related context. Route tickets to the current Shift Relay Lead’s Priority Queue based on facility, shift schedule, and on-call rules, with fallback routing to a backup lead if unacknowledged.

Acceptance Criteria
Urgent or Person-Request Triggers Ticket Creation
Given an inbound Smart Callback where the caller flags the call as "Urgent" or requests a specific staff member And caller identity is obtained via ANI lookup or verified keypad input When the system confirms the flag/request Then a callback ticket is created within 2 seconds containing: caller name (or "Unknown"), caller phone (ANI), resident linkage (resident ID or "Unresolved"), urgency level, requested person (if any), playback context (content ID/name and timestamp), call start time, call end time, call duration, ANI, facility ID, and call ID And the ticket receives a unique ticket ID and initial state "Open" And the ticket appears at the top of the facility’s Shift Relay Lead Priority Queue
De-duplication and Context Merge Within Configured Window
Given a configurable de-duplication window exists with default value 10 minutes And an open callback ticket already exists for the same caller (ANI) and resident linkage When an additional urgent flag or person-request from the same caller/resident occurs within the window Then the system does not create a new ticket And merges the new event into the existing ticket by appending a playback context entry with timestamp, incrementing a trigger count, and updating the ticket’s last activity time And records a de-dup audit entry linking the event to the existing ticket And the Priority Queue position is updated to reflect the new last activity time
Routing to Current Shift Relay Lead’s Priority Queue
Given facility F has an active shift with Relay Lead L determined by schedule and on-call rules When a new callback ticket is created for facility F Then the ticket is assigned to L and visible in L’s Priority Queue within 1 second of ticket creation And the ticket displays Assignment = L, Queue = Priority, Facility = F And if multiple facilities are implicated, the resident linkage determines the facility; if resident is unresolved, the facility is inferred from the dialed DID or caller’s default facility profile
Fallback Routing on Unacknowledged Tickets
Given a ticket is assigned to a Relay Lead and remains unacknowledged When the acknowledgement SLA elapses (Urgent: 3 minutes; Non-urgent person-request: 10 minutes) Then the ticket is auto-routed to the configured Backup Lead B without creating a duplicate ticket And B receives an immediate notification of the reassignment And the ticket’s audit log records the escalation with timestamps, prior assignee, new assignee, and reason "SLA elapsed" And if Backup Lead B is unavailable, the ticket escalates to the facility escalation pool per on-call rules
Quiet-Hour Ring-Through Control With Escalation Override
Given facility F has quiet hours configured When a ticket is created during quiet hours Then non-urgent person-requests do not ring through devices and instead deliver silent push/in-app alerts to the assigned Lead And urgent tickets trigger ring-through override to the assigned Lead per policy And the ticket stores the applied quiet-hour rule ("silent" or "override") in its audit metadata
Playback Context and Call Metadata Accuracy
Given the call includes system playback (e.g., IVR prompt or resident update playback) When the ticket is created Then the ticket’s playback context includes the last played item ID, title/label, and playback timestamp And call metadata includes start time, end time, duration (seconds), ANI, DID, and call ID And all timestamps match telephony logs within ±1 second And if no playback occurred, the playback context is set to "None" with reason recorded
Resident Linkage Resolution and Fallback
Given the caller’s ANI matches exactly one resident’s approved contact When the ticket is created Then the resident linkage is set to that resident’s ID Given the ANI matches multiple residents’ contacts When the ticket is created Then the resident linkage remains "Unresolved" and candidate residents are stored for manual selection Given the caller enters a valid resident code during IVR When the ticket is created Then the resident linkage is set to the entered resident ID and marked "Verified" And routing uses the resolved resident’s facility; if unresolved, routing uses the DID-inferred or caller-profile default facility And manual linkage updates the ticket and re-evaluates routing without creating a new ticket
Quiet-Hour Policy Engine
"As a facility administrator, I want quiet hours enforced with smart overrides for true emergencies so that residents and staff are not disturbed unnecessarily while still handling critical issues promptly."
Description

Enforce configurable quiet-hour rules per facility and per role to suppress non-urgent ring-throughs while allowing true escalations. Support rule exceptions for designated emergency categories, and apply DND for individuals with override options. Integrate with shift calendars to determine who is eligible to be alerted. Log all suppressions and overrides on the ticket for transparency. Provide admin controls to set policies and test scenarios before deployment.

Acceptance Criteria
Non-Urgent Suppression During Quiet Hours
Given Facility A has Quiet Hours set to 21:00–07:00 local And the current time is within Quiet Hours And a caller creates a non-urgent Smart Callback ticket (urgency=false and category not in emergency list) When the Quiet-Hour Policy Engine evaluates the ticket Then no ring-through is initiated to any user And the ticket is created and routed without audible/visual paging alerts And a suppression entry is appended to the ticket log with timestamp, matched_rule_id, and reason="quiet_hours_non_urgent"
Emergency Category Override During Quiet Hours
Given Facility A emergency categories include ["Life Safety", "Medication Error"] And the current time is within Quiet Hours And a caller flags the message as urgent with category="Life Safety" When the Quiet-Hour Policy Engine evaluates the ticket Then ring-through alerts bypass Quiet Hours and DND per override rules and are sent to eligible on-duty recipients within 10 seconds And the ticket log records override=true with matched_rule_id, decision="ring", and targeted_recipient_ids
Role-Based Quiet-Hour Policy Enforcement
Given Facility A configures Quiet-Hour rules so that only role="Shift Relay Lead" is allowed ring-through during Quiet Hours for emergency categories And the current time is within Quiet Hours And an emergency Smart Callback ticket is created When the Quiet-Hour Policy Engine evaluates recipients Then only users with role="Shift Relay Lead" who are on-duty are targeted And users with other roles (e.g., Caregiver, Admin) do not receive ring-through And the ticket log includes matched_rule_id and filtered_out_roles
Individual DND With Category Overrides
Given user U has DND=On and DND_override_categories=["Life Safety"] And the current time is within Quiet Hours When a Smart Callback ticket is created with category="Life Safety" Then U receives ring-through despite DND, within 10 seconds And the ticket log records override=true with reason="dnd_category_override" When a Smart Callback ticket is created with category="General" Then U does not receive ring-through And the ticket log records suppression with reason="user_dnd"
Shift Calendar Eligibility for Alerts
Given the shift calendar marks L1 (Shift Relay Lead) as on-duty and C1 (Caregiver) as off-duty And an emergency Smart Callback ticket is created during Quiet Hours When the Quiet-Hour Policy Engine selects recipients Then only L1 is eligible to receive ring-through And C1 is not alerted due to off-duty status And the ticket log records recipient_selection with eligible_user_ids and ineligible_user_ids and reason codes
Ticket-Level Audit Logging of Suppressions and Overrides
Given a suppression or override decision is made by the Quiet-Hour Policy Engine When the Smart Callback ticket is viewed by an admin Then the ticket displays an audit entry containing fields: decision (ring/suppress), matched_rule_id, reason, affected_user_ids, timestamp, facility_id And the audit entry persists in ticket history and can be retrieved via ticket export API
Admin Policy Simulator and Safe Deployment
Given an admin opens Quiet-Hour Policy settings and creates or edits a policy draft When the admin runs Test Scenario with inputs (facility, role, category, urgency, time, user DND state) Then the simulator returns a decision (ring/suppress), matched_rule_id, target_recipient_count within 2 seconds And simulator runs do not send real alerts or modify production tickets And the Publish action is disabled until at least one simulator run is saved for the draft And publishing the policy activates it without impacting in-flight alerts, and the activation is logged with timestamp and admin_id
Escalation, SLA Timers, and Notifications
"As a Shift Relay Lead, I want SLA timers and reminders with escalate-to-backup notifications so that no urgent callback is missed during a busy shift."
Description

Attach SLA targets to each ticket by urgency (e.g., acknowledge within 5 minutes for urgent, callback within 15 minutes) and start timers on creation. Notify the assigned Shift Relay Lead via push and in-app alerts; escalate to backup leads or admins if SLAs breach or acknowledgments are missed. Provide one-tap callback and templated response notes within the ticket. Suppress redundant alerts after acknowledgment and record all notifications and outcomes on the ticket.

Acceptance Criteria
SLA Timer Initialization by Urgency on Ticket Creation
Given the organization SLA config defines: Urgent(Ack=5 minutes, Callback=15 minutes) and Routine(Ack=15 minutes, Callback=60 minutes) And a Smart Callback ticket is created with an urgency of Urgent or Routine at timestamp T0 When the ticket is created Then the system attaches the matching Ack and Callback SLA targets to the ticket And starts both SLA timers from T0 And displays visible countdowns for Ack and Callback on the ticket view And persists the timers and remaining time across app restarts and device changes And stores the SLA targets and T0 on the ticket for auditing
Lead Notification Delivery on Ticket Creation
Given an assigned Shift Relay Lead with a valid push token is on duty And a Smart Callback ticket is created at timestamp T0 When the ticket is created Then a push notification containing ticket ID, urgency, caller identity(if available), what was played, and timestamp is sent to the Lead within 10 seconds of T0 And an in-app priority banner appears for the Lead within 5 seconds of next app foreground And tapping the notification opens the ticket detail And if the push token is invalid, the system logs the failure and still presents the in-app banner And the notification event is recorded on the ticket
Redundant Alert Suppression After Acknowledgment
Given a Smart Callback ticket with an active Ack SLA timer And the assigned Lead opens the ticket and records an acknowledgment at time Ta When any subsequent Ack reminder thresholds are reached after Ta Then no additional Ack reminder notifications are sent to the Lead for this ticket And push/in-app alerts related to Ack are suppressed across all of the Lead’s devices And the suppression state is recorded on the ticket And Callback SLA reminders remain eligible unless the Callback is completed
Acknowledgment SLA Breach Escalation Flow
Given an Urgent Smart Callback ticket with Ack SLA of 5 minutes and a Priority Queue And no acknowledgment is recorded by T0+5:00 When the Ack SLA breaches Then the ticket is marked "Ack SLA Breached" and moved to the top of the Shift Relay Lead’s Priority Queue And backup Lead(s) and designated admin(s) are notified via push and in-app And during quiet hours, notifications are delivered silently (no audible ring-through) And the escalation event, recipients, delivery status, and timestamps are appended to the ticket audit trail And if the primary Lead acknowledges after escalation, further Ack-related alerts are stopped
Callback SLA Enforcement and Escalation
Given a Smart Callback ticket with Callback SLA targets defined (Urgent=15 minutes, Routine=60 minutes) And the ticket has been acknowledged at time Ta When a callback outcome has not been recorded by Ta+SLA Then the system escalates to backup Lead(s) and designated admin(s) via push and in-app And marks the ticket "Callback SLA Breached" and pins it in the Priority Queue And during quiet hours, notifications are delivered silently (no audible ring-through) And the escalation event is recorded on the ticket And when a callback is completed, the system records start/end times, caller ID, outcome, and marks "Callback SLA Met" if within SLA, otherwise "Callback SLA Breached—Resolved"
One-Tap Callback and Templated Notes Capture
Given a Smart Callback ticket includes a callable phone number When the Lead taps the one-tap Call button Then the app initiates the device dialer to that number and records call start time And upon call end, the app prompts the Lead to select an outcome (e.g., reached, voicemail, wrong number) and a templated response note or free text And saving the note records outcome, note content, author, and timestamp on the ticket And if the ticket lacks a phone number, the Call button is disabled with a visible reason And all actions are appended to the ticket audit trail
Notification and Outcome Audit Trail on Ticket
Given notifications, acknowledgments, escalations, callbacks, and note saves can occur on a ticket When any such event occurs Then an immutable audit entry is appended containing: event type, actor/system, recipients (if any), channel (push/in-app), timestamps, delivery result (success/failure), related SLA milestone, and any user-entered data And the ticket timeline displays entries in reverse chronological order And the audit trail can be exported as JSON or CSV from the admin view And edits to notes create new entries and show the editor and edit timestamp (original preserved)
Audit & Compliance Logging
"As a compliance officer, I want a complete audit trail and protected data handling so that we meet regulatory requirements and can investigate incidents."
Description

Maintain a complete audit trail for Smart Callback: call arrival, identity checks, IVR selections, context captured, ticket creation, routing decisions, quiet-hour suppressions, notifications, acknowledgments, and resolution notes. Protect data with encryption in transit and at rest, apply least-privilege access, and redact sensitive content from notifications. Support retention policies and export for compliance reviews. Integrate with KinLoop’s existing logging and admin console for monitoring and incident investigation.

Acceptance Criteria
End-to-End Smart Callback Audit Trail
Given a Smart Callback call arrives via IVR When the system processes identity checks, captures IVR selections, creates a callback ticket, evaluates routing and quiet-hour rules, sends notifications, receives an acknowledgment, and is resolved Then a single correlated audit trail exists with a shared correlation_id linking all events And each event record includes: event_type, correlation_id, call_id, ticket_id (if created), actor (system/user id), UTC timestamp to millisecond precision (ISO 8601), and event_payload summarizing inputs/outputs And the captured event_types include at minimum: call_arrival, identity_check, ivr_selection, context_capture, ticket_created, routing_decision, quiet_hour_evaluated, notification_sent, acknowledgment_received, resolution_added, ticket_closed And events are persisted within 5 seconds of occurrence and are queryable by correlation_id And events are stored in strict chronological order with a monotonic sequence_number per correlation_id
Quiet-Hours Suppression and Escalation Logging
Given a call occurs during configured quiet hours When quiet-hour rules suppress ring-through or allow escalation due to urgent flag or named-person request Then the audit trail contains a quiet_hour_evaluated event including: rule_id, rule_version, local_time_window, outcome (suppressed|escalated|bypassed), reason, and evaluator_id And if suppressed, a notification_sent event references the suppression outcome and target recipients And if escalated, a routing_decision event records override_reason = "urgent" or "person_requested" and the resulting destination queue/user And all above events are linked by the same correlation_id and appear before any acknowledgment_received
Security: Encryption In Transit and At Rest; Least-Privilege Access
Given any audit or ticket data is transmitted between services or clients When transport occurs Then TLS 1.2+ is enforced and non-TLS connections are rejected and logged as denied_access events Given audit data is stored at rest When data is written to persistent storage Then AES-256 (or stronger) encryption at rest is applied with KMS-managed keys and key rotations are logged Given roles are configured (Admin, Compliance, Shift Lead, Caregiver, Support) When a user requests to view, export, or modify audit data Then access is allowed only to roles explicitly permitted for that action and all access attempts (allow/deny) are logged with user_id, role, action, scope, and IP, preventing data exposure to unauthorized roles
Sensitive Data Redaction in Outbound Notifications
Given a notification is generated from a Smart Callback event When the notification content is assembled Then fields configured as sensitive (e.g., caller phone, resident identifiers, notes full text, voice transcript) are excluded or replaced with [REDACTED] and only non-sensitive metadata (ticket_id, category, location/unit, timestamp, callback window) is included And any free-text snippet is truncated to a maximum of 120 characters with entity-masked terms per the redaction configuration And the audit trail records a redaction_applied event containing redaction_rules_applied and a checksum of the pre-redaction payload (not the payload itself) And notifications containing media only include links requiring authenticated console access; media is never inlined
Retention Policy Enforcement and Legal Hold
Given an organization-level retention policy (e.g., 365 days) is configured When audit records exceed the retention window and are not under legal hold Then records are purged by a scheduled job and a purge_completed event logs time_range, record_count, and job_id And records tagged with legal_hold=true are not deleted and appear in purge reports as preserved_count And purge operations are irreversible and verifiable via before/after counts by date range
Compliance Export and Admin Console Integration
Given an Admin or Compliance role requests an audit export by date range, feature = Smart Callback, and optional filters (queue, user, event_type) When the export is generated Then a downloadable package (JSON Lines and CSV) with schema documentation and a signed integrity manifest (SHA-256) is produced within 10 minutes for up to 1 million events And the export action is logged with requester, filters, record_count, and manifest_hash And the Admin Console Audit view supports search by call_id, ticket_id, correlation_id, user_id, event_type, and renders an ordered timeline per correlation_id And export/download URLs expire within 15 minutes and require re-authentication
Tamper-Evidence, Time Synchronization, and Integrity Monitoring
Given audit events are written When stored Then each event includes a hash of the previous event in the same correlation chain (hash_chain_prev), creating a verifiable append-only chain And a daily anchor hash of all chains is computed and stored in a write-once location And system clocks are synchronized via NTP; if drift exceeds 200 ms, an integrity_alert event is emitted And an hourly integrity check verifies sequence continuity and hash chains; gaps or mismatches create integrity_alert events routed to on-call

AutoLanguage

Automatically matches the call experience to each contact’s preferred language, with easy keypad switching mid‑call. Names and common care terms are pronounced correctly, improving accessibility and reducing misunderstandings for multilingual families without adding staff translation work.

Requirements

Per-Contact Language Profiles
"As a community administrator, I want to set and maintain each contact’s preferred language so that every call starts in the right language without manual intervention."
Description

Store and manage each contact’s preferred language, regional variant, and fallback order to drive call experience selection. Include admin UI and bulk import to set language preferences at the resident-contact level, with defaults at community/facility level. Persist ISO language/locale codes, preferred TTS voice, and optional reading speed. Provide API endpoints for CRUD operations and audit changes. Enforce role-based permissions, multi-tenant isolation, and data residency. Synchronize preferences across mobile and web apps so outbound calls, IVR prompts, and digests use the same setting. Validate entries and provide sensible fallbacks when a language is not supported.

Acceptance Criteria
Admin UI: Create and Edit Per‑Contact Language Profile
Given a Community Admin is viewing a resident’s contact profile When the admin opens Language Preferences Then the admin can set Preferred Language as a valid BCP‑47 tag (e.g., en-US, es-MX) And the admin can set a Regional Variant (locale) constrained to supported values for that language And the admin can set a Fallback Order as an ordered list of up to 5 valid BCP‑47 tags with no duplicates And the admin can select a TTS Voice from the allowed voices for the chosen language/locale And the admin can set Reading Speed between 0.5 and 2.0 (step 0.05), default 1.0 When the admin saves Then the profile persists and is retrievable on refresh with exact values And invalid entries (unknown codes, unsupported voice, out‑of‑range speed) show inline errors and block save And an audit record is created capturing who, when, old→new diff, tenant, and source=UI
Facility Defaults and Override Precedence
Given a Facility Default language profile exists for a community And a resident contact has no per‑contact profile When the system selects language settings for that contact Then it applies the Facility Default Given a resident contact has a per‑contact profile When the system selects language settings Then the per‑contact profile overrides the Facility Default for all overlapping fields And missing fields in the per‑contact profile are inherited from the Facility Default And the effective profile is materialized and available via API with a computed flag per field (overridden vs inherited)
Bulk Import of Language Preferences with Validation and Dry‑Run
Given a Community Admin uploads a CSV using the provided template (resident_id, contact_id, preferred_language, locale, fallback_order, tts_voice, reading_speed) When Dry‑Run=true Then the system validates all rows and returns a report with row numbers, errors, and a summary (total, valid, invalid) without persisting changes When Dry‑Run=false and there are zero validation errors Then the import commits in a single transaction (all‑or‑nothing) And creates per‑row audit entries with source=Import and the uploaded file ID When duplicates for the same contact_id appear in the file Then the import fails validation with a duplicate error listing affected rows When unknown resident_id/contact_id, unsupported language/locale/voice, or out‑of‑range speed are present Then the import flags the rows with specific, field‑level error messages
API CRUD with RBAC, Multi‑Tenant Isolation, and Auditing
Given an authenticated request with tenant A and role Caregiver When calling GET /v1/contacts/{id}/language-profile for a contact in tenant A Then the response is 200 with the profile Given role Caregiver When calling PUT/PATCH/DELETE on the same resource Then the response is 403 Forbidden Given role Community Admin in tenant A When calling PUT /v1/contacts/{id}/language-profile with a valid body Then the response is 200 and the new profile is persisted with ETag returned And an audit trail entry records who, when, diff, tenant, and source=API Given a request from tenant B for a contact in tenant A When calling any CRUD endpoint Then the response is 404 Not Found (to prevent tenant enumeration) Given an update with If-Match ETag that is stale When the server detects a version mismatch Then it returns 409 Conflict
Cross‑Platform Synchronization and Versioning
Given a per‑contact profile is updated via Web Admin When a signed‑in mobile caregiver app is online Then the updated profile is delivered to the device within 10 seconds p95 via push sync And the app displays the new values on next profile view without requiring a restart Given the device is offline at update time When it reconnects Then it fetches the latest version and resolves using last‑write‑wins with ETag to avoid overwriting newer data And conflicting local drafts are rejected with a user‑visible conflict message
Fallback Selection When Preferred Language Unsupported
Given a contact’s preferred language/voice is unsupported for the current channel (e.g., outbound call TTS) When initiating a call or generating IVR/digest prompts Then the system selects the next language in the contact’s Fallback Order that is supported for that channel And if none are supported, it uses the Facility Default And if the Facility Default is unsupported or unset, it uses the product default en-US And the selected fallback (and reason) is logged in the call/session metadata and exposed in admin logs And name/pronunciation dictionaries use the effective locale selected
Data Residency Enforcement for Language Profiles
Given a tenant configured for region EU When creating, updating, or reading language profiles Then all data at rest (primary store and backups) resides in EU‑scoped storage And cross‑region replication for these records is disabled Given an admin from a different region attempts to bulk export another region’s profiles When the export job is requested Then the job executes only within the tenant’s region and the data never traverses regions And residency region is included in audit entries and export job metadata for verification
Auto-Matched Call Experience
"As a family contact, I want calls to begin in my preferred language automatically so that I can immediately understand updates and options."
Description

On call initiation, automatically select IVR prompts, TTS voice, ASR grammars, and captioning language based on the callee’s saved language profile. Preload localized assets to minimize connect latency and ensure continuity across transfer, hold, and voicemail. If the preferred language is unavailable, follow the contact’s fallback order, then the community default. Handle mixed-language households by offering a short language confirmation prompt when confidence is low. Ensure consistency across outbound updates, inbound callback menus, and voicemail drop content. Instrument KPIs for language-match rate and first-prompt comprehension signals to guide improvements.

Acceptance Criteria
Auto-select localized assets on call initiation
Given a callee with language profile L that is available When a call to the callee is initiated and answered Then IVR prompts, TTS voice, ASR grammars, and captioning are set to L before the first prompt plays And the additional connect latency attributable to localization is ≤ 300 ms at p95 And the first prompt plays in language L 100% of the time
Fallback language selection policy
Given a callee whose preferred language is unavailable When the call is initiated Then the system selects the first available language in the callee’s fallback list And if none are available, the community default language is selected And the selected language and fallback reason are logged And no language outside the specified order is used in 100% of cases
Low-confidence language confirmation for mixed-language households
Given language identification confidence < 0.75 or the callee is marked mixed-language When the call connects Then a single, ≤ 7-second confirmation prompt offers the top two languages from the callee profile via DTMF (1/2) and speech equivalents And if no input is received within 5 seconds, default to the highest-priority language And the selection applies to the current call session only unless the user opts to update their profile And the confirmation interaction completes without agent intervention in ≥ 95% of such calls
Language continuity across hold, transfer, and voicemail
Given a call with an established language L When the call is placed on hold, transferred, or reaches voicemail Then all prompts, system messages, and captions remain in L without reverting to another language And the voicemail greeting and recorded instructions play in L And continuity success rate is ≥ 99.5% over a rolling 30-day period
End-to-end language consistency across touchpoints
Given a contact with language profile L (or resolved fallback) When receiving outbound update calls, navigating inbound callback menus, or receiving voicemail drop content Then all prompts, TTS, ASR, captions, and pronunciation lexicons consistently use L across touchpoints And names and common care terms use correct language-specific pronunciations with ≥ 98% lexicon application accuracy in audits
KPI instrumentation for language match and comprehension
Given any call session When prompts are delivered and inputs are received Then events capture the resolved language, fallback level (match, fallback1, fallback2, community default), and first-prompt comprehension signals (first-attempt DTMF success, reprompt count, barge-in) And metrics are emitted to analytics within 60 seconds of call end And event loss rate is < 0.5% And no PII beyond language and anonymized IDs is transmitted
Mid-call language switching via keypad
Given an active call in language L1 with multiple languages available When the caller presses the language options hotkey (e.g., *0) and selects a new language L2 via DTMF or speech Then IVR, TTS, ASR, and captions switch to L2 within 2 seconds without dropping or restarting the call And the switch is confirmed in L2 And the number of reprompts is ≤ 1 And the switch event is logged
Mid-Call Keypad Language Switch
"As a caller, I want to change the call language mid-call using the keypad so that I can follow along or include someone who prefers a different language."
Description

Allow callers to switch languages at any time using DTMF (e.g., a dedicated key or short menu). Detect the keypress, confirm the new language briefly, and seamlessly reload current prompt, grammars, and TTS voice without losing call state or context. Support multiple switches per call with throttling to prevent loops. Provide a discoverable help key to list available languages when the preference is unknown. Log each switch with timestamp and previous/new language for analytics and compliance. Ensure behavior parity for PSTN and VoIP endpoints and across carrier networks.

Acceptance Criteria
Mid-Call Language Switch via DTMF
Given an active call with an ongoing prompt or input capture And a configured mapping of languages to DTMF keys exists When the caller presses a valid language-switch DTMF key Then the system detects the key within 250 ms And briefly confirms the new language in that language in <= 1.5 seconds And reloads the current prompt, grammars, and TTS voice for the selected locale And resumes at the same call state and context without data loss And previously collected inputs remain intact
Multiple Switches With Throttling
Given an active call When the caller performs multiple language switches Then at least 5 successful switches are allowed per call And a minimum 3-second cooldown between switches is enforced And no more than 2 switches are allowed within any 10-second window And if throttled, the caller hears a brief notice and the language remains unchanged And all throttled attempts are logged with reason "throttled"
Help Key Lists Available Languages
Given an active call where the caller may not know the available languages And a help key is configured (default: 0) When the caller presses the help key Then the system announces the list of available languages with corresponding DTMF keys in the current language And the caller can select a language from the list using a single keypress And if no selection is made within 10 seconds, the call resumes in the current language and state And the help action does not alter or reset the current interaction context And when no language preference is on file, the first prompt mentions the help key
Switch Event Logging for Analytics and Compliance
Given any successful or failed language switch attempt When the attempt occurs Then a log entry is created within 2 seconds containing timestamp (UTC), call/session ID, endpoint type (PSTN/VoIP), carrier (if available), previous language code and new language code (BCP-47), DTMF transport (in-band/RFC2833/SIP INFO), outcome (success/fail), and failure reason (if any) And logs exclude raw DTMF audio and PII, storing only hashed identifiers And logs are retained for at least 24 months and are queryable via the analytics API
Parity Across PSTN, VoIP, and Carriers
Given the feature is invoked on PSTN and VoIP endpoints across supported carriers When the caller switches language using DTMF Then functional behavior and prompts are identical across endpoint types and carriers And DTMF detection accuracy is >= 99.5% across in-band and out-of-band signaling And average switch confirmation and reload time meet the same performance thresholds across all networks
Error Handling and Safe Fallbacks
Given an invalid key or unsupported language selection When the caller presses an unassigned key or a malformed sequence Then the system plays a brief error message in the current language and does not change languages And after 3 consecutive failed attempts, the system offers the help menu And if language resource loading exceeds 750 ms or fails, the system rolls back to the prior language and continues the flow And all errors and rollbacks are logged with reason codes
Pronunciation and Locale-Consistent Voice
Given a switch to a new language locale When the system reloads TTS for that locale Then the voice uses the correct locale-specific TTS And pronunciations for stored contact names and common care terms use the pronunciation dictionary for that locale And on a test set of 100 representative names/terms per locale, at least 95% meet the predefined pronunciation evaluation criteria
Pronunciation Dictionary for Names & Care Terms
"As a caregiver, I want names and common care terms pronounced correctly so that families feel respected and clearly understand the updates."
Description

Deliver correct pronunciations of resident and staff names and common care terms via a multilingual, domain-specific dictionary. Support SSML with phoneme tags and custom lexicons per language/locale. Auto-generate initial pronunciations from locale-aware models, allow caregivers/admins to override with simple phonetic input, and propagate updates across all call flows. Integrate with resident profiles to ingest name fields, nicknames, and preferred pronunciations, and with clinical vocabularies for common care phrases. Validate pronunciations via preview playback in the app before going live.

Acceptance Criteria
Locale-aware auto-generation and caregiver override
Given a resident/staff name or care term is created or updated with a specified language/locale, When the record is saved, Then the system auto-generates a pronunciation entry for that locale within 5 seconds. Given a record lacks an explicit locale, When generating the pronunciation, Then the system uses the facility default locale and flags the entry as Needs Review. Given a caregiver/admin provides a phonetic override (simplified phonetics or SSML phoneme), When the override is saved, Then the override supersedes the auto-generated pronunciation for that specific locale only. Given overrides exist for multiple locales, When calls occur in each locale, Then the locale-matching override is used and others are not applied. Given an override is removed by an authorized user, When the change is saved, Then the system reverts to the latest auto-generated pronunciation for that locale and logs the change.
SSML phoneme tags and custom lexicons applied during TTS
Given a pronunciation entry includes SSML phoneme tags or custom lexicon entries, When speech is synthesized in the matching language, Then the TTS request includes the SSML/lexicon and the audio renders without SSML parsing errors. Given the same term exists in both a vendor lexicon and the KinLoop custom lexicon, When synthesizing speech, Then the KinLoop custom lexicon pronunciation takes precedence. Given a mid-call language switch occurs, When subsequent phrases are synthesized, Then the system switches to the target language’s lexicon and phoneme rules without requiring call restart. Given a user submits unsupported or invalid SSML, When saving the entry, Then the system blocks the save and displays a validation error explaining the issue.
Resident profile ingestion of names, nicknames, and preferred pronunciations
Given a resident profile is created or updated with legal name, nickname, and preferred pronunciation, When the profile is saved, Then all fields are ingested into the dictionary and available for TTS within 10 seconds. Given a resident has a preferred pronunciation specified, When speaking the resident’s name, Then the preferred pronunciation is used over auto-generated and nickname pronunciations according to the resident’s display preference. Given two residents share the same name, When dictionary entries are created, Then entries are scoped by resident ID to prevent cross-resident pronunciation bleed. Given a resident has a nickname flagged “Use in calls,” When generating call scripts, Then the nickname pronunciation is used; otherwise the legal name pronunciation is used.
Preview playback gating before go‑live
Given a new or edited pronunciation entry exists, When a user taps Preview, Then audio renders within 2 seconds and plays back the exact pronunciation to be used in calls. Given the preview plays successfully, When the user taps Approve, Then the pronunciation status changes to Active and becomes eligible for live use; if not approved, it remains Draft and is not used in calls. Given preview rendering fails, When the user attempts to approve, Then the system blocks activation and displays an actionable error message with retry. Given an Active entry is subsequently edited, When the edit is saved, Then the entry reverts to Draft until re‑previewed and approved.
Propagation across call flows and mid‑call language switches
Given a pronunciation entry becomes Active, When 60 seconds have elapsed, Then all call flows (outbound digests, inbound family line, voicemail prompts) use the updated pronunciation. Given a call is in progress and the language is switched via keypad, When subsequent utterances are generated, Then the correct locale-specific pronunciation is used for names and care terms without reverting to the prior language. Given cached TTS results exist from before the update, When a new session starts, Then caches are invalidated and the updated pronunciation is used; previously sent recordings are not altered retroactively.
Clinical vocabulary coverage and rapid term management
Given the system is initialized for a facility, When the dictionary is deployed, Then at least 200 common care phrases per supported language are preloaded from clinical vocabularies. Given a caregiver enters a care term not found in the dictionary, When saving the update, Then the system auto-generates a locale-appropriate pronunciation and offers a one-tap Add to Dictionary flow. Given an admin edits or adds a clinical term pronunciation, When the change is approved, Then it is applied across all matching phrases within 60 seconds without affecting unrelated words. Given a term lacks a pronunciation in the current locale, When it is spoken, Then the system falls back to default TTS and logs a Missing Pronunciation event for later curation.
Auto Translation and TTS Delivery
"As a caregiver, I want my updates automatically translated and voiced in each family’s language so that I don’t need to do manual translation or recordings."
Description

Translate dynamic update content from caregiver input language to the contact’s preferred language using a secure NMT pipeline with a protected glossary for clinical and brand terms. Feed translated text into locale-matched TTS voices with SSML for clarity, pauses, and emphasis. Cache translations for identical messages to reduce cost and latency. Provide confidence scoring and fall back to the original language with a clear notice if quality is below threshold or target language unsupported. Ensure processing within approved data boundaries and redact PHI per policy before sending to third-party engines when required.

Acceptance Criteria
Glossary‑Protected NMT Translation to Preferred Language
Given a caregiver submits an update in the source language configured for their device And the contact’s preferred language is supported by the NMT engine And a protected glossary defines clinical and brand terms with required renderings and/or no‑translate flags When the system translates the update Then the output is in the contact’s preferred language And glossary entries marked no‑translate remain unchanged And glossary entries with specified translations appear exactly as defined And a translation confidence score is computed and stored with the message
Locale‑Matched TTS with SSML Prosody Controls
Given translated text is available for delivery And the contact’s preferred locale is known as a BCP‑47 tag And a pronunciation lexicon for names and common care terms is available When the system synthesizes speech Then the selected voice matches the contact’s locale at least at the language subtag level And SSML applies sentence pauses of 200–400 ms and emphasis on marked key terms And detected dates, times, and numbers are rendered with locale‑appropriate say‑as formats And lexicon entries are applied without error And the audio container and sample rate match the platform default output settings
Cache Reuse for Identical Messages
Given a cache key composed of message hash and target language exists And the cached translation has not expired (TTL = 24 hours) When the same message is requested for translation again Then the cached translation is returned without calling the external NMT service And end‑to‑end translation latency for the repeated request is < 300 ms at P95 under nominal load And a cache‑hit metric is recorded for observability
Confidence‑Based Fallback with Clear Notice
Given translation produces a confidence score below the configured threshold of 0.80 Or the target language is unsupported by NMT or TTS When preparing delivery Then the system delivers the original‑language content instead of the translation And a clear fallback notice is included at the start of the audio and in message metadata And the confidence score, threshold, and fallback reason are captured in logs and analytics And no TTS attempt is made in an unsupported language
Data Boundary Compliance and PHI Redaction
Given organizational data boundary settings and PHI redaction policy are enabled And a third‑party NMT/TTS engine would be invoked When preparing the payload for external processing Then processing is confined to the configured data boundary region(s) And PHI entities (e.g., full name, DOB, MRN, phone, email, street address) are redacted or tokenized per policy before transmission And no unredacted PHI appears in outbound payloads or vendor logs as verified by automated DLP checks And an audit log records boundary, redaction actions, engine used, and request IDs
Mid‑Call Language Switch Applied to Subsequent Segments
Given an active update call is streaming TTS in language L1 And the contact enters the keypad sequence to switch to language L2 When the next TTS segment is generated Then translation and TTS switch to L2 for all subsequent segments without replaying prior content And an audible confirmation of the new language is played within 2 seconds And the switch event is recorded with timestamp and the new locale tag
Language Selection Audit & Compliance Logging
"As an administrator, I want an auditable record of languages used and switches on calls so that we can meet compliance requirements and resolve any disputes."
Description

Record language used at call start, each mid-call switch, and the rationale (auto-match, fallback, or user-selected), with timestamps and contact/resident associations. Store minimal DTMF metadata (key class, not exact digit when sensitive) and outcome of language confirmation prompts. Retain logs per compliance policy with export to CSV and admin dashboard filters by facility, resident, language, and date range. Exclude raw audio and transcripts unless explicitly enabled by policy. Surface alerts for frequent fallbacks or switch churn to flag missing preferences or asset gaps.

Acceptance Criteria
Call Start Language and Rationale Logged
Given an AutoLanguage-enabled call is initiated with a known contact and resident, When the call connects and the start language is determined, Then a start_log is persisted with fields: call_id, facility_id, resident_id, contact_id, start_language_code (BCP-47), start_rationale (AUTO_MATCH|FALLBACK|USER_SELECTED), timestamp_start_utc (ISO 8601), policy_version, and actor_user_id when USER_SELECTED. Given a transient write failure occurs, When connectivity returns within 10 minutes, Then the start_log write is retried until success and only one start_log exists per call_id. Given audio/transcript capture is disabled by policy, When the start_log is stored, Then no raw audio or transcript content is included.
Mid-Call Language Switch Logging with Timestamps
Given an active call with an existing start_log, When a language switch occurs, Then a switch_event is appended with timestamp_utc, new_language_code (BCP-47), switch_rationale (AUTO_MATCH|FALLBACK|USER_SELECTED), and actor_user_id when USER_SELECTED. Given multiple switches occur during the call, When the call ends, Then switch_events are ordered by timestamp with no duplicates and at least one event per switch action. Given the new language equals the current language, When a switch is requested, Then no switch_event is logged.
DTMF Metadata Minimization and Classification
Given a language confirmation prompt requests DTMF, When logging the input, Then only key_class (CONFIRM_YES|CONFIRM_NO|NO_RESPONSE|MENU_NAV) is stored and not the exact digit(s). Given a sensitive DTMF capture (e.g., PIN/MRN), When logging, Then only sensitivity_class=SENSITIVE and input_length are stored and the exact digit(s) are never stored. Given a non-sensitive menu navigation input, When logging, Then key_class=MENU_NAV and step_id are stored without the exact digit(s).
Language Confirmation Prompt Outcome Recording
Given a language confirmation prompt is played to the contact, When the contact responds or times out, Then outcome (CONFIRMED|DECLINED|NO_RESPONSE), attempt_number, and outcome_timestamp_utc are recorded for the call_id. Given the contact declines the auto-matched language, When the system applies a different language, Then the applied language rationale is FALLBACK and is linked to the decline outcome. Given the policy timeout is N seconds, When no DTMF is received within N seconds, Then outcome=NO_RESPONSE and the next action taken is logged.
Compliance Retention and CSV Export
Given a retention policy of R days is configured, When a log record exceeds R days, Then it is purged or archived per policy and excluded from standard queries and dashboards. Given an admin applies filters (facility, resident, language, date range), When requesting CSV export, Then the CSV is generated within 60 seconds with a header and columns: call_id, facility_id, resident_id, contact_id, start_timestamp_utc, start_language_code, start_rationale, switch_events_json, confirmation_outcomes_json, dtmf_metadata_minimized, policy_version, and contains exactly the filtered records. Given policy explicitly enables audio/transcript capture, When logs are stored, Then only storage_reference_ids and capture_flags are included and no inline audio or transcript content is present in CSV.
Admin Dashboard Filtering by Facility/Resident/Language/Date
Given the admin dashboard is open, When facility, resident, language, and date range filters are applied individually or combined, Then results reflect only matching records and load within 3 seconds for datasets up to 10,000 records. Given filters are cleared, When the reset action is invoked, Then all filters are removed and the default results set is shown. Given an invalid date range is entered (start date after end date), When filters are applied, Then a validation error is displayed and no query is executed.
Alerts for Frequent Fallbacks and Switch Churn
Given a resident/contact has a fallback rate greater than 30% across at least 10 calls in the last 7 days, When this threshold is crossed, Then an alert is created within 1 hour and appears in the admin alerts panel with resident/contact references. Given more than 2 language switches per call occur on 3 or more calls for the same resident within 7 days, When this condition is met, Then a switch_churn alert is generated and linked to the affected records. Given an admin acknowledges an alert, When it is marked acknowledged, Then it is removed from the active alerts list and retained in alert history with timestamp and acknowledging user_id.
Pre-rendered Prompts and Localization Caching
"As a family member, I want prompts to play quickly and naturally in my language so that the call feels smooth and easy to follow."
Description

Maintain a versioned library of localized, pre-rendered audio for common prompts across supported languages to keep IVR interactions under target latency. Cache assets at the edge/CDN and on-device where applicable, with cache-busting on content or voice updates. Fall back gracefully to real-time TTS for uncommon prompts. Monitor cache hit rates and per-language latency, and set SLOs (e.g., sub-500 ms for first prompt). Ensure consistent volume, prosody, and audio format across languages for a natural, uniform experience.

Acceptance Criteria
First Prompt Latency SLO (Per Language)
Given a supported language and a common IVR first prompt When the call starts and the first prompt is requested Then the end-to-start playback latency is ≤ 500 ms at the 95th percentile for that language over the last 24 hours And latency measurements include network transit, cache lookup, and decode time And the system records latency histograms per language for audit
Edge/CDN and On-Device Cache Hit Performance
Given production traffic for common prompts in any supported language When prompts are requested Then CDN/edge cache hit rate is ≥ 90% over a rolling 24-hour window per language And on-device cache serves repeat requests with start-to-playback latency ≤ 100 ms in ≥ 95% of cases And cache misses are logged with language, prompt key, and reason
Versioning and Cache-Busting on Content/Voice Updates
Given a new version of a localized prompt or voice profile is published and activated When clients request that asset after activation Then CDN edges serve only the new version within 10 minutes of activation And devices replace any cached prior version within 60 minutes or on next app start, whichever comes first And no call session plays mixed versions of the same prompt or voice profile after activation
Graceful Fallback to Real-Time TTS for Uncommon Prompts
Given a requested localized prompt is not available as a pre-rendered asset When the prompt is needed during a call Then real-time TTS begins playback within ≤ 1.2 seconds from request And the audio format, loudness, and prosody match the pre-rendered standards And a cache-miss event is logged within 1 second and the prompt is queued for pre-render within 5 minutes
Audio Consistency: Volume, Prosody, and Format
Given any localized prompt in any supported language When the audio is analyzed Then integrated loudness is -23 LUFS ± 1 LU and true-peak ≤ -1 dBFS with no clipping And sample format is 16 kHz, 16-bit PCM, mono; leading/trailing silence ≤ 150 ms And average speech rate is within 0.9x–1.1x of the language-specific baseline with ≤ 5% word-duration jitter between adjacent prompts
Per-Language Monitoring, SLOs, and Alerting
Given live traffic and enabled monitoring When p95 first-prompt latency for any language exceeds 500 ms for 10 consecutive minutes Then an alert is sent to on-call within 5 minutes with affected language and current cache-hit rate And dashboards display p50/p90/p95 latency and cache-hit by language with 30-day retention And burn-rate alerts are configured for 2x and 5x SLO breaches
Mid-Call Language Switch Served from Cache
Given an active IVR call and the caller switches language via keypad When the next system prompt is played Then the prompt is delivered in the new language with start-to-playback latency ≤ 500 ms at p95 And the prompt is served from pre-rendered cache when available; otherwise TTS fallback is used and logged And no prompt from the previous language is played after the switch

ShareSafe Voice

Voice readouts automatically omit staff‑only notes, room numbers, and any content restricted by consent scope or Incident Freeze. Every call is logged with a Proof Seal reference, so Privacy Stewards can demonstrate compliant, need‑to‑know sharing even over the phone.

Requirements

Caller Authentication & Authorization
"As an authorized family member, I want to securely verify my identity over the phone so that I can hear updates only for the residents I’m approved to receive information about."
Description

Provide secure verification and authorization for phone-based updates to ensure only approved family members can hear readouts for the correct resident. Support inbound (family-initiated) and outbound (caregiver-initiated) flows with PIN/OTP verification, caller ID heuristics as a secondary signal, and mapping to KinLoop’s access control lists and consent scopes. Minimize PHI exposure during prompts, prevent voicemail disclosure of sensitive content, and block access after configurable failed attempts. Log all auth outcomes and decision reasons for audit and monitoring. Integrate with existing contact records, resident linkages, and consent management, requiring no extra steps for tech-light caregivers.

Acceptance Criteria
Inbound family call: PIN/OTP verification without PHI exposure
- Given a family member calls the ShareSafe Voice line, When the system prompts for verification, Then no resident name, room number, diagnosis, or care detail is spoken or displayed prior to successful verification. - Given the caller requests an OTP, When a 6-digit OTP is issued to a verified contact method on file, Then the OTP expires in 10 minutes and is limited to 1 use. - Given the caller has a pre-set 6-digit family PIN on file, When caller ID attestation is A and the number matches a verified contact, Then PIN is accepted as the first factor; otherwise, OTP is required. - Given the caller enters valid credentials (OTP or required PIN+OTP), When verification succeeds, Then the system advances to authorization checks within 2 seconds and masks the credentials in all logs. - Given the caller abandons before verification, When the call ends, Then no voicemail or SMS containing PHI is sent and the attempt is logged as Incomplete without PHI leakage.
Outbound caregiver call: One-tap start with callee OTP before readout
- Given a caregiver taps “Call Family Update” from a resident’s record, When the action is initiated, Then the system auto-selects authorized contact(s) linked to that resident with no manual number entry and adds at most 1 extra tap beyond today’s workflow. - Given the callee answers, When verification begins, Then a 6-digit OTP is delivered to the answering number and must be entered via keypad or DTMF press within 60 seconds before any content is read. - Given verification succeeds, When the readout is requested, Then only content permitted by the callee’s consent scope is available; staff-only notes, room numbers, and consent-restricted items are excluded by policy. - Given verification fails or times out, When the call ends, Then no PHI is disclosed and the caregiver is shown a neutral “Not Verified” outcome in-call UI without revealing the callee’s details.
Caller ID heuristics as secondary signal with mandatory strong factor
- Given an inbound call with caller ID matching a verified number and STIR/SHAKEN attestation A, When verification is initiated, Then the system may allow PIN-only challenge; otherwise, OTP is mandatory. - Given caller ID is blocked, mismatched, or attested as B/C/None, When verification is initiated, Then OTP is required regardless of PIN presence. - Given risk indicators change mid-call (e.g., caller ID re-auth fails), When verification is in progress, Then the system escalates to OTP or terminates without PHI disclosure. - Given a successful verification, When proceeding to authorization, Then the log records caller ID match status and attestation as decision inputs without storing full phone numbers in cleartext.
Authorization enforcement by ACLs, consent scopes, and Incident Freeze
- Given a caller is authenticated and mapped to a contact record, When authorization is evaluated, Then access is limited to residents and categories permitted by that contact’s ACL and consent scope. - Given an Incident Freeze is active for a resident, When any readout is requested, Then the system denies access to frozen categories and plays a neutral denial without naming the resident or issue. - Given a contact is linked to multiple residents, When the system offers a selection, Then only residents with active authorization are listed; non-authorized residents are not enumerated. - Given authorization is denied, When the denial occurs, Then no PHI is disclosed and the denial reason code is logged for audit.
Voicemail and call-screening safeguards prevent disclosure
- Given an outbound call reaches voicemail or answering machine detection confidence ≥ 0.8, When the tone/beep is detected or no OTP entry occurs within 30 seconds, Then no resident-specific content is played and only a generic callback message (no PHI) may be left per org policy. - Given an inbound call drops before verification completes, When the system considers follow-up, Then no SMS or voicemail with PHI or resident identity is sent. - Given voicemail is detected and a generic message is left, When logging the event, Then the system records a No Disclosure - Voicemail outcome with timestamp and call identifier.
Failed-attempt rate limiting and lockout
- Given a caller fails N consecutive verification attempts within 15 minutes (org-configurable; default N=3), When the threshold is reached, Then the system blocks further attempts for T minutes (default T=30) and plays a neutral lockout message with no PHI. - Given a lockout is active, When additional attempts occur, Then verification is refused, a blocked-attempt counter increments, and no hints about resident identity or which factor failed are provided. - Given authorized staff lift a lockout, When the reset is performed, Then actor ID, reason, timestamp, and affected contact are recorded in the audit log.
Comprehensive audit logging and Proof Seal reference
- Given any authentication or authorization decision occurs, When the event is finalized, Then the system stores an immutable log with UTC timestamp, call direction, hashed caller/callee IDs, factors used (OTP/PIN/caller ID), outcome, decision reason codes, policy version, and a Proof Seal reference ID within 5 seconds of call end. - Given retention policies, When 13 months elapse (org-configurable), Then logs remain retrievable by Privacy Stewards and exportable in CSV/JSON without revealing raw phone numbers or PHI. - Given a Privacy Steward reviews a call using the Proof Seal ID, When the record is opened, Then the system displays the exact consent scope, ACL, Incident Freeze status, and redaction policy snapshot that were in effect at decision time.
Real-time Voice Redaction Engine
"As a caregiver, I want the system to automatically remove staff-only and restricted details from voice readouts so that I can share updates quickly without risking a privacy violation."
Description

Automatically transform update content into a phone-safe script by removing staff-only notes, room numbers, and any details restricted by consent scope or Incident Freeze before text-to-speech playback. Combine rule-based pattern scrubbing (e.g., room/bed identifiers, staff names, internal tags) with metadata flags on note fields to ensure deterministic omission. Preserve clarity by substituting neutral phrasing where needed (e.g., “location omitted”) and smoothing grammar. Enforce latency targets to keep readouts responsive, and fail safely by halting playback with a neutral message if residual risk is detected. Provide configuration hooks for policy updates, comprehensive unit tests, and regression suites to validate redaction coverage across edge cases and languages.

Acceptance Criteria
Omit Staff-Only Notes via Metadata Flags
Given an update payload where one or more note fields are flagged as internal/staff-only via metadata When a phone-safe script is generated for a family recipient Then all flagged fields are omitted from the output And a neutral connector phrase is inserted where needed (e.g., "note omitted") to preserve readability And the output contains zero tokens originating from the omitted fields And TTS playback uses only the redacted script
Pattern Scrubbing Across Languages
Given content containing room/bed identifiers (e.g., "Rm 205B", "205-Bed A", "Habitación 12B"), staff references with honorifics (e.g., "Nurse Kelly", "Enf. García"), and internal tag markers (e.g., "[STAFF]", "#internal", "{PRIVATE}") When the phone-safe script is generated Then all room/bed identifiers are replaced with the localized placeholder "location omitted" And staff references are replaced with "care team member" And internal tag markers are removed entirely And punctuation and spacing remain valid And across a regression suite of ≥200 annotated cases per supported language (EN, ES), the redaction pass rate is 100%
Honor Consent Scope and Incident Freeze
Given the recipient’s consent configuration excludes one or more content categories and/or an Incident Freeze is active for the resident When generating the phone-safe script for that recipient Then all content outside consent is omitted or replaced with the localized placeholder "details omitted due to consent" And if Incident Freeze is active, incident-related details are fully suppressed and only a neutral status message is produced And no prohibited terms appear in the output
Neutral Substitutions and Grammar Smoothing
Given a redacted script with one or more omissions When the final output is assembled Then there are no double spaces, double commas, stray leading/trailing punctuation, or empty sentences And placeholders are localized to the playback language And the output starts with a capital letter and ends with terminal punctuation (., ?, or !) And no more than two placeholders appear consecutively
Latency and Responsiveness Targets
Given an update up to 1,500 characters under nominal system load (≤70% CPU) When generating the phone-safe script and initiating TTS Then redaction processing completes within P95 ≤ 200 ms and P99 ≤ 350 ms And time-to-first-audio-byte (TTFAB) is P95 ≤ 800 ms and P99 ≤ 1,200 ms And if thresholds are exceeded, latency metrics are emitted for monitoring while playback continues (unless fail-safe risk triggers)
Fail-Safe Halt on Residual Risk
Given the risk analyzer flags residual sensitive content after redaction with severity ≥ high When preparing to start TTS Then playback is halted before any sensitive text is spoken And the caller hears the neutral message "Details are currently unavailable" And the redacted script is not cached or persisted And a decision code "FAIL_SAFE_RISK" is emitted for monitoring
Configurable Policy Hot-Reload
Given a new redaction policy (patterns, placeholders, thresholds) is submitted via the configuration endpoint When the policy is saved Then the engine hot-reloads the policy without service restart within 60 seconds And all subsequent requests use the new policy version identifier And if the policy fails validation, the previous version remains active and an alert is emitted
Consent Scope & Incident Freeze Enforcement
"As a Privacy Steward, I want consent scopes and incident freezes enforced automatically during voice readouts so that only appropriate, need-to-know information is shared."
Description

Resolve and enforce per-recipient consent scopes and active Incident Freeze states at readout time, ensuring only need-to-know information is shared. Evaluate content categories (e.g., health status, schedules, media references) against the recipient’s allowed scope and any freezes applied to the resident or topic. When a restriction applies, block or redact the affected portions and play a neutral explanation. Version policy evaluations, record the rule decisions used, and handle time-bounded or conditional consents. Support offline tolerance with short-lived cached policies and immediate invalidation when a freeze is invoked by Privacy Stewards.

Acceptance Criteria
Recipient consent-scope filtering at readout
Given a recipient with consent allowing Health Status and denying Schedules and Media, and a readout draft containing Health Status, Schedule (with a room number), Media reference, and a staff-only note When ShareSafe Voice generates the readout Then only the Health Status content is spoken And the Schedule and Media content are redacted And the staff-only note is omitted regardless of consent And any room identifiers (e.g., "Room 214") are removed from output And a pre-approved neutral explanation is played once per redaction And the final audio/transcript contains no content from denied categories And the event is marked "Scope Enforced" in the log
Immediate Incident Freeze enforcement and cache invalidation
Given a Privacy Steward activates an Incident Freeze on the resident while the device is online When a readout is in progress or initiated Then any ongoing readout halts within 5 seconds at the next sentence boundary And frozen categories are not spoken thereafter And a neutral freeze explanation is played once And cached policies for the resident are invalidated within 30 seconds And the call log records Freeze ID, invocation timestamp, enforcement timestamp, and redaction count
Time-bounded consent expiry mid-call
Given a recipient has a consent that expires at time T and a readout starts at T-1 minute When the clock reaches T during the call Then content gated by the expiring consent is redacted from that point forward And the call continues with remaining permitted content And the Proof Seal records the consent version, expiry T, and the decision pivot time And no gated content appears in audio or transcript after T
Conditional category-level consent resolution
Given a recipient’s consent permits Health Status, denies Schedules, and permits Media only if no third-party resident is referenced When evaluating a draft containing Health Status, a visiting schedule, and a media reference that mentions another resident Then Health Status is spoken And the visiting schedule is redacted And the media reference is redacted because the condition fails And decision logs include rule IDs and pass/fail outcomes for each item
Offline tolerance with short-lived cached policies
Given the device is offline and holds a cached policy snapshot for the resident not older than 10 minutes When a readout is requested Then the cached policy is used to filter and the readout proceeds And the Proof Seal marks Policy Source as Cached with snapshot timestamp And if the cache age exceeds 10 minutes, the readout is blocked with a neutral offline message and no content is disclosed And upon reconnection, any active Incident Freeze invalidates the cache within 30 seconds and any ongoing readout is halted within 5 seconds
Proof Seal logging with versioned policy decisions
Given any voice readout completes When the event is finalized Then a Proof Seal entry is created containing recipient ID, resident ID, policy evaluation version, consent snapshot IDs and timestamps, incident freeze status, list of rule decisions per content item, redaction count, and a cryptographic hash of the audio transcript and decision log And the entry is immutable and retrievable by Privacy Stewards within 2 seconds And the call record includes the Proof Seal reference ID
Proof Seal Call Logging
"As a Privacy Steward, I want each call logged with a tamper-evident Proof Seal so that I can demonstrate compliant, need-to-know sharing to auditors."
Description

Generate a tamper-evident Proof Seal for every readout, binding the redacted transcript, policy/version identifiers, timestamps, caller/callee identifiers, decision logs, and outcome codes. Store the seal and metadata in an immutable audit log with a human-readable reference code included in the call record. Provide verification and retrieval APIs/UI for Privacy Stewards to demonstrate compliance, along with retention and export policies aligned to regulatory requirements. Optionally associate a low-risk audio recording of the redacted readout where permitted; otherwise store transcript-only artifacts.

Acceptance Criteria
Seal Generation on Readout Completion
Given a ShareSafe Voice redacted transcript is ready and a call to an approved family contact is in progress When the caregiver completes the readout Then the system generates a Proof Seal binding the redacted transcript hash, policy/version identifiers, UTC timestamps, caller and callee identifiers, decision logs, outcome code, and system build/version And the seal and all bound metadata are written atomically to the immutable audit log And a human-readable reference code matching ^PS-[A-Z0-9]{10}$ is added to the call record and returned to the client And the operation completes within 2 seconds at the 95th percentile And the reference code is globally unique across the environment And if the completion is retried with identical inputs within 60 seconds, the same reference code is returned (idempotent)
Integrity Verification via API and UI
Given a Privacy Steward with Audit:Verify permission provides a Proof Seal reference code via API or UI When the verification request is submitted Then the system validates the seal’s cryptographic integrity against stored artifacts and returns status "valid" with bound attributes And if any bound element or signature is altered, the result is "invalid" with a specific reason code And verification completes within 2 seconds at the 95th percentile And all verification attempts are logged with steward ID, timestamp, reference code, and result
Immutable Audit Log and Reference Retrieval
Given an existing Proof Seal entry in the audit log When any actor attempts to modify or delete that entry Then the system rejects the operation with 403/Forbidden and records a security event Given a valid reference code When the record is retrieved via API or UI Then the system returns the immutable metadata, sealed transcript artifact pointer, and a monotonic sequence number And the returned reference code matches the call record’s stored reference code And read integrity is checked via checksums; any corruption blocks retrieval and surfaces an alert And retrieval latency is under 3 seconds at the 95th percentile for records under 1 MB
Retention Scheduling and Export Package Generation
Given configurable retention schedules per jurisdiction and legal hold flags are defined When a record reaches its retention end date without a legal hold Then it is marked Expired and purged from active retrieval within 24 hours, leaving a minimal tombstone with reference code, purge timestamp, and retention policy ID And purge actions are logged and auditable Given an authorized user requests an export for a date range, facility, and resident filter When the export is initiated Then the system produces a signed export bundle (machine-readable JSON/CSV plus human-readable summary) with all matching seals, artifacts, and an integrity manifest (checksums) or streams results in pages of 10,000 And the export enforces role-based access controls and logs access And the export completes within 1 hour for up to 100,000 records or streams without data loss
Incident Freeze and Consent Scope Logging
Given an Incident Freeze or consent restriction is active for the resident at readout time When a readout attempt is made Then the system enforces policy by either blocking delivery and generating a Proof Seal with outcomeCode=Denied including policy IDs and rationale, or permitting delivery and generating a seal that records the applied consent scope and policy IDs And any freeze state and consent scope are included in the decision log bound to the seal And verification and retrieval surfaces these fields to authorized Privacy Stewards And audio association is disabled while Incident Freeze is active
Optional Audio Recording Association
Given policy, jurisdiction, and consent permit storing a low-risk recording of the redacted readout When the readout completes Then the system stores only the redacted audio and links it to the Proof Seal via content hash and reference code And if not permitted, no audio is stored and only transcript artifacts are retained, with the decision recorded in the seal’s decision log And audio access is restricted to authorized roles and all access attempts are logged And audio files meet format and size limits (e.g., <= 5 minutes and <= 5 MB); violations result in rejection or truncation noted in the outcome code
Fail-Safe Behavior on Seal or Storage Errors
Given a failure occurs during seal generation, signing, hashing, or audit-log write When the caregiver attempts to complete the readout Then no content is delivered and the client receives a clear recoverable error message And the system retries up to 3 times over 60 seconds; on persistent failure, an incident is created and Privacy Stewards are notified within 5 minutes And no unsealed readout content is transmitted or spoken And upon recovery, the readout can be resumed and exactly one Proof Seal is created; duplicate seals are prevented
One-Tap Call Initiation & IVR Delivery
"As a caregiver, I want a one-tap way to deliver a compliant voice update so that I can save time and avoid phone tag while staying within policy."
Description

Enable caregivers to initiate compliant phone updates with a single tap from the resident’s profile. The system assembles the latest eligible updates, runs redaction and policy checks, then dials the authorized recipient via IVR, delivering the text-to-speech readout with clear, natural voices. Provide DTMF controls for repeat/slow/next, multi-language voice selection based on recipient preference, retries on no-answer, and safe voicemail behavior that omits PHI. Ensure seamless handoff from the caregiver app, minimal on-screen complexity, and automatic logging with the associated Proof Seal reference.

Acceptance Criteria
One-Tap Call Initiation From Resident Profile
Given a logged-in caregiver viewing a resident profile with ShareSafe Voice enabled And at least one authorized recipient exists When the caregiver taps "Call Update" Then the system assembles all eligible updates from the last 24 hours ordered newest-first And runs redaction and policy checks before any call is placed And the call attempt to the highest-priority authorized recipient begins within 3 seconds of the tap And the initiation flow requires no more than 1 user tap total And if no authorized recipient exists, the system blocks initiation and displays an error banner within 1 second
IVR Readout With DTMF Controls
Given a call is connected to an authorized recipient When the IVR begins the readout Then the text-to-speech voice is natural-sounding with 22 kHz or higher sample rate And the recipient can press 1 to repeat the current item within 1 second And the recipient can press 2 to slow speech rate to 0.85x within 1 second And the recipient can press 3 to skip to the next item within 1 second And the recipient can press 9 to end the call immediately And if no input is received for 10 seconds during a menu, the IVR plays a brief help prompt and resumes
Consent, Redaction, and Incident Freeze Enforcement
Given updates contain staff-only notes, room numbers, or consent-restricted content Or an active Incident Freeze applies to the resident When the system prepares the readout Then all staff-only notes are omitted And all room numbers are omitted And all content outside the recipient's consent scope is omitted And content under Incident Freeze is omitted And the resulting audio contains zero PHI tokens from the omitted fields And if all items are filtered, the IVR plays "There are no shareable updates at this time" and ends
No-Answer Handling, Retries, and Safe Voicemail
Given the system attempts a call to an authorized recipient When the call is not answered within 30 seconds Then the system retries up to 2 additional times at 5-minute intervals And if voicemail is detected, the system leaves only a non-PHI message: "KinLoop has a new update for you. Please call back to hear it." And the voicemail message contains no resident name, room number, condition, or care details And if voicemail cannot be confidently detected, no message is left and a retry is scheduled
Recipient Language and Voice Selection
Given a recipient has a preferred language and voice setting on file When the IVR readout begins Then the system uses the recipient's preferred language for prompts and content with locale-appropriate pronunciation And the selected TTS voice matches the stored preference And if the preferred voice is unavailable, the facility default voice for that language is used And if the preferred language is unsupported, the call uses the facility default language and logs the fallback
Proof Seal Call Logging and Auditability
Given a call attempt is initiated from a resident profile When the call flow completes (connected, voicemail, or failed) Then a log record is created within 2 seconds containing resident ID (hashed), recipient ID, dialed number (masked), timestamps, outcome, duration, DTMF actions, and the Proof Seal reference ID And the log is immutable and queryable by Privacy Stewards within 2 seconds of creation And if the call is aborted due to policy checks, the log records the policy reason and no audio content is stored
Anomaly Monitoring & Rate Limiting
"As a Privacy Steward, I want alerts and safeguards around voice access so that I can detect and contain misuse in real time."
Description

Continuously monitor access patterns and enforce rate limits to reduce misuse and over-disclosure risk. Apply per-resident and per-recipient thresholds, lockouts after repeated failed verifications, and geo/time-based heuristics. Generate real-time alerts to Privacy Stewards for unusual activity (e.g., spikes in calls, cross-resident access attempts), with dashboards and exports for investigation. Integrate with Proof Seal logs for end-to-end traceability and provide admin controls for whitelisting legitimate high-volume scenarios.

Acceptance Criteria
Per-Resident and Per-Recipient Call Rate Limiting
- Given resident R and recipient A with a limit of 3 readouts per 5 minutes configured, when A initiates a 4th readout for R within 5 minutes after successful verification, then the system returns HTTP 429 and plays TTS “Temporarily rate limited,” disclosing no content. - Given the 5-minute rolling window elapses so A has ≤3 readouts in the last 5 minutes, when A requests a readout for R, then the request succeeds and is not rate-limited. - Given a rate limit is enforced, then a Proof Seal entry is created with event_type=rate_limit and includes recipient_id, resident_id, count, threshold, window_start, window_end, and timestamp. - Given a rate limit is enforced, then the event appears in the Privacy Steward dashboard within 30 seconds. - Given an admin updates the per-resident/per-recipient thresholds, when the change is saved, then enforcement reflects the new values within 60 seconds and the configuration change is logged with a Proof Seal reference.
Lockout After Repeated Failed Verifications
- Given recipient A fails verification 5 times within 10 minutes, when a 6th attempt occurs within the same window, then the system enforces a 30-minute lockout, returns HTTP 423 and plays TTS “Account temporarily locked,” and discloses no content. - Given a lockout is active, when any verification attempt occurs, then the attempt is blocked and recorded with lockout_remaining in the audit log. - Given a lockout is triggered, then an alert is sent to Privacy Stewards via in-app notification and email within 30 seconds, including recipient_id, attempt_count, source identifiers, and Proof Seal reference. - Given 30 minutes elapse without admin override, then the lockout automatically expires and normal verification resumes; expiration is logged with Proof Seal.
Cross-Resident Access Spike Anomaly
- Given recipient A requests readouts for more than 3 distinct residents within 10 minutes without cross-resident authorization, then the system classifies an anomaly type=cross_resident_spike and sends a steward alert within 30 seconds containing the resident list and Proof Seal references. - Given a cross_resident_spike anomaly is active for A, when A requests additional readouts, then step-up verification (one-time code) is required; on failure, disclosure is blocked and the attempt is logged. - Given A has explicit authorization for each requested resident, when the same access pattern occurs, then no anomaly is raised; accesses are still logged with Proof Seal. - Given a steward acknowledges the anomaly in the dashboard, then step-up remains required until acknowledgment time + 60 minutes or a whitelist is applied; all state changes are logged with Proof Seal.
Geo/Time Heuristics and Step-Up Verification
- Given a call originates from a location ≥500 miles from A’s last known location within 24 hours or during a restricted time window, then risk_score ≥ threshold triggers step-up verification before any disclosure. - Given step-up verification succeeds within 120 seconds, then the readout proceeds; otherwise the session is terminated with no disclosure and is logged with reason=step_up_failed. - Given a high-risk geo/time event is detected, then a steward alert is issued within 30 seconds including geo delta, time factors, risk reasons, and Proof Seal reference. - Given geo data is unavailable, then time-based heuristics are applied; the system does not block unless risk_score ≥ threshold; the fallback decision and inputs are logged with Proof Seal.
Real-Time Alerts and Steward Dashboard Visibility
- Given any of rate_limit, lockout, cross_resident_spike, or high_risk_geo_time events occur, then a steward alert record is created within 5 seconds, delivered via in-app and email within 30 seconds, and appears on the dashboard with severity, actor, resident(s), event_type, and a Proof Seal link. - Given a steward filters the dashboard by resident R and a date range, then matching events return within 2 seconds for up to 10,000 events and paginate beyond that without timeouts. - Given a steward opens an event, then the Proof Seal link resolves to the immutable log entry with matching hash and timestamps for the underlying call(s).
Audit Exports with Proof Seal Integration
- Given a steward requests an export for a date range ≤31 days with filters (resident, recipient, event_type), then CSV and JSON exports are generated and available for download within 60 seconds for up to 100,000 events. - Given an export is generated, then each record includes event_id, event_type, resident_id, recipient_id, timestamp, outcome, enforcement_action, config_snapshot_id, and proof_seal_id; the export includes a chain root hash to validate integrity. - Given an unauthorized user requests an export, then the system returns HTTP 403 and no data is produced; the attempt is logged with Proof Seal.
Admin Whitelisting of Legitimate High-Volume Scenarios
- Given an admin creates a whitelist for recipient A and resident R with start_time, end_time, and scope (rate_limit, anomaly_alerts), then enforcement honors the rule within 60 seconds and suppresses only the selected controls during the window. - Given a whitelist is active, then all accesses are still logged with event_flag=whitelisted and associated proof_seal_id; no content outside consent scope is ever disclosed. - Given a whitelist expires or is revoked, then enforcement reverts immediately and a whitelist_end event is logged with Proof Seal. - Given overlapping whitelist rules exist, then the most permissive allowed behavior within the overlap is applied without bypassing verification or consent restrictions; resolution is logged with Proof Seal.

Deflect Insights

Live metrics show deflected calls, minutes saved, peak calling windows, listen‑through rates, and acknowledgment trends by resident and family. Exportable reports help administrators quantify impact, fine‑tune digest timing, and coach teams where additional clarity reduces callbacks further.

Requirements

Deflection Attribution Engine
"As an administrator, I want accurate attribution of deflected calls and minutes saved so that I can confidently report impact and make data-driven decisions."
Description

Compute and surface accurate deflected call counts and minutes saved by correlating inbound call logs with KinLoop update and digest events. Support ingestion of call volume baselines and ongoing logs via CSV/API, define configurable attribution windows (e.g., N hours after an update), and apply facility-specific baselines to estimate avoided calls post‑adoption. Provide resident- and family-level rollups, handle time zone differences, and expose methodology/tooltips for transparency. Include data quality checks, anomaly detection, and confidence intervals to ensure credibility of reported savings. Integrate with the analytics warehouse and power downstream dashboards and exports.

Acceptance Criteria
Call Log & Baseline Ingestion via CSV/API
Given a facility submits call logs via CSV upload or the authenticated API with required fields [facility_id, resident_id, family_id (nullable), call_id, direction=inbound, call_start_ts, call_end_ts or duration_sec, timezone (optional)] When the payload is processed Then valid rows are stored and available for attribution within 15 minutes, malformed rows are rejected with per-row error messages, and a downloadable error report is produced within 5 minutes And duplicate call_id or duplicate file re-uploads are ignored idempotently And sustained ingestion throughput is ≥50,000 rows/min for at least 5 minutes without data loss And baseline files (pre-adoption) and ongoing logs are tagged with data_period=baseline or data_period=post_adoption for modeling
Attribution Window Configuration & Recalculation
Given a facility admin sets an attribution window N hours (1–72) and saves the setting When the setting is saved Then new attributions immediately use N for future computations and a backfill job can be triggered to recompute the last 90 days with job status (Queued|Running|Succeeded|Failed) And if no setting exists, the default attribution window is 6 hours And the current window value is exposed as attribution_window_hours in API responses and dashboard metadata And changing N updates metrics within 30 minutes of backfill completion
Deflected Calls and Minutes Computation & Attribution
Given a facility-level baseline model per resident and hour-of-week exists (expected_calls_h, expected_avg_duration_sec_h) sourced from pre-adoption logs or an imported baseline When post-adoption inbound call logs and KinLoop update/digest events are present Then for each hour h: deflected_calls_h = max(0, round_half_up(expected_calls_h - observed_calls_h)) and minutes_saved_h = deflected_calls_h * (expected_avg_duration_sec_h/60) And each deflection_h is attributed to the most recent qualifying update/digest for the same resident within the last N hours; if none, the deflection is marked unattributed And the engine outputs per-hour and per-event attribution records including [event_id (nullable), resident_id, family_id (nullable), deflected_calls, minutes_saved, unattributed_flag, attribution_window_hours, baseline_version] And totals across hours equal daily totals within 0.1% rounding tolerance
Resident- and Family-level Rollups, APIs, and Warehouse Parity
Given attribution records exist When querying rollup endpoints/tables with filters (facility_id, resident_id, family_id, date_range) Then daily and cumulative metrics are returned: deflected_calls, minutes_saved, unattributed_deflections, CI_low, CI_high And API responses match warehouse table aggregates for identical filters within 0.1% And CSV exports up to 365 days and ≤1,000,000 rows generate within 60 seconds And pagination and sorting are supported without altering totals
Time Zone Normalization & DST Handling
Given calls may include explicit timezone and each facility has a default timezone When data is ingested and metrics are computed Then all timestamps are stored in UTC with facility_local_time materialized for queries And attribution windows and day boundaries are evaluated in the facility's local timezone And DST transitions do not double-count or drop hours (23/25-hour days are handled correctly) And cross-timezone families are normalized to facility time for attribution
Transparency: Methodology Metadata & Tooltips
Given a user views Deflect Insights metrics or calls the metrics API When the response is returned Then metadata fields are present: baseline_date_range, baseline_method, attribution_window_hours, attribution_rule, rounding_rule, CI_method, data_quality_flags And dashboard tooltips surface plain-language explanations that match the metadata and link to documentation And the API includes a methodology_url and schema_version for auditability
Data Quality Checks, Anomaly Detection, and Confidence Intervals
Given ingestion and computation complete When automated data quality checks run (on ingest and nightly) Then the system flags: missing_days_rate > 10%, duration_missing_rate > 30%, hourly spikes > 3 SD, and negative deflection artifacts And flagged periods are excluded from CI computation and labeled in outputs with reasons And 95% confidence intervals for deflected_calls and minutes_saved are computed when baseline_hours_n >= 30; otherwise CI fields are null with reason=insufficient_data And anomaly alerts are posted to monitoring with facility_id context within 10 minutes of detection
Real-time Deflection Dashboard
"As an administrator, I want live visibility into deflection metrics by resident and family so that I can monitor performance and quickly spot where to intervene."
Description

Deliver a responsive, role-aware dashboard that displays live metrics for deflected calls, minutes saved, listen‑through rates, and acknowledgment trends with filters for date range, facility, unit, resident, and family. Provide trend lines, heatmaps, and drill-downs to individual residents/families while preserving privacy constraints. Refresh data within a 5‑minute SLA, include hover definitions for each KPI, and support cohort comparisons (e.g., units using templates vs. not). Optimize for web and tablet, ensure accessibility compliance, and cache queries for performance.

Acceptance Criteria
Role-Aware Access & Privacy Enforcement
Given a user with Admin role scoped to Facility A, when they open the dashboard, then data is visible only for Facility A and not for any other facility. Given a user with Caregiver role assigned to Unit X, when they open the dashboard, then only Unit X data is visible and cross‑unit or cross‑facility data is not accessible. Given an aggregate chart or KPI, when it is rendered, then no personally identifying information (names, faces, contact details) or media is displayed. Given a cohort, trend, or heatmap bucket with fewer than 5 unique residents or families, when privacy thresholds are evaluated, then the bucket is suppressed or merged into "Other" rather than shown. Given a resident or family with an active consent restriction for analytics visibility, when aggregates and drill‑downs are produced, then their data is excluded from display for users without explicit permission.
5‑Minute Data Refresh SLA & Freshness Indicator
Given a new qualifying event is ingested at time T (e.g., deflected call, acknowledgment), when metrics are recomputed, then the affected KPIs and charts reflect the change by T+5 minutes at the 95th percentile and by T+7 minutes at the 99th percentile. Given the dashboard is open for more than 5 minutes, when the refresh interval elapses, then KPI tiles and charts auto‑refresh without a full page reload. Given the dashboard is displayed, when KPIs render, then each KPI shows a "Last updated" timestamp accurate to the minute in the facility’s local timezone. Given network connectivity is lost during auto‑refresh, when the refresh fails, then a non‑blocking stale data indicator is shown and the system retries within 60 seconds.
KPI Hover/Focus Definitions
Given a user hovers over a KPI info icon, when the tooltip appears, then it displays a plain‑language definition, the exact formula (numerator/denominator), and the active date range. Given a keyboard‑only user focuses the KPI info icon, when focus is set, then the same tooltip content is shown and can be dismissed with Escape. Given a screen reader is active, when the KPI info icon is focused, then the tooltip content is exposed via ARIA relationships and read in logical order. Given the user changes filters, when the tooltip is reopened, then the tooltip reflects the updated date range and formula parameters.
Filtering & Cohort Comparisons
Given the dashboard is loaded, when the user applies any combination of date range, facility, unit, resident, and family filters (including multi‑select), then all KPIs, charts, and tables reflect the intersection of those filters within 1.5 seconds at the 95th percentile. Given filters are cleared, when defaults are applied, then the dashboard defaults to the last 7 calendar days in the facility’s local timezone. Given a user enables cohort comparison, when Cohort A and Cohort B are selected (e.g., units using templates vs. not) under the same date range, then KPIs display side‑by‑side values with absolute and percentage deltas computed correctly. Given role‑based permissions, when cohort options are populated, then only facilities/units within the user’s scope are available for selection. Given the same filter and cohort selection is executed again within 10 minutes, when results are requested, then cached results are served with a response time under 800 ms at the 95th percentile without exposing data outside the user’s permission scope.
Visualizations—Trend Lines & Peak Calling Heatmaps
Given a selected date range greater than 48 hours, when trend lines render, then data points are aggregated daily with correct timestamps and consistent color mapping per KPI. Given a selected date range of 48 hours or less, when trend lines render, then data points are aggregated hourly with correct timestamps. Given the heatmap view is opened, when data is rendered, then the grid shows hour‑of‑day by day‑of‑week with accurate cell values and a legend that matches the scale used. Given the user hovers or taps a data point or heatmap cell, when a tooltip appears, then it shows the exact value, time bucket, active filters, and cohort (if applicable). Given no data exists for the selected filters, when charts render, then an accessible empty state is shown instead of a broken visualization.
Drill‑Down to Resident/Family Details with Consent Controls
Given a user clicks a KPI, trend point, table row, or heatmap cell, when a drill‑down is requested, then a detail view opens scoped to that slice and inherits all active filters and cohort selections. Given the user lacks permission for a resident or family in the drill‑down scope, when the detail is rendered, then restricted rows are omitted or anonymized and no personally identifying information is displayed. Given a resident or family has a consent restriction for analytics display, when drill‑down data is prepared, then those records are excluded from the result set. Given the drill‑down is opened, when content is shown, then no photos or media are displayed; only numeric and textual metadata within policy are shown. Given the user navigates into a drill‑down, when they choose to go back, then breadcrumbs allow returning to the parent view without losing filter context, and deep links do not expose PII in the URL. Given a drill‑down is requested, when results are returned, then the detail view loads within 1.5 seconds at the 95th percentile.
Performance, Caching, Accessibility, and Device Optimization
Given a cold start on a 10 Mbps connection, when the dashboard loads, then first meaningful paint occurs within 2 seconds at the 95th percentile. Given subsequent interactions with existing filters, when results are requested, then responses complete within 1.5 seconds at the 95th percentile by leveraging cached queries. Given caching is enabled, when cache entries are created, then cache keys include user role, permission scope, filters, and cohort selections, and time‑to‑live is 10 minutes with immediate invalidation on new data affecting the result. Given the dashboard is evaluated against WCAG, when accessibility tests run, then the experience meets WCAG 2.2 AA including keyboard navigation, visible focus, non‑color indicators, ARIA labeling for KPIs/charts, and color contrast of at least 4.5:1. Given the dashboard is opened on tablet and web, when layout is applied, then the UI adapts to common breakpoints (≥768 px) with touch targets of at least 44×44 px and no horizontal scrolling required in portrait orientation.
Peak Calling Window Detection
"As an administrator, I want to know when families are most likely to call so that I can adjust digest timing to reduce interruptions."
Description

Identify and visualize peak inbound calling windows by hour and day-of-week using historical call logs and correlate them with digest send times. Produce a time‑of‑day heatmap and recommended digest timing adjustments per facility/unit to minimize inbound calls. Handle time zone and daylight saving shifts, allow simulation of alternative send times with predicted impact, and log accepted recommendations for later ROI analysis.

Acceptance Criteria
Hour-by-Day Peak Heatmap Generation
Given a facility/unit has at least 7 days of inbound call logs timestamped in UTC and a configured time zone When the user opens Deflect Insights > Peak Windows with date range = Last 30 days Then a 24x7 heatmap renders within 5 seconds using local facility time with hourly bins 00–23 and days Sun–Sat And each cell tooltip shows absolute call count and percentage of total for the selected range And switching date range to 7/30/90 days recomputes within 5 seconds And if fewer than 7 days of data exist, an "Insufficient data" message is displayed and no recommendation is generated
Digest Send-Time Correlation Overlay
Given digest send times exist for the selected facility/unit and date range When the user toggles "Overlay digest send times" Then markers appear at the digest hour per day-of-week on the heatmap And the UI displays average calls in the 2 hours post-digest vs the overall hourly average with absolute and % delta And metrics recompute when date range, facility, or unit filters change
Facility/Unit Scoping and Filters
Given a facility with multiple units and call logs tagged by unit When the user selects a specific unit or "All units" Then the heatmap, correlation, and recommendations are computed for the selected scope only And the scope selection is reflected in titles/exports and persists for the session And unit-level results exclude calls not attributed to that unit
Recommended Digest Timing per Unit
Given allowed digest send hours are configured (e.g., 08:00–20:00 local) And at least 30 days of call history exist for the selected scope When the user requests a recommendation Then the system proposes a single hour that minimizes predicted calls in the 2-hour window post-digest within the allowed window And shows the top 3 candidate hours with predicted calls and expected % reduction vs current And shows "No change recommended" if expected reduction < 5%
Time Zone and Daylight Saving Handling
Given call logs are stored in UTC and the facility time zone is set When viewing dates that include a DST transition Then hourly bins are computed using local wall time with 23-hour or 25-hour days correctly aggregated And all displayed times include time zone abbreviation (e.g., MDT/MST) And changing the facility time zone updates computations and labels consistently
Alternative Send-Time Simulation with Predicted Impact
Given the current digest send hour is configured for the selected scope When the user selects up to 3 alternative hours and clicks "Simulate" Then the system returns predicted calls for each alternative and % change vs current within 3 seconds And displays an 80% confidence interval for each prediction And does not modify the live schedule until the user accepts a change
Acceptance Logging for ROI Analysis
Given the user has Admin role When the user accepts a recommended or simulated digest time Then an immutable log entry is written within 1 second containing facility/unit id, previous time, new time, model version, data range used, predicted change, user id, UTC timestamp, and a snapshot reference And the entry is visible in the ROI log list and exportable to CSV for a selected date range
Listen-through and Acknowledgment Analytics
"As a care lead, I want to see listen-through and acknowledgment patterns so that I can understand engagement and improve update quality."
Description

Instrument and calculate engagement metrics across media types, including percent listened, completion rate, average listen duration, photo view rate, and time‑to‑acknowledgment. Break down results by resident, family, unit, and update type, and track trends over time. Surface low‑engagement segments and content patterns to inform coaching. Ensure event schemas are standardized, privacy-preserving, and stored in the analytics warehouse for reuse.

Acceptance Criteria
Percent Listened and Completion Rate Calculation
Given an audio update of length L seconds and a family member listens for t seconds (including seeks/replays), When the session ends, Then percent_listened is recorded as min(round((unique_seconds_heard/L)*100), 100). Given multiple sessions by the same family member for the same update within 24 hours, When aggregating, Then the listener’s percent_listened equals the max across their sessions. Given an update with N unique listeners, When calculating completion_rate, Then completion_rate = count of listeners with percent_listened >= 90 divided by N and is displayed with one decimal place. Given live playback crosses 90% for a listener for the first time, When the threshold is reached, Then completion_rate updates within 60 seconds. Given client/server clock skew up to 2 seconds, When computing listened_ms, Then absolute error is <= 2 seconds.
Average Listen Duration Accuracy
Given a listener replays portions of an update with length L, When computing listened_duration for that listener, Then the duration is capped at L seconds. Given K unique listeners for an update, When calculating average_listen_duration, Then it equals sum of each listener’s capped duration divided by K and is rounded to the nearest second. Given filters by resident, family, unit, or update type are applied, When querying average_listen_duration, Then the result matches the aggregation across the selected cohort within 0.1% of the value returned by a direct warehouse query. Given a session ends, When metrics are recalculated, Then average_listen_duration reflects the new data within 60 seconds.
Photo View Rate Tracking
Given an update with M recipients and P unique viewers who viewed at least one photo for >= 2 seconds, When calculating photo_view_rate, Then photo_view_rate = P/M and is displayed as a percentage with one decimal place. Given a carousel with multiple photos, When calculating per-photo view rate, Then a viewer counts for a photo only if that photo was in view for >= 2 seconds; per-update view rate counts viewers who viewed any photo. Given a recipient opens the update but does not view any photo for >= 2 seconds, When metrics are computed, Then the recipient is not counted as a viewer. Given the same recipient views multiple times, When aggregating, Then the viewer is deduplicated per update and per photo. Given a viewing session ends, When metrics are recalculated, Then photo_view_rate updates within 60 seconds.
Time-to-Acknowledgment Measurement
Given an update is delivered at delivered_at in facility local timezone, When the first acknowledgment event is recorded from any approved family member, Then time_to_ack = floor((ack_at - delivered_at) in minutes). Given no acknowledgment within 72 hours, When computing time_to_ack, Then time_to_ack is null and the update is included in the unacknowledged count. Given multiple acknowledgment events, When calculating time_to_ack, Then only the earliest acknowledgment is used, and total_acks is incremented for each unique acknowledger. Given filters by resident, family, unit, or update type, When viewing time_to_ack metrics, Then median and p90 are computed for the selected cohort and match warehouse results within 0.1%.
Segmentation, Trends, and Time Window Controls
Given filters by resident, family, unit, and update type, When any combination is applied, Then all metrics recompute within 5 seconds for cohorts up to 50,000 events. Given no filters are selected, When viewing metrics, Then results default to facility-wide values. Given a time window of Last 7 days, Last 30 days, Quarter-to-date, or Custom (max 365 days) is selected, When rendering trend lines, Then points align to facility local day boundaries and days without activity display zero values. Given the time window or filters change, When exporting CSV, Then the export reflects the same range, granularity (daily/weekly), filters, and matches on-screen totals within 0.1%.
Low-Engagement Surfacing and Content Pattern Insights
Given any segment (resident, family, unit, update type) with at least 30 updates in the selected window, When ranking engagement, Then flag low engagement if any of: average percent_listened < 50%, photo_view_rate < 30%, or median time_to_ack > 1440 minutes. Given low-engagement segments exist, When viewing the dashboard, Then the top 10 segments are listed with metric values, sample size (n), and a link to example updates. Given content attributes (media length buckets 0–15s, 16–60s, >60s; update type; send time hour bucket), When analyzing low-engagement segments, Then the top 3 attributes most correlated with low engagement are shown with lift scores and confidence n. Given an export is requested, When generated, Then the CSV includes for each low-engagement segment: segment_type, segment_id/name, metrics, n, correlated_attributes, and suggested coaching cue.
Event Schema, Privacy, and Warehouse Ingestion
Given event types listen_start, listen_progress, listen_end, photo_view, update_delivered, update_acknowledged, When emitted, Then each conforms to schema_version v1 with required fields: event_id (UUID), event_type, schema_version, occurred_at_ms, received_at_ms, facility_tz, resident_id_hash, family_id_hash, unit_id, update_id, media_type, media_length_ms, listened_ms (when applicable), percent_listened (when applicable), view_seconds (when applicable), client_type, consent_scope. Given privacy requirements, When events are recorded, Then no raw names, emails, or phone numbers are stored; identities are hashed with a per-tenant rotating salt; consent_scope excludes non-consenting individuals; and resident-level delete requests remove related events from the warehouse within 7 days. Given events are ingested to the analytics warehouse, When querying, Then 99.9% of events are available within 5 minutes; late events are backfilled within 24 hours; duplicates are suppressed via event_id idempotency. Given warehouse datasets are published, When analysts discover metrics, Then materialized views for percent_listened, completion_rate, average_listen_duration, photo_view_rate, and time_to_ack refresh within 10 minutes and are documented for reuse.
Exportable Reports and Scheduled Delivery
"As an administrator, I want exportable and scheduled reports so that I can share results with leadership and meet compliance reporting needs."
Description

Provide configurable export options (CSV, XLSX, PDF) for KPI summaries, resident/family breakdowns, and unit scorecards, with data dictionaries embedded for clarity. Enable one‑time downloads and scheduled email deliveries (weekly/monthly) to authorized recipients with secure, expiring links and watermarking. Support multi-tenant branding, time zone selection, and audit logs of generation and access. Apply redaction rules and aggregation thresholds on exports to protect privacy.

Acceptance Criteria
XLSX/CSV/PDF Exports with Embedded Data Dictionary
- Given an admin selects any of KPI summaries, resident/family breakdowns, or unit scorecards and format = XLSX, When the export completes, Then the file contains a worksheet named "Data Dictionary" listing every exported column with fields: Column Name, Definition, Data Type, Unit, and Calculation Notes. - Given format = PDF, When the export completes, Then the PDF includes an appendix section titled "Data Dictionary" containing one entry per exported column with the same fields as above. - Given format = CSV, When the export completes, Then the download bundle includes a companion file named data_dictionary.csv containing one row per exported column with fields: column_name, definition, data_type, unit, calculation_notes. - Given any export, When comparing the exported column headers to the data dictionary entries, Then there is a one-to-one match with no missing or extra columns. - Given a column defined as percentage or minutes in the data dictionary, When inspecting the export, Then the values adhere to the specified unit and data type (e.g., percentages rendered as numeric ratios or percent strings as specified).
Scheduled Weekly/Monthly Delivery via Expiring Secure Links with Watermarks
- Given a schedule configured for weekly delivery on a specified weekday and time in time zone T with recipients R, When the scheduled time arrives, Then each recipient in R receives an email containing a secure, expiring download link to the report. - Given a schedule configured for monthly delivery on a specified day-of-month and time in time zone T, When a month does not contain that day, Then the delivery occurs on the last day of that month at the configured time. - Given a secure link with TTL = X (as configured), When X has elapsed since generation, Then attempts to access the link return 410/expired and no file is served. - Given a delivered report in PDF or XLSX format, When opened, Then a visible watermark appears on each page/sheet containing the tenant name and the text "Confidential". - Given a recipient who was not included in the schedule (or an unauthenticated user), When they attempt to access the secure link, Then access is denied (HTTP 403) and the attempt is logged. - Given multiple recipients, When each accesses their link, Then each access is individually logged and the same report content is delivered for that run (identical checksum).
Multi‑Tenant Branding and Time Zone Application in Reports
- Given tenant branding settings (logo, display name, primary color), When exporting to PDF/XLSX, Then the header displays the tenant logo and name, and styled elements use the tenant primary color. - Given a CSV export, When downloaded, Then the file name includes the tenant display name or slug and report type (e.g., tenantslug_kpi_summary_YYYYMMDD.csv). - Given time zone selection = T for the export, When examining time-based fields and aggregations (e.g., day/hour buckets, peak calling windows), Then all timestamps and bucket labels are expressed in T and the selected time zone is stated in the report header/metadata. - Given a date range spanning a daylight saving time change in T, When exporting hourly aggregations, Then the number of hourly buckets and their labels reflect local time without duplicate labels; the DST transition is noted in the header/metadata. - Given a user from Tenant A, When exporting, Then only data for Tenant A is included and no identifiers from other tenants appear in content, metadata, file name, or watermark.
Redaction Rules and Aggregation Thresholds Enforced in Exports
- Given a tenant-configured minimum aggregation threshold K, When generating resident/family breakdowns, Then any grouping with count < K is excluded or rolled into an "Other" group and sensitive measures in such groups are replaced with "[REDACTED]". - Given a recipient role without access to personal identifiers, When exporting resident/family breakdowns, Then fields designated as PII (e.g., full name, email) are omitted or tokenized per policy and marked as redacted in the data dictionary. - Given redactions are applied, When reviewing the PDF/XLSX header or CSV README/metadata, Then a note indicates that redaction rules and threshold K were enforced on this export. - Given an attempt to disable redaction via query parameters or UI overrides, When the export runs, Then policy-based redaction still applies and the override is ignored. - Given totals are shown alongside redacted rows, When summing visible groups including "Other", Then totals equal the unredacted aggregate displayed in the Deflect Insights dashboard for the same filters and range.
Audit Logging of Report Generation and Access
- Given a one-time export is requested, When the job starts and completes, Then two immutable audit log entries are created capturing tenantId, requesterId, reportType, filters, format, startedAt, completedAt, status (success/failure), and checksum of the output. - Given a scheduled export triggers, When emails are sent, Then an audit entry records scheduleId, runId, recipients list (hashed or IDs), generatedAt, expiresAt, and delivery status per recipient. - Given a secure link is accessed, When the file is downloaded or access is denied, Then an access log entry records runId/linkId, recipientId (or unauthenticated), ip, userAgent, accessedAt, and outcome (downloaded/denied/expired). - Given compliance admin permissions, When viewing audit logs for a date range, Then all related entries are visible and read-only; attempts to modify entries are blocked and logged as denied. - Given retention policy R, When querying logs older than R, Then entries are no longer available and the system reports that they have been purged per policy.
One‑Time Authorized Download with Role‑Based Access Control
- Given a user with Reports.View permission selects report type, scope (tenant/unit/resident), time range, format (CSV/XLSX/PDF), and time zone, When they click Export, Then a downloadable file is generated and available via a secure link. - Given a user without Reports.View permission attempts to export, When they click Export, Then the action is blocked with an authorization error and no file/link is created. - Given a generated secure link with TTL = X, When X elapses, Then the link can no longer be used to download the file. - Given the download is attempted from a different tenant context, When accessing the link, Then access is denied (HTTP 403) and the attempt is logged. - Given PDF/XLSX formats, When the file is opened, Then a watermark with tenant name "Confidential" is present; for CSV, Then the file name includes the tenant slug and a disclaimer is included in the metadata/companion file.
Export Content Accuracy for Deflect Insights KPIs
- Given filters (date range, unit(s), resident(s), family group(s)) and time zone T are applied in the Deflect Insights dashboard, When exporting KPI summaries and scorecards in any format, Then metric values (deflected calls, minutes saved, peak calling windows, listen‑through rates, acknowledgment trends) match the dashboard values under the same filters and T. - Given the export includes peak calling windows, When examining the output, Then peak windows correspond to the top N time buckets used in the dashboard and are labeled in time zone T. - Given the data dictionary specifies units and precision for each metric column, When inspecting exported values, Then units and precision match the specification (e.g., minutes as numeric minutes, rates as percentages to the stated decimal places). - Given resident/family breakdowns are exported, When counting rows after redaction/aggregation, Then the number of rows equals the number displayed in the dashboard list for the same filters, excluding any groups suppressed by threshold K. - Given totals and subtotals are provided, When recomputing from row-level data, Then the recomputed totals equal the summarized values shown in the export header and match the dashboard totals.
Coaching Insights and Clarity Recommendations
"As a care manager, I want actionable coaching insights so that my team can reduce callbacks by making clearer updates."
Description

Correlate callbacks with engagement signals to flag updates likely to trigger follow-up calls and generate actionable guidance. Provide a clarity score based on heuristics (e.g., presence of key details, length, use of templates), recommend phrasing/templates, and show before/after impact when guidance is applied. Present unit and individual coaching opportunities, track adoption of recommendations, and protect PHI by running models on redacted text and excluding sensitive fields from storage.

Acceptance Criteria
Real-time Clarity Score in Composer
Given a caregiver is composing an update and stops typing for 1 second, When scoring runs on the redacted draft, Then a 0–100 clarity score and an explanation of detected/missing key details display within 500 ms. Given the draft is shorter than 20 characters after redaction, When scored, Then the UI shows "Insufficient content" and no score. Given two drafts that differ only by the presence of an approved template tag, When scored, Then the template draft's score is at least 5 points higher and the explanation cites "Template used". Given the same draft is scored 10 times within a session, When compared, Then the score variance is 0 and the explanations are identical.
Proactive Callback Risk Flagging
Given the system has at least 30 days of engagement signals for the resident-family pair, When a draft meets the high-risk rule (missing time-of-event OR medication detail) AND the pair’s 30-day callback rate is above unit median, Then a "High risk of callback" banner appears before send with top 3 contributing factors. Given the draft does not meet any risk rules and the pair’s 30-day callback rate is below unit median, When scored, Then no risk banner shows. Given historical data for the last 90 days, When backtesting the risk model, Then precision-at-High >= 0.60 and recall-at-High >= 0.40; results are viewable in the admin QA report.
Actionable Guidance with Quick Apply
Given a draft has clarity score < 70 or shows a risk banner, When guidance is requested or auto-shown, Then at least 3 ranked recommendations render within 1 second with estimated score deltas. Given the caregiver taps "Quick Apply" on a recommendation, When applied, Then the draft text updates, placeholders remain bracketed for review, and an undo option persists for 30 seconds. Given recommendations are applied, When rescored, Then the new score and risk label update and a before/after comparison is shown inline.
Before/After Impact Visualization
Given an update where at least one recommendation was applied, When the message is sent, Then the system records pre-apply score/risk and post-apply score/risk along with an adoption flag. Given the admin opens Coaching Impact, When filtered by date range, unit, caregiver, or resident, Then the dashboard shows adoption rate, average score lift, and 14-day callback rate change with definitions. Given an impact view is open, When "Export CSV" is clicked, Then the file downloads within 5 seconds containing the visible aggregates and no PHI fields.
Unit and Individual Coaching Opportunities
Given the admin opens Coaching Opportunities, When the view loads, Then units and caregivers are ranked by estimated callback reduction potential with visible criteria (avg score, risk rate, listen-through, acknowledgments). Given a coaching item is selected, When "Assign coaching" is pressed, Then a coaching task is created, the assignee receives an in-app notification, and the item status updates to "Assigned". Given a coaching task is marked "Reviewed", When metrics refresh overnight, Then the item can move to "Improving" if callback rate drops >= 10% versus prior 14-day baseline.
PHI Redaction and Storage Controls
Given any draft text, When sent to scoring or risk services, Then PHI redaction runs first and only redacted text is processed; the raw text is not logged or persisted outside the messaging store. Given application logs, When searched for resident names, DOB, MRN, or contact info, Then zero matches are found for inference-service logs across the last 30 days. Given an export or admin report is generated, When fields are reviewed, Then no PHI fields are present; only aggregates and anonymized IDs are included. Given an access audit, When reviewing inference requests, Then an audit record shows timestamp, redaction version, model version, and requester without PHI payload.
Role-based Access and Privacy Guardrails
"As a compliance-conscious administrator, I want insights restricted by role and consent so that resident privacy and regulations are upheld."
Description

Enforce strict RBAC and consent-aware filtering for all insights, limiting visibility by role, facility, and resident assignment. Apply minimum aggregation thresholds to prevent re‑identification, mask PII in dashboards and exports, and require explicit permissions for detailed drill‑downs. Maintain comprehensive audit trails, configurable data retention policies, and HIPAA/SOC 2‑aligned controls. Integrate with existing KinLoop user/tenant models to ensure consistent access across web and exports.

Acceptance Criteria
Enforce RBAC Scoping Across Web and Exported Insights
Given a user with role Caregiver assigned to Facility A and Residents R1,R2, When viewing Deflect Insights, Then only Facility A metrics are visible and resident-level views are limited to R1,R2. Given the same user, When exporting insights, Then the export contains only rows within Facility A and Residents R1,R2 and excludes all other facilities and residents. Given a user without facility assignment, When accessing Deflect Insights, Then access is denied with HTTP 403 and no data is returned. Given a Super Admin with cross-facility permission, When viewing or exporting, Then data from all facilities within their tenant is visible; data from other tenants is not. Given tenant or role changes in KinLoop’s user model, When the user refreshes, Then access scopes reflect the updated assignments within 60 seconds.
Consent-Aware Filtering of Residents and Families
Given a resident marked as No-Share/No-Consent, When any user below PrivacyOfficer role views insights, Then the resident is excluded from resident-level insights and from exports. Given the same resident, When an Admin with PrivacyOfficer permission views aggregated metrics, Then the resident's data is included only in aggregates that meet threshold k and no identity-revealing fields are shown. Given a family member without consent on file, When viewing family-facing metrics, Then listen-through and acknowledgment metrics for that family are hidden or zeroed. Given consent status changes, When the status is updated, Then filtering takes effect across web and exports within 60 seconds.
Aggregation Thresholds to Prevent Re-identification
Given a query result for any dimension where count < k (tenant-configurable, default 5), When rendering or exporting, Then the cell is suppressed with 'Suppressed (<k)' and drilldown is disabled. Given a time-series bucket with <k events, When exporting, Then the bucket is suppressed or merged per policy without exposing counts <k. Given combined filters that reduce cohort size below k (e.g., Facility A + Caregiver B + Day D), When applied, Then the UI displays a suppression message and returns no rows. Given threshold k is updated by a tenant admin, When saved, Then the new threshold applies to subsequent queries and is recorded in audit logs.
PII Masking in Dashboards and Exports
Given dashboard views, When rendering resident or family identifiers, Then show resident initials and family relationship only; full names, emails, and phone numbers are masked (e.g., J.D., ****@****, (***) ***-1234). Given a CSV/PDF export without ExportPII permission, When generated, Then PII columns are omitted or masked and no raw identifiers appear. Given ExportPII permission present, When exporting, Then only the minimum necessary PII fields configured by tenant appear, with a banner indicating sensitive export; export links expire after 15 minutes. Given an automated data scan, When scanning dashboard HTML and export files for email and phone patterns, Then zero unmasked PII matches are found.
Permission-Gated Resident-Level Drilldowns
Given a user without Insights.Drilldown permission, When clicking an aggregate metric, Then drilldown is disabled and a tooltip explains the required permission. Given a user with Insights.Drilldown and within assigned resident scope, When drilling down, Then resident-level rows are visible only for assigned residents and respect consent flags and threshold rules. Given a user with Insights.Drilldown but outside scope, When attempting drilldown, Then the API returns 403 and the UI shows no data. Given a temporary drilldown grant is issued, When the grant duration elapses (default 8 hours), Then access auto-revokes and all drilldowns during the window are logged.
Configurable Data Retention and Purging for Insights Data
Given a tenant retention policy of N days (30–365 configurable), When the nightly job runs, Then insights events older than N days are purged or archived per policy and are no longer queryable or exportable. Given legal hold is enabled for a tenant or resident, When retention jobs run, Then held records are retained and flagged; access still respects RBAC and consent. Given exports are generated, When signed URLs are issued, Then they expire within 15 minutes (configurable) and are invalid after expiry. Given an admin updates retention settings, When saved, Then changes are enforced from the next scheduled job and the change is recorded in audit logs with actor, old value, new value, and timestamp.
Comprehensive Audit Trails and Compliance Controls
Given any access to Deflect Insights pages or APIs, When a session reads data, Then an immutable audit record is written with user, role, tenant, scope, action, timestamp, and client IP. Given any export generated or download attempted, When initiated, Then an audit record includes export type, row count, filter scope, and download status. Given any permission or configuration change (RBAC assignment, threshold k, retention, consent override), When saved, Then the audit log captures actor, previous value, new value, and reason field. Given an integrity check, When verifying the audit store, Then records are tamper-evident (hash-chained) and retained for at least 1 year or a tenant-configured period; access to audit logs is RBAC-restricted. Given security is assessed, When inspecting transport and storage, Then TLS 1.2+ is enforced for insights endpoints and PHI is encrypted at rest using AES-256 or cloud KMS equivalent.

One-Time Link

Create single-use or limited-view links that auto-expire after a set duration or first open. Snapshot Aides can share quickly without worry that a link lingers or spreads, while families get just-in-time access that disappears when no longer needed.

Requirements

Link Composer & Content Packaging
"As a Snapshot Aide, I want to quickly package a photo and update into a sharable one-time link so that I can hand off information without extra steps or privacy risk."
Description

Enable Snapshot Aides to select one or more photos, short text/voice-to-text updates, and optional resident context, then generate a shareable package encapsulated behind a one-time link. The composer should support auto-blur of non-consenting faces, strip EXIF/PII, and bundle assets into a lightweight, CDN-backed payload. It integrates with existing Snapshot workflows, allowing one-tap creation from a captured update and storing only server-side references so nothing sensitive appears in the URL.

Acceptance Criteria
One-Tap Creation from Snapshot Flow
Given an aide has just captured a Snapshot update in the app And at least one photo or text/voice-to-text note is present When they tap "Share as One-Time Link" Then the composer opens with the captured assets preselected And the expiry option defaults to the site’s configured default And the "Generate Link" action is enabled When "Generate Link" is tapped Then the link is created within 2 seconds And a share sheet with Copy and native share options is displayed And the generated URL contains no readable identifiers
Multi-Asset Packaging & Voice-to-Text Inclusion
Given the aide selects 1–10 photos and optionally enters text or dictates a voice note When generating the package Then the package contains the selected photos in the chosen order And dictated audio is transcribed to text and included; no audio file is shared And entered/transcribed text is shown for review and can be edited before share And the Generate action is disabled if no assets (photos or text) are selected And the resulting package renders correctly on modern mobile and desktop browsers
Auto-Blur of Non-Consenting Faces
Given one or more selected photos contain faces of residents marked as non-consenting When the composer preview renders and the package is generated Then those faces are automatically blurred to a level that obscures identification And faces of consenting residents remain unblurred And the aide cannot disable blur for non-consenting faces And downloaded assets from the link retain the applied blur
Metadata Sanitization & Opaque URL
Given selected photos may contain EXIF or embedded metadata When the package is generated Then all EXIF, including GPS coordinates, device model, timestamps, and serial identifiers, are removed from delivered assets And original filenames are replaced with non-guessable IDs And the shared URL contains only an opaque token with at least 128 bits of entropy and no resident or facility identifiers And no PII, asset keys, or resident names appear in the URL path, query string, or page HTML And assets are retrieved server-side via the token; direct asset IDs are never embedded in the URL
CDN-Backed Delivery & Payload Optimization
Given the package is generated When a recipient opens the link Then media assets are served from the configured CDN domain via signed, time-limited URLs And image assets are optimized to a web format and resolution suitable for on-screen viewing (no original full-resolution files are delivered) And CDN cache headers are set to respect the link’s expiry, preventing caching beyond expiration And opening the link does not require installing the app
Link Expiry and Single-Use Enforcement
Given the aide configures the link as single-use or sets a duration When a recipient opens a single-use link Then the content renders once and subsequent attempts show an Expired message with no asset access When a recipient opens a duration-based link after the configured expiry Then the link shows Expired and no assets are accessible And attempts to access assets directly via CDN after expiry are denied by signature/TTL enforcement And the system records first-open timestamp and total open count for auditing
Expiry & View-Limit Configuration
"As an Administrator, I want links to auto-expire by time or after a limited number of views so that shared updates disappear when no longer needed and cannot be reused."
Description

Provide configurable expiration controls at creation time, including time-based TTL (e.g., 15 minutes to 7 days), first-open expiry, and limited-view counts (e.g., single-use or up to N opens). Defaults inherit from site-wide policy while allowing per-link overrides within policy bounds. Expiry metadata is stored server-side and evaluated on access to ensure links self-terminate as configured across devices and channels.

Acceptance Criteria
Time-Based TTL Selection and Enforcement
Given a site policy with a minimum TTL of 15 minutes and a maximum TTL of 7 days, When a creator selects a time-based TTL within those bounds at link creation, Then the link is created and the server stores an expiresAt timestamp in UTC based on server time. Given a link with a time-based TTL, When the TTL elapses per server time, Then any access attempt returns HTTP 410 Gone with reason "expired" and no content is returned. Given a client device has incorrect local time, When it accesses a non-expired link, Then content is returned until the server-side TTL elapses, independent of client time. Given a creator attempts to set a TTL outside policy bounds, When the request is submitted, Then the backend rejects with HTTP 400 and the UI displays a policy-bound validation message.
First-Open Expiry Behavior
Given "Expire on first open" is selected at link creation, When the first successful content retrieval occurs, Then the link immediately transitions to expired state and viewsUsed is set to 1. Given a link configured to expire on first open, When any subsequent access occurs after the first successful retrieval, Then the server returns HTTP 410 Gone with reason "first-open consumed" and no content. Given two nearly simultaneous first-access requests, When they reach the server, Then only one request returns HTTP 200 with content and the other returns HTTP 410, ensuring atomic single consumption.
Limited View Count Enforcement
Given a link with viewLimit N (N ≥ 1), When a user retrieves the content successfully (HTTP 200), Then viewsUsed increments atomically and is persisted server-side. Given viewsUsed equals viewLimit, When any further access is attempted, Then the server returns HTTP 410 Gone with reason "view limit reached" and no content is returned. Given requests that do not return protected content (e.g., HEAD or metadata-only responses), When they occur, Then viewsUsed does not increment. Given multiple concurrent accesses when remaining views = 1, When they occur, Then only one returns HTTP 200 with content and the others return HTTP 410, preventing over-consumption.
Default Inheritance and Per-Link Overrides
Given site-wide defaults for expiry mode, TTL, and viewLimit, When the create-link form loads, Then those default values are preselected. Given the creator retains the defaults, When the link is created, Then stored metadata reflects the defaults and policyId. Given the creator overrides values within policy bounds, When submit is pressed, Then the link is created and the override values are persisted server-side. Given the creator provides an override value outside policy bounds, When submit is pressed, Then the backend rejects with HTTP 400 and the UI displays the exact violated bound (e.g., min/max TTL or max viewLimit).
Server-Side Metadata and Cross-Channel Enforcement
Given a link is created, When it is persisted, Then the server stores at minimum: mode (timeTTL | firstOpen | viewLimit), createdAt (UTC), expiresAt (UTC if applicable), viewLimit (if applicable), viewsUsed (starting at 0), and policyId. Given the link is accessed via any channel (web, app deep link, SMS, email), When the request reaches the server, Then the server evaluates expiry metadata before returning any content. Given the link is expired or the view limit is reached, When it is accessed, Then the server responds with HTTP 410 Gone, includes a reason code, and sets Cache-Control: no-store with no protected payload. Given the link is valid, When it is accessed, Then the server responds HTTP 200 with content and sets Cache-Control: no-store to prevent client/proxy caching.
Recipient Messaging for Expired or Exceeded Links
Given a link has expired by time, When a recipient opens it, Then the UI displays "This link has expired" and no content details are revealed. Given a link has reached its view limit, When a recipient opens it, Then the UI displays "This link is no longer available (view limit reached)" and no content is shown. Given an invalid or tampered token, When a recipient opens it, Then the UI displays a generic "Link invalid or expired" message without confirming the existence of specific content.
Secure Tokenized Delivery
"As a Compliance Officer, I want one-time links to be cryptographically strong and reveal no sensitive information in the URL so that regulatory and privacy requirements are met."
Description

Generate non-guessable, signed tokens for each link with sufficient entropy and short path lengths, avoiding resident names or identifiers in URLs. Enforce HTTPS-only transport, HSTS, and cache-control headers to prevent persistence on intermediaries. Tokens map to server-side access intents, not raw objects, ensuring the content can be revoked independently of the URL. Include optional watermarking of media and on-screen disclosure to deter screenshots.

Acceptance Criteria
Signed, High-Entropy Token Generation
Given a request to create a one-time link When the token is generated Then the token shall be created using a CSPRNG with ≥128 bits of entropy And the token value shall be unique across a sample of 1,000,000 generated tokens with 0 collisions And the token shall be signed and verifiable using the server-held key (e.g., JWS) with verification succeeding for untampered tokens and failing for any modified token payload or signature And the token shall be URL-safe (Base64url or equivalent) with no padding characters
PII-Free, Short URL Path
Given a generated one-time link Then the URL path shall consist of a single opaque token segment ≤64 URL characters And the URL shall contain no resident names, MRNs, DOBs, room numbers, or other identifiers And the URL shall contain no query parameters other than the token (or none) And the total URL length shall be ≤256 characters And automated static checks shall flag and block any attempt to embed PII into the path or query
HTTPS-Only Access with HSTS
Given any attempt to access the tokenized link over HTTP When the request is received Then the server shall not serve content over plaintext and shall respond with a redirect to HTTPS (301/308) or a 403 policy denial And all successful content delivery shall occur over TLS v1.2+ with modern ciphers (no RC4/3DES) And responses shall include Strict-Transport-Security with max-age ≥ 15552000 and includeSubDomains And no mixed-content requests shall be present on the page
No-Cache Intermediary Controls
Given a successful HTTPS response for a tokenized link Then response headers shall include Cache-Control: no-store, no-cache, max-age=0, private And response headers shall include Pragma: no-cache and Expires: 0 And responses delivered via CDN or proxy shall include Surrogate-Control: no-store (or equivalent) and be marked uncacheable And subsequent requests from a fresh client shall not be served from intermediary cache (verified by CDN/proxy cache status = MISS)
Server-Side Intent Mapping and Revocation
Given a valid tokenized link Then the token shall resolve to a server-side access-intent record (scope, resource pointer, expiry, view limits) and not to a direct object URL And removing or altering the access-intent record shall immediately deny access to the content When the link is revoked by an authorized user Then any subsequent request shall return 410 Gone or 403 Forbidden within ≤30 seconds of revocation And audit logs shall record token creation, first access, and revocation events with timestamps
Auto-Expiry on Duration or First Open
Given a token configured for single-use When the first successful content retrieval occurs Then the token shall be invalidated immediately and any subsequent request shall return 410 Gone or 403 Forbidden Given a token configured for limited views N When each view is consumed Then the remaining view count shall decrement until zero, after which access is denied with 410/403 Given a token with time-bound expiry T When current server time ≥ T (with ±5 minutes clock skew tolerance) Then access shall be denied with 410/403 and an expiration message displayed without exposing PII
Optional Watermarking and Disclosure
Given watermarking is enabled for a tokenized media delivery When the media is rendered Then a persistent overlay shall display facility name, access timestamp, and a truncated token hash on all images and video frames And watermark opacity shall be between 20% and 35% and occupy at least 8% of the shorter media dimension And the overlay shall not be suppressible by client-side controls And an on-screen disclosure shall state that access is temporary and not to be shared
Access Verification & Anti-Forwarding
"As a Snapshot Aide, I want to add a quick verification check to a one-time link so that only the intended family member can view it even if the link is forwarded."
Description

Offer optional gates to reduce unauthorized forwarding: one-time SMS/email verification, sender-defined passcode, CAPTCHA, and device fingerprint binding on first open. Allow locking a link to a specific recipient contact when known, while maintaining a friction-light path for just-in-time shares. Failed or suspicious attempts trigger throttling and alerting without revealing whether content exists.

Acceptance Criteria
SMS/Email One-Time Code Verification on First Open
Given a one-time link with SMS or email verification enabled and a recipient contact on file When the recipient opens the link Then the system sends a 6-digit one-time code to the configured channel within 10 seconds and prompts for entry And the code expires after 10 minutes or upon successful use, whichever comes first And entering the correct code grants access to the link content exactly once And entering an incorrect code displays a generic "Unable to open link" message without indicating whether the content exists And code resend is limited to 3 resends per 10 minutes
Sender-Defined Passcode Gate
Given a one-time link with a sender-defined passcode When the recipient opens the link Then the system prompts for the passcode and does not display any content until validated And only passcodes 4–32 characters are accepted; validation is performed server-side against a salted hash And the correct passcode grants access; an incorrect passcode yields a generic error without revealing whether content exists And after 5 consecutive failed entries within 10 minutes, further attempts for that link and device are blocked for 15 minutes or until the sender resets the link And the passcode value never appears in URLs, logs, analytics, or client-visible error messages
Device Fingerprint Binding to First-Open Device
Given a one-time link with device binding enabled When the recipient successfully accesses the link the first time Then the system binds the link to that device/browser via a privacy-preserving device fingerprint stored in first-party storage And subsequent open attempts from a different device/browser or from a cleared-storage session are denied with the same generic failure message used for other denials And subsequent opens from the bound device within the link’s allowed window succeed without re-verification And a "Request access from sender" action is available that notifies the sender without revealing content or link existence to the requester
Recipient-Locked Link (Known Contact)
Given a one-time link locked to a specific recipient contact (phone number or email) When the link is opened by any requester Then verification is only possible via the locked contact channel; alternate contacts are refused And OTP or magic-link messages are delivered only to the locked contact and the requester cannot change the destination contact And forwarded links cannot be used to obtain codes or access by third parties And if the sender reassigns the locked contact, all prior verifications are invalidated and future verifications target the new contact only
Throttling, CAPTCHA, and Alerting on Suspicious Activity
Given repeated or anomalous access attempts against a one-time link When 5 failed verifications occur from the same IP/device or 10 across distinct IPs within 10 minutes Then further attempts are throttled with exponential backoff starting at 60 seconds and capping at 15 minutes And a CAPTCHA challenge is required on the next attempt and must be solved before verification is retried And an alert is recorded for admin review with timestamp, IP/device fingerprints, and link identifier; no PII is stored in clear text And all failures return identical generic messaging and HTTP status codes to avoid disclosing whether content exists
Friction-Light Access for Just-in-Time Shares
Given a one-time link with no gates enabled When the recipient opens the link Then the content loads in 2 taps or fewer and within 2 seconds at the p95 on supported devices, with no account creation or app install required Given a one-time link with any single gate enabled When the recipient opens the link Then the total steps to view content do not exceed 3 screens, with SMS/email codes auto-filled via deep link where supported And all verification screens meet WCAG 2.1 AA for touch targets, contrast, and screen reader labels
Revocation, Monitoring & Audit Trail
"As an Administrator, I want to monitor and revoke one-time links and see an audit trail so that I can respond quickly to mistakes or misuse and maintain compliance records."
Description

Provide real-time server-side enforcement that tracks opens, view counts, and TTL, returning clear expired states when limits are reached. Allow creators and admins to manually revoke links, view access history, and see delivery/open events. All actions write to an audit log with timestamp, actor, device hints, and outcome to support compliance reviews and incident response.

Acceptance Criteria
TTL Auto-Expiration Returns Clear Expired State
- Given a one-time link with ttl_seconds set, When server time >= created_at + ttl_seconds, Then GET/HEAD requests return HTTP 410 with code "link_expired" and a localized message, and no content bytes are returned. - Given an unexpired link, When requested, Then response includes Cache-Control: no-store and Expires: 0 to prevent caching. - Given a device with incorrect local clock, When it requests an expired link, Then server still returns expired state based on server time. - Given an expired link, When accessed via the URL in any channel, Then the same 410 and JSON body are returned across API and web views, and an "expired_ttl" audit event is recorded with timestamp, actor (if known), device hints, and outcome=blocked.
View-Count Limit Enforcement
- Given a link with max_views=1, When the first open completes, Then view_count increments to 1 and the content is delivered once. - Given the same link, When a subsequent open is attempted, Then the request is denied with HTTP 410 and code "link_consumed", and no content or metadata are leaked. - Given two near-simultaneous opens, When both are attempted within 500 ms, Then at most one succeeds and the other is denied, and the final view_count is 1. - Given known link preview user-agents, When they request the URL, Then the system serves a non-sensitive placeholder without incrementing view_count and records an "unfurl" event, not an "open".
Manual Revocation by Creator/Admin
- Given the link creator or an admin has revoke permission, When they click Revoke or call the revoke API, Then the link becomes invalid within 2 seconds globally. - Given the revoked link, When any subsequent request is made, Then the response is HTTP 410 with code "link_revoked" and no content, and a "revoked" audit event is captured with actor id and reason (if provided). - Given an in-progress session that tries to fetch additional assets after revocation, When it makes the next request, Then it is denied and logged as "blocked_after_revocation". - Given insufficient permissions, When a non-owner caregiver attempts revocation, Then the action fails with 403 and an "authorization_failed" audit event.
Access History Visibility
- Given a creator or admin, When they open the link details page, Then they can view a chronological event timeline including created, delivered, opened, expired, revoked, and denied events. - Given events exist, When listed, Then each entry shows ISO-8601 UTC timestamp, event type, actor (user id or "anonymous_link"), device hints (UA family and OS), and truncated IP (/24 IPv4 or /64 IPv6). - Given pagination controls, When more than 50 events exist, Then results are paginated with stable ordering and a next cursor. - Given no events yet, When viewing history, Then the UI states "No events yet" and audit access is recorded as "history_viewed".
Audit Log Completeness and Integrity
- Given any action on a link (create, deliver, open, expire, revoke, denied, history_viewed, export), When it occurs, Then an append-only audit entry is written with timestamp (UTC), actor id (or system), device hints, action, target link id, and outcome. - Given the audit log, When queried, Then entries are immutable and carry a hash chain or signature that validates integrity. - Given an admin, When they export the audit log for a link, Then they can download JSON and CSV within 10 seconds including all fields, and the export is logged as "audit_exported". - Given retention policy, When an entry ages beyond retention, Then it is archived per policy but integrity proofs remain verifiable.
Real-Time Delivery and Open Event Tracking
- Given a link sent via KinLoop, When the delivery provider confirms handoff, Then a "delivered" event is recorded and appears in the timeline within 5 seconds. - Given a recipient opens the link, When the first byte of protected content is served, Then an "open" event is recorded with device hints and increments the open counter within 1 second. - Given network outages, When provider webhooks are delayed, Then the system queues and reconciles events without duplication; timeline remains eventually consistent within 2 minutes. - Given data privacy, When events are displayed, Then no resident PII or content is exposed in event payloads or messages.
Recipient App-less View
"As a Family Member, I want to open a shared link on my phone without installing an app so that I can quickly see the update when it matters."
Description

Render a responsive, accessible web view that loads without the KinLoop app, optimized for low-friction first open and WCAG AA accessibility. The view displays media, captions, and consent-safe details, supports pinch-to-zoom, disables right-click saving where feasible, and provides clear messaging on expiry status. Localizes timestamps and messages to the recipient’s locale and timezone.

Acceptance Criteria
App-less Web View Loads Quickly and Reliably
Given a recipient opens a valid One-Time Link on a supported mobile browser (Chrome 124+, Safari iOS 16+, Edge 124+) When the page loads over a Fast 3G profile (≈400 ms RTT, 1.6 Mbps) Then First Contentful Paint ≤ 1.8 s and Time to Interactive ≤ 3.0 s Given the recipient device has JavaScript enabled When the page loads Then no app installation or sign-in is required to view the content Given an unsupported or very old browser (< iOS 13 or equivalent) When the link is opened Then show a graceful fallback message with minimal snapshot info and guidance to open on a supported device Given transient network loss during initial load When connection resumes within 30 seconds Then the view auto-retries and renders without manual refresh Given initial delivery of the view When the HTML, CSS, JS, and critical image placeholders are transferred Then total initial payload ≤ 350 KB gzipped
WCAG 2.2 AA Accessibility Compliance
Given keyboard-only navigation When tabbing through the view Then all interactive elements are reachable in logical order, have visible focus, and are operable without a mouse Given a screen reader (NVDA, JAWS, VoiceOver, TalkBack) When reading the page Then all controls expose correct names/roles/states, images have accessible names, and expiry status is announced Given browser zoom to 200% or large text settings When viewing the content on a 320 px wide viewport or larger Then no loss of information or functionality and no horizontal scrolling is introduced Given color contrast evaluation When tested Then text and interactive components meet contrast ≥ 4.5:1 for regular text and ≥ 3:1 for UI components Given media with audio When the page loads Then no media autoplays; playback requires an explicit user gesture
Media Display with Pinch-to-Zoom and Consent-Safe Details
Given a snapshot containing photos When the view renders on a touch device Then pinch-to-zoom is enabled on images and double-tap zoom controls are available on non-touch devices Given non-consenting faces detected in media When rendered Then those face regions are blurred to the configured threshold and cannot be unmasked via client interactions Given a snapshot with voice-to-text captions When rendered Then the caption text is displayed adjacent to the media and is exposed to assistive technologies Given consent-safe data constraints When rendering resident information Then only approved fields (e.g., resident first name, activity type) are shown; other residents are anonymized or omitted Given media assets contain EXIF metadata When served to the recipient Then GPS coordinates and device identifiers are stripped from responses
Download Deterrents Enabled Where Feasible
Given the recipient long-presses or right-clicks on media When the context menu would normally display save/download options Then the default context menu is suppressed on the media element Given the recipient attempts common save shortcuts or drag-and-drop of media When triggered Then the page prevents saving the media via these interactions without breaking core viewing accessibility Given media responses are delivered When the server sends headers Then responses include Cache-Control: no-store, Referrer-Policy: no-referrer, and Content-Security-Policy with frame-ancestors 'none' Given a direct media URL is requested without a valid token When accessed Then the server returns 403 and no media bytes are disclosed Given assistive technologies are in use When navigating and reading the page Then deterrents do not impede the accessibility tree or keyboard operability
Localized Timestamps and Messages
Given the recipient provides Accept-Language and a device locale When rendering UI strings and status messages Then the highest-preference supported locale is used with deterministic fallback to en-US Given the recipient’s IANA timezone is detected or provided When displaying “Sent” timestamps Then times are converted from UTC to the recipient timezone with correct DST handling and locale-appropriate formats (e.g., en-US: MMM d, h:mm a; de-DE: d. MMM, HH:mm) Given English (en-US) and Spanish (es-ES) configurations When tested Then all visible messages, expiry text, and buttons appear in the correct language Given locale-specific hour cycles When formatting times Then 12-hour or 24-hour format is used according to locale conventions Given no locale can be resolved from headers When rendering Then locale is inferred from browser settings or falls back to en-US consistently
Link Expiration and Status Messaging
Given a single-use link When the content is fully rendered for the first viewer Then the link is immediately invalidated and subsequent opens return an Expired view with HTTP 410 Given a duration-based link (e.g., 72 hours) When the recipient opens the link Then a banner displays remaining time and the link auto-expires at the configured cutoff regardless of open tabs Given an expired link When opened Then no media or personal data are returned; a clear, localized expiry message and non-identifying request-new-link option are shown Given link preview bots (e.g., iMessage, Facebook, Slack) When they fetch the URL Then previews do not reveal media and do not consume a single-use open Given client time differs from server time When enforcing expiry Then server time is authoritative for all expiration decisions
Limited-View and First-Open Enforcement
Given a link configured with N views When it is opened and content fully renders Then the remaining views counter decrements by 1 and is shown to the user (e.g., “2 of 3 views left”) Given the page is refreshed within 5 minutes on the same device session When detecting a duplicate view Then no additional view is consumed Given concurrent opens on multiple devices When race conditions occur Then only the first completed render consumes a view; others receive updated remaining or Expired messaging Given all views are consumed When the link is opened again Then the Expired view with HTTP 410 is shown and no media is exposed Given observability requirements When opens, view consumption, and expiry events occur Then non-PII analytics events are emitted for auditability
Admin Policies & Defaults
"As an Administrator, I want to set organization-wide defaults and limits for one-time links so that staff share consistently and within compliance boundaries."
Description

Expose org-level controls for maximum TTL, default expiry settings, allowed verification methods, watermarking, and permitted share channels (SMS, email, QR). Policies propagate to mobile and web clients, enforcing guardrails while allowing limited per-link overrides. Include analytics dashboards summarizing link creation volumes, open rates, expirations, and revocations.

Acceptance Criteria
Enforce Max TTL and Default Expiry
Given an org policy defines a maximum TTL and a default expiry When a caregiver creates a one-time link without specifying TTL Then the default expiry is prefilled in the UI and applied in the created link metadata Given a maximum TTL is configured When a caregiver attempts to set a TTL greater than the maximum Then the client prevents submission and the API rejects the request with HTTP 400 and error code TTL_EXCEEDS_POLICY Given per-link TTL overrides are allowed by policy When a caregiver sets a TTL within the allowed range Then the link is created successfully and the effective TTL is stored and retrievable via API Given per-link TTL overrides are disallowed by policy When a caregiver attempts to change the TTL Then the UI control is disabled/read-only and the API ignores any TTL value in the request
Allowed Verification Methods Enforcement
Given an org policy enables only specific verification methods (e.g., SMS OTP, Email OTP) When a caregiver creates a new link Then only the enabled verification methods are shown and selectable in the UI Given a create-link API request specifies a verification method not allowed by policy When the request is processed Then the API returns HTTP 400 with error code VERIFICATION_METHOD_NOT_ALLOWED and no link is created Given the policy requires at least one verification method When a recipient attempts to open a link without completing an allowed verification Then access is denied with HTTP 401 and the event is logged for analytics
Watermark Policy Application
Given watermarking is enforced by org policy When media (photo or transcript) is delivered via a one-time link Then the content is watermarked with org name, UTC timestamp, and link ID, is visibly present in the rendered media, and cannot be disabled by the client Given watermarking is optional and per-link overrides are permitted When a caregiver toggles watermark on/off during link creation Then the selection is applied to the link and reflected in the delivered media Given watermarking is disabled by policy or overrides are not permitted When a caregiver attempts to enable/disable watermarking Then the UI control is hidden or disabled and any submitted value is ignored by the API
Permitted Share Channels Enforcement
Given an org policy defines permitted share channels (SMS, Email, QR) When a caregiver opens the share options for a new link Then only the permitted channels are displayed and selectable Given a client attempts to send or register a link via a disallowed channel When the API receives the request Then it is rejected with HTTP 400 and error code CHANNEL_NOT_PERMITTED and no delivery occurs Given QR is not permitted by policy When the caregiver views sharing options Then no QR code is generated or presented
Policy Propagation and Real-Time Enforcement
Given an admin updates any policy value in the web console When the change is saved Then server-side enforcement applies immediately to all subsequent API requests Given mobile and web clients are online When a policy is changed Then clients fetch and apply the new policy within 5 minutes or on next app foreground, whichever comes first Given a client is offline with a cached, older policy When it performs an action now violating the updated policy Then the action is blocked on sync by the server and the client surfaces a policy violation message to the user Given policy versions are tracked When the policy changes Then clients record the effective policy version and timestamp for audit and support diagnostics
Per-Link Overrides Within Guardrails
Given the org policy specifies which fields allow per-link overrides (e.g., TTL, max views, watermark) When a caregiver adjusts an allowed field within configured bounds Then the link is created and the override is stored and returned by the API Given numeric bounds are defined for a field (e.g., min/max TTL, min/max views) When a caregiver inputs a value outside the bounds Then the UI shows inline validation and the API rejects the request with a specific error code (e.g., VALUE_OUT_OF_RANGE) Given overrides are disabled for a field When a caregiver attempts to change that field Then the control is read-only/hidden and any submitted override is ignored by the API
Admin Analytics Dashboard Accuracy and Filters
Given the admin selects a date range in Analytics When metrics load Then counts of links created, opened, expired, and revoked for that range are displayed and open rate equals opens/created rounded to one decimal place Given site/unit and caregiver filters are available When filters are applied Then metrics update within 2 seconds and reflect only matching records Given new link events occur When the dashboard is refreshed Then metrics include events ingested up to the last 15 minutes and display the latest data timestamp Given the admin exports CSV for a date range When the export completes Then the file includes fields: link_id, created_at, channel, verification_method, created_by, opens, expires_at, revoked_at, with PII masked per policy Given a known test dataset When dashboard totals are compared to API aggregations for the same filters Then counts match within 1 record or 1% (whichever is greater)

OTP Step-Up

Add an optional one-time SMS or email code on top of the PIN, delivered only to the approved contact on file. If a link is forwarded, the extra check ensures the right person is viewing—boosting security without adding complexity for trusted recipients.

Requirements

Configurable Step-Up Policy Rules
"As a facility administrator, I want to set clear rules for when OTP is required so that sensitive updates are protected without adding unnecessary friction for trusted families."
Description

Enable administrators to define when OTP step-up is required on top of the existing PIN, with policies configurable at organization, community, and resident levels. Triggers include first-time access from a device, access via a shared/digest link, access to sensitive content types (e.g., photos with residents, care notes), login from a new IP/geo, and manual override for high-risk cases. Provide an admin UI to toggle policies, set default behavior, and stage rollout to specific facilities or groups. The policy engine must integrate cleanly with KinLoop’s existing PIN gate and digest email/link flows so that step-up is invoked before any protected content or metadata is revealed. The system must degrade gracefully when policies are disabled and respect resident consent settings and compliance requirements.

Acceptance Criteria
Organization-Level Policy Configuration and Staged Rollout
Given I am an Org Admin with permissions to manage security policies When I open the Step-Up Policy settings in the Admin UI Then I can toggle the following triggers: First-time device, Shared/Digest link, Sensitive content types, New IP/Geo, Manual override And I can set the default organization behavior to one of: Disabled, Per-trigger, Always require OTP And I can scope the policy to: Entire organization, Selected communities, Selected resident groups And I can schedule a rollout start date/time and end date/time for selected scopes And saving persists settings, returns success, and writes an audit record including admin ID, changes, timestamp, and scope And changes propagate and are enforced within 60 seconds across targeted scopes And disabling the feature removes OTP prompts across the scoped entities without affecting PIN flow
First-Time Device Access Triggers OTP
Given step-up on first-time device is enabled for the user’s scope And the contact attempts access from a device without an existing trusted device record for this org When the contact enters the correct PIN Then the system prompts for a one-time code before any protected content or metadata is revealed And the OTP is delivered only to the approved contact’s verified channel (SMS or email) on file And the OTP expires after 10 minutes and becomes invalid after 5 failed attempts, after which a 15-minute lockout is applied And selecting “Trust this device” marks the device as trusted for 30 days for this contact and org, revocable from account settings And on success, access proceeds; on cancel/lockout, access is denied with no content leakage And the event is logged with device fingerprint, IP, timestamp, policy trigger, and outcome
Shared/Digest Link Access Triggers OTP
Given step-up on shared/digest link access is enabled for the recipient’s scope And a digest or shared link contains only an opaque token without PII When the link is opened Then the system requires an OTP before showing any titles, thumbnails, counts, or metadata And the OTP is sent only to the approved recipient contact on file, regardless of who opened the link And upon successful OTP, the token is bound to that contact and device; subsequent opens on that device within 24 hours bypass OTP unless another trigger applies And the link token expires after 7 days or immediately after manual revocation, whichever comes first And OTP send attempts are rate-limited to 5 per hour per contact per organization And on expiration or failure, a safe error is shown with no content leakage
Sensitive Content Access Triggers OTP by Content Type
Given step-up for sensitive content types is enabled and the sensitive types include photos with residents and care notes When a contact attempts to view an item flagged as sensitive Then the system requires OTP even on a trusted device before rendering the item And non-consenting faces remain blurred and consent-restricted items remain inaccessible regardless of OTP outcome And filenames, captions, timestamps, and resident identifiers are redacted until after successful OTP And audit logs capture contact ID, content type, resident IDs involved, trigger activated, and outcome
New IP/Geo Access Triggers OTP
Given step-up for new IP/geo is enabled with thresholds of country change or movement >100km from last trusted location And the contact accesses from a recognized device on a new IP/geo crossing thresholds When the contact passes the PIN gate Then the system requires OTP before any protected content or metadata is shown And requests originating from allowlisted corporate IP ranges bypass the new IP/geo trigger And if geo lookup is unavailable, the system falls back to IP change only; if both checks fail, OTP is required by default And on success, the new IP/geo is trusted for 24 hours for that device and contact And all events are rate-limited and logged with geo/IP details and policy trigger
Admin Manual Override Forces Step-Up
Given an admin applies a manual override to a contact and/or resident marking them high-risk When any access attempt involves that contact or content for that resident Then OTP is required regardless of device trust, link type, or other trigger states And the override takes effect within 60 seconds across all platforms and can be revoked by the admin at any time And applying or revoking an override creates an immutable audit log entry with admin ID, subject IDs, timestamp, and reason And bulk overrides via CSV upload or group selection apply atomically and report per-subject success/failure
Graceful Degradation and Compliance Safeguards
Given step-up policies are disabled at an applicable scope or the OTP delivery service is unavailable When a contact attempts to access protected content Then the system either enforces PIN-only access with no OTP prompts (when disabled) or blocks access with a non-revealing error per admin-configured fallback (when service unavailable), without leaking content or metadata And digest links continue to function according to the selected fallback without adding PII to URLs And resident consent settings are always enforced; step-up cannot override consent restrictions And Admin UI hides or disables step-up controls when the feature flag is off And all fallback decisions are logged for audit with cause and scope
Verified OTP Delivery Channels
"As an approved family contact, I want to receive a one-time code via my preferred channel so that I can quickly and securely access updates without hassle."
Description

Deliver one-time codes only to the approved contact on file via verified SMS or email, honoring the recipient’s preferred channel with automatic fallback to the alternate channel if delivery fails. Implement secure message templates, localization, and rate limiting for sends and resends, with visible countdown for “Resend code.” Integrate with existing messaging providers (e.g., SMS and email) and support provider failover. Store delivery status via webhooks while masking PII and never persisting the full OTP in logs. Provide safeguards for stale or unverified contact info (prompt to update through approved admin workflows) and maintain audit-safe records of where codes were sent without exposing contact details.

Acceptance Criteria
Preferred Channel Delivery to Approved Contact
Given a user has approved, verified contact information on file (SMS and/or email) and a preferred channel is configured And the user initiates OTP step-up from a valid session When an OTP is requested Then the system sends exactly one OTP to the preferred channel’s destination on file and to no other destination And the destination cannot be edited or overridden by the user at send time And the provider API acknowledges the send (2xx) within 5 seconds And the message uses the approved template for the user’s locale And an audit record is written capturing channel, masked destination, timestamp, provider, and message ID And no logs or analytics persist the OTP value or unmasked contact details
Automatic Fallback to Alternate Verified Channel
Given the preferred channel send fails due to hard bounce, undeliverable, or two consecutive timeouts within 30 seconds And an alternate channel on file is verified When fallback is enabled and an OTP is still required Then the system sends a new OTP via the alternate verified channel within 10 seconds of failure determination And the previously issued OTP is immediately invalidated And the audit record links both attempts and marks fallback=true And only one active OTP exists at any time And if no alternate verified channel exists, no message is sent and a generic error is returned while recording the failure in audit logs without PII
In-Channel Provider Failover Policy
Given provider A is the primary for SMS (or email) and provider B is configured as secondary And a send attempt via provider A returns a 5xx, throttling error, or times out after 3 seconds When the retry policy is applied Then the system retries once on provider A and, if it fails again, fails over to provider B within 5 seconds And no duplicate messages are delivered for a single OTP request across providers And provider selection, attempts, and outcomes are captured in audit records with masked data only And if both providers fail, the request surfaces a generic error and does not trigger cross-channel fallback unless fallback rules apply
Resend Rate Limiting and Visible Countdown
Given a user requests OTP resends within a session When the user taps Resend Then a visible countdown of 30 seconds is displayed and the Resend control is disabled until the countdown reaches zero And resends are limited to 5 sends per 15-minute window per session and 10 sends per day per contact method And exceeding limits returns HTTP 429 with a non-revealing error message and no message is sent And each resend generates a new OTP and invalidates the prior OTP immediately And rate-limit events are recorded in audit logs without PII or OTP values
Localized, Secure Message Templates
Given the user’s locale is known When an OTP is sent via SMS or email Then the message is rendered using an approved, versioned template corresponding to that locale And if the locale is unsupported, the content falls back to the en-US template And all template variables are escaped/sanitized to prevent injection And the template excludes PHI and does not reveal the full destination address And the sender identity (from name/number) matches a configured, verified identity
Safeguards for Stale or Unverified Contact Info
Given the destination contact is missing, unverified, or marked stale (not reverified in the last 12 months) When an OTP is requested Then no message is sent And the user is blocked from step-up with guidance to update contact info via approved admin workflows And an audit event is recorded with reason=contact_unverified_or_stale and without exposing contact details And the API response is generic and does not confirm whether a specific contact exists
Webhook Delivery Status and Audit-Safe Storage
Given messaging providers post delivery status webhooks When a webhook is received Then the request signature (e.g., HMAC) is validated and invalid/unsigned requests are rejected with 401 And status updates are stored idempotently by provider message ID with normalized status codes and timestamps And stored records mask contact addresses and never include the OTP value And transient processing failures are retried with exponential backoff up to 5 attempts And audit records are queryable by correlation ID without exposing PII
OTP Token Lifecycle and Security Controls
"As a security-conscious product owner, I want strict OTP lifecycle controls so that attempted misuse or forwarding cannot compromise resident privacy."
Description

Generate cryptographically strong OTPs (e.g., 6-digit numeric) with a short time-to-live (e.g., 10 minutes), single use, and replay protection. Bind each OTP to the recipient, device session, and requested resource when applicable, invalidating upon successful verification or expiry. Enforce attempt limits with exponential backoff and temporary lockouts after repeated failures. Store only hashed OTPs server-side and include clock-skew tolerance. Provide secure error messaging that does not disclose account existence or contact details. Ensure codes are compatible with both SMS auto-fill and email clients while preventing exposure in logs, notifications, or link previews.

Acceptance Criteria
OTP Generation, Format, and Server Storage
Given a step-up verification is initiated for an approved contact When the server generates an OTP Then the OTP is a 6-digit numeric code uniformly generated by a CSPRNG And the OTP value is never persisted in plaintext; only a salted hash is stored server-side using SHA-256 or stronger And the OTP value is never written to application, access, or analytics logs And the OTP issuance record includes a unique identifier not derived from the OTP value
Time-to-Live, Expiry, and Clock-Skew Tolerance
Given an OTP was issued When a verification request is received within 10 minutes of issuance (with ±60 seconds server-side clock-skew tolerance at the boundary) Then the OTP is accepted as within the valid window When a verification request is received after the valid window Then the OTP is rejected with a generic error and the record is marked expired And once expired, the OTP cannot be verified under any circumstance
Single-Use, Replay Protection, and Binding
Given an OTP is issued for recipient R, device session S, and resource X When a verification attempt is made by R from S for X with the correct OTP within the valid window Then verification succeeds and the OTP is invalidated immediately When any subsequent attempt uses the same OTP (regardless of recipient, session, or resource) Then verification fails with the same generic error and is recorded as a replay When an attempt is made from a different recipient, a different session, or for a different resource than bound Then verification fails with the same generic error
Attempt Limits, Exponential Backoff, and Temporary Lockouts
Given an OTP is active for a recipient/session When consecutive failed verification attempts occur Then exponential backoff is enforced before the next attempt: 0s, 2s, 4s, 8s, 16s, capped at 60s And after 5 consecutive failed attempts for the same OTP/session, that OTP is invalidated and a 5-minute session-level OTP lockout is applied And after 10 failed attempts across any OTPs for the same recipient within 15 minutes, a 15-minute recipient-level OTP verification lockout is applied And error responses during backoff or lockout remain generic and do not reveal which limit was triggered
Secure Error Messaging and Non-Disclosure
Given any failure case (invalid code, expired code, wrong recipient, wrong session, wrong resource, or non-existent account/contact) When the server responds to an OTP request or verification Then the response message and HTTP status code do not indicate account existence or contact details And failure responses use a single generic error (e.g., "The code is invalid or has expired") across the above cases And responses never include or confirm the delivery channel (SMS/email) or any masked contact information
Delivery Compatibility and Non-Exposure in Messages and Previews
Given an OTP must be delivered via SMS or email When the SMS is sent Then the message contains exactly one 6-digit code within the first 120 characters in a format compatible with mobile OS auto-fill (e.g., "Your KinLoop code is 123456") And the SMS contains no URLs and no additional 6-digit sequences When the email is sent Then the code appears in the first line of the email body and not in the subject line And the email does not include the code inside any URL or query parameter And KinLoop systems do not include the OTP in any server-generated metadata (e.g., Open Graph/oEmbed) that could appear in link previews And no system-generated notification includes the OTP value
Audit Logging and Telemetry Without Sensitive Data
Given OTP issuance and verification events are audited When logs, metrics, and traces are emitted Then plaintext OTP values are never recorded in any log, metric, trace, or error message And contact identifiers are masked (e.g., phone/email partially redacted) and never fully logged And logs contain only non-reversible identifiers (e.g., OTP record ID) and outcomes (issued, verified, expired, failed) with timestamps And automated scans of log storage show zero matches for 6-digit OTP patterns in message fields
Trust This Device Opt-in
"As a recurring family viewer, I want to trust my personal device so that I don’t have to enter a code every time while staying secure."
Description

After a successful OTP verification, allow recipients to opt in to “Trust this device” to reduce future prompts. Issue a signed, expiring device token (e.g., httpOnly cookie or secure storage) bound to the account, browser/app instance, and risk signals. Respect policy-configured trust duration (e.g., 30 days) and re-prompt on elevated risk (IP/geo change, device fingerprint change, policy update). Provide a simple UI to manage and revoke trusted devices from the recipient profile or via admin support. Enforce a maximum number of trusted devices per account and automatically expire trust on inactivity or when contact details change.

Acceptance Criteria
Post-OTP Trust Opt-in and Token Issuance
Given the recipient has completed OTP verification in the current session and is on a supported client When they select "Trust this device" and confirm Then the system issues a signed, expiring device token bound to the recipient account, current browser/app instance, and captured risk signals, stored as an HttpOnly Secure cookie (web) or in secure OS keystore (app) And the server records a trust entry with device identifier, createdAt, and lastSeenAt And subsequent access from this device within validity bypasses OTP unless risk policy dictates re-prompt And the opt-in control is hidden unless OTP was just passed and storage is available
Risk-Based Re-Prompt on Trusted Device
Given a valid trusted token is presented When elevated risk is detected (e.g., IP or ASN change, suspicious geo-velocity, device fingerprint change beyond threshold, or trust policy version update) Then the recipient must complete OTP before accessing protected content And on successful OTP, a new trusted token is issued and the prior token is invalidated when risk involves fingerprint mismatch or policy version update And risk evaluation occurs before granting access to any protected content
Policy-Driven Trust Duration and Inactivity Expiry
Given trust duration and inactivity limits are configured by policy When the absolute trust duration elapses or the inactivity threshold is exceeded Then the trusted token is rejected and OTP is required on next access And lastSeenAt is updated on each successful session that uses a valid trusted token And changes to policy values take effect for subsequent trust evaluations without requiring client updates
Recipient Trusted Devices Management UI
Given an authenticated recipient opens Profile > Trusted devices When the list loads Then it shows each trusted device with device label, created date, and last seen And the recipient can revoke any single device or revoke all devices; on confirmation the server invalidates the selected trust entries and deletes any local token on the current device And revoking the current device ends the session and requires OTP on next access
Maximum Trusted Devices Enforcement
Given a maximum number of trusted devices per account is configured When a new device attempts to opt in and the account is at the limit Then the recipient is prompted to remove one or more existing trusted devices before proceeding, and issuance is blocked until the count is within the limit And tenant-level admins can change the limit, and the new limit is enforced for subsequent trust issuances
Auto-Revocation on Contact Detail Changes
Given a recipient’s OTP delivery contact (phone or email) is changed on their account When the change is committed Then all existing trusted device tokens for that account are invalidated server-side, and subsequent access from any device requires OTP And the system surfaces a message on next sign-in explaining that trusted devices were reset due to contact changes
Admin Support Revokes Trusted Devices
Given an authorized admin opens a recipient’s profile in the admin console When they view the Trusted devices section Then they can see current trusted devices and revoke any or all And revocations are audited with admin ID, timestamp, and device identifiers And the recipient’s next access from revoked devices requires OTP
Context-Bound Secure Links
"As an administrator, I want shared links to be valid only for the intended recipient and content so that forwarding doesn’t leak private resident information."
Description

Issue digest and update links that are context-bound to the intended recipient and content, preventing unauthorized access if a link is forwarded. Embed a short-lived, non-guessable token that references the content and recipient; require OTP when the link is opened from an untrusted device or mismatched session. Do not expose resident names, photos, or sensitive metadata in the pre-verification screen or in link previews (suppress Open Graph previews). Provide clear messaging and a request-access path if a forwarded link is opened by the wrong person. Ensure compatibility with existing KinLoop email digests and in-app notifications without changing caregiver workflows.

Acceptance Criteria
Context-Bound Token Generation
Given a digest or update link is generated for intended recipient R and content C When the system creates the URL Then the URL contains a non-guessable token T with at least 128 bits of entropy And T is cryptographically bound to R and C and is invalid for any other recipient or content And T has a server-enforced expiry of ≤24 hours for single-update links and ≤14 days for digest links And after expiry, opening the URL returns a non-identifying 401/403 response with no content bytes of C And ≥5 invalid/expired token submissions from the same IP or device in 10 minutes are rate-limited for 15 minutes
Forwarded Link Opened by Wrong Recipient
Given a secure link L is bound to recipient R1 and content C When L is opened by a user signed in as R2 or on a device not previously trusted for R1 Then no content from C is returned prior to verification And the screen displays generic messaging only (no resident names, photos, or sensitive metadata) And the user is offered a clear Request Access action that, when submitted, notifies admins and is logged And if R1 opens L on a trusted device within the token validity window, access is granted without re-verification
OTP Step-Up on Untrusted Device or Mismatched Session
Given recipient R opens a valid link L on an untrusted device or with a mismatched session When R requests verification Then a one-time code is delivered only to R’s approved SMS number or email on file within 30 seconds And the code is single-use, 6 digits, and valid for 10 minutes And after successful entry, access is granted and the device is marked trusted for R for 30 days via a secure, httpOnly, sameSite=strict cookie And after 5 failed code attempts or 3 delivery retries, the flow is locked for 15 minutes with a generic error message
Pre-Verification Privacy and Link Preview Suppression
Given any pre-verification or error state for a secure link When the URL is fetched by a preview bot/crawler (e.g., iMessage, WhatsApp, Facebook, Gmail, Outlook) or via HEAD/unauthenticated GET Then Open Graph/Twitter Card tags are omitted or set to generic placeholders with no resident names, photos, or sensitive metadata And the page renders only non-sensitive branding text such as “Secure family update from KinLoop” And HTTP headers include X-Robots-Tag: noindex,noimageindex,noarchive and Cache-Control: no-store And verified shares in the named clients display only generic previews with no image thumbnails
Seamless Compatibility with Existing Digests and Notifications
Given caregivers publish updates via existing KinLoop workflows When email digests and in-app notifications are generated Then all links are issued as context-bound secure links without requiring caregiver UI changes or extra steps And email rendering and deliverability metrics (SPF/DKIM/DMARC pass rates and bounce rate) remain within ±2% of baseline over a 7-day rollout And in-app notification taps on authenticated and trusted devices open content without OTP prompts And metrics show no increase >2% in caregiver time-to-publish compared to baseline
Token Revocation on Access Changes
Given a token T exists for recipient R and content C When R’s access is revoked, R’s contact is changed, or C is deleted Then T and any other active tokens for (R, C) are invalidated within 60 seconds And subsequent opens return a non-identifying 401/403 with the Request Access option And issuing a new link for R and C generates a new token that does not resurrect invalidated tokens
Step-Up Audit Logging and Admin Insights
"As a facility administrator, I want visibility into OTP usage and issues so that I can monitor security and support families effectively."
Description

Record privacy-preserving audit events for OTP activities, including sends, channel used, delivery outcomes, verification successes/failures, lockouts, device trust adds/removals, and policy trigger reasons. Expose an admin dashboard with filters by facility, resident, date range, and channel, plus export to CSV and API access for compliance reporting. Surface alerts for anomalous patterns (e.g., repeated failures, high resend rates) and provide actionable guidance to support staff to resolve recipient issues. Ensure all logs redact PII and OTP values and are retained according to compliance and organizational retention policies.

Acceptance Criteria
Comprehensive OTP Event Logging with Redaction
Given an OTP step-up flow is initiated for an approved contact When any of the following occurs: code_send_initiated, code_send_succeeded, code_send_failed, delivery_confirmed, delivery_bounced, verification_succeeded, verification_failed, resend_requested, lockout_triggered, policy_evaluated Then an audit record is written within 1 second containing: timestamp_utc (ISO 8601), tenant_id, facility_id, resident_id, contact_id_hash, channel (sms|email), event_type, outcome, reason_codes[], delivery_status, resend_count, lockout_counter, device_fingerprint_hash (optional), policy_trigger, correlation_id And no PII (full phone, full email, OTP value, message body) is stored; phone masked as +*******{last4}, email masked as f*****@d*****.{tld}; OTP value is never persisted And records are immutable and tamper-evident (checksum saved and verified on read); write failures are retried up to 3 times with exponential backoff without delaying the user flow
Admin Dashboard Filtering and Performance
Given an admin opens the Step-Up Insights dashboard When filters are applied by facility, resident, date range (UTC), and channel (sms|email) Then the visible event list and aggregated metrics reflect only matching events, with counts equal to backend query results And results load within 2 seconds p95 for up to 100k events and support pagination (50/100/500 per page) And timestamps display in the admin’s local timezone with explicit TZ label; backend queries remain UTC And no PII is displayed; masked values only; OTP values are never visible
CSV Export and Audit API for Compliance Reporting
Given an admin requests a CSV export with current filters When the export job completes Then the CSV contains only filtered events with columns: timestamp_utc, tenant_id, facility_id, resident_id, contact_id_hash, channel, event_type, outcome, reason_codes, delivery_status, resend_count, lockout_counter, device_trust_action, policy_trigger, correlation_id And PII remains masked and OTP values are excluded; file is UTF-8 with header row and comma delimiter And exports up to 1,000,000 rows are delivered via an expiring (24h) signed URL; larger exports are split into sequential parts with deterministic filenames And the REST API endpoint /v1/otp-audit supports the same filters, cursor pagination, OAuth scope admin.audit.read, and enforces tenant isolation; responds within 2 seconds p95 for pages up to 10k rows
Anomalous Pattern Alerts and Triage Guidance
Given the system continuously evaluates OTP audit events When any anomaly condition is met (e.g., ≥5 verification failures for the same contact within 10 minutes; resend rate >40% in the last hour for a facility with ≥50 attempts; delivery failure rate >10% over 15 minutes) Then an alert is generated within 2 minutes and appears in the dashboard and is optionally emailed to configured recipients And the alert includes scope (facility/resident/contact hash), metrics, suspected causes, and actionable steps (e.g., verify/update contact info, switch channel, temporarily disable step-up, contact support) with one-click links And alerts are deduplicated for 30 minutes, support acknowledge/resolve states, and all alert lifecycle changes are audit-logged
Device Trust Add/Remove Auditability
Given a user adds or removes a trusted device during or after OTP verification When the trust action occurs Then an audit event is recorded with: timestamp_utc, tenant_id, facility_id, resident_id, contact_id_hash, device_fingerprint_hash, os/browser family, ip_hash, device_trust_action (add|remove), initiator (self|admin), outcome (accepted|rejected), correlation_id And the dashboard supports filtering by device_trust_action and shows counts and trends over the selected date range And trust changes require successful step-up verification; otherwise the event outcome is rejected and no trust state change is applied
Retention Policy and Legal Hold Enforcement
Given tenant-specific retention policies are configured (default 13 months, jurisdictional overrides allowed) When an audit record reaches its retention limit and is not on legal hold Then it is purged or archived per policy by a daily job, and a retention-deletion summary event is logged with counts and policy_id; no recoverable PII remains And authorized roles/scopes (admin.audit.read) can view/export audit data; unauthorized access attempts are blocked and audit-logged And when a legal hold is applied to a facility/resident scope, deletions are paused within 1 hour; when the hold is removed, backlog purges complete within 24 hours and are audit-logged

Watermark Shield

Overlay each link view with a subtle, personalized watermark (contact name and timestamp) to discourage screenshots and unauthorized forwarding. Any captured image still traces back to the viewer, protecting resident dignity and supporting compliance.

Requirements

Token-Bound Watermark Identity
"As an approved family contact viewing a secure update, I want the watermark to display my name and when I viewed it so that I understand the content is traceable to me and I’m discouraged from sharing it."
Description

Display a personalized watermark on every secure link view derived from the viewer’s unique access token, showing the viewer’s display name and the precise view timestamp. The watermark text is generated at render time and never baked into the source media, ensuring content files remain unchanged. The system must map link tokens to an approved contact, fall back gracefully if the token lacks a resolved identity (e.g., show token suffix), and log each render event with UTC timestamp and timezone offset used in the overlay. This integrates with KinLoop’s existing link delivery and permission model, reinforcing accountability while maintaining privacy and compliance expectations.

Acceptance Criteria
Overlay Shows Viewer Name and Timestamp
Given a valid secure link token mapped to an approved contact When the viewer opens the link in a supported browser Then a watermark overlay is rendered at view-time on top of the media container And the overlay text includes the contact’s display name exactly as stored and the precise render timestamp And the timestamp displayed follows ISO 8601 local time with numeric offset (e.g., 2025-08-28T14:05:22-04:00) And the overlay text is generated on the client at render time and not pre-composited into media assets
Fallback Identity When Contact Not Resolved
Given a valid token that does not resolve to a contact display name When the link is opened Then the overlay displays a fallback identity in the format "Token-<last6(token_id)>" And no other personally identifying information is shown in the overlay And the same fallback value is used consistently across the session and recorded in logs
Overlay Not Baked Into Source Media
Given any secure link rendering a media asset When the original media file is retrieved directly from the media API or storage for download Then the file’s SHA-256 hash matches the stored master copy And the binary contains no watermark pixels or text when inspected And disabling client-side rendering (e.g., via print stylesheet or dev tools) removes the overlay without altering the media file
Render Event Logging With UTC And Offset
Given a watermark overlay is rendered for a token-bound view When the page completes initial render Then a render log entry is written containing: link_id, hashed token_id, contact_id (if resolved), identity_mode (name|token_suffix), overlay_local_timestamp, overlay_timezone_offset, overlay_utc_timestamp (ISO 8601 Z), and request_id And the log entry is persisted within 1 second of render and is queryable by link_id and hashed token_id
Token Mapping And Permission Enforcement
Given a secure link token without active permission to the requested content When the link is opened Then the content is not displayed and no overlay is rendered And an access denied response is shown and no render log entry is created Given a secure link token with active permission mapped to a contact When the link is opened Then the overlay uses the mapped contact’s display name and the view proceeds
Unique Timestamp Per View And Timezone Handling
Given the same secure link is viewed multiple times or from different devices/sessions When each view is rendered Then the overlay timestamp reflects the precise render time of that specific view (to the second or better) And each render creates a distinct log entry with its own overlay_utc_timestamp and overlay_timezone_offset Given the browser reports a local timezone offset different from the server default When the overlay is rendered Then the displayed timestamp uses the browser-reported local time and the log records both the local offset used and the UTC time
Adaptive Watermark Rendering Engine
"As a viewer on any device, I want the watermark to be readable yet unobtrusive so that I can comfortably view updates while still being reminded not to capture or forward them."
Description

Render a subtle but persistent diagonal, repeated text watermark across the visible media/container that adapts to underlying content for legibility without obstructing faces or key details. The engine must support images and videos by using an overlay layer (CSS/SVG/canvas for images, player overlay for video) with dynamic contrast, stroke, and opacity adjustments based on local luminance. It should scale responsively across devices and orientations, maintain performance under low-end hardware constraints typical in care settings, and avoid altering original files. The pattern density and placement must ensure any reasonable crop or screenshot still includes identifiable text.

Acceptance Criteria
Dynamic Contrast and Legibility Adaptation
Given media with dark, mid-tone, and bright regions When the watermark overlay renders Then each watermark token achieves a local contrast ratio ≥ 3:1 against its immediate background via dynamic fill, stroke, and opacity adjustments And watermark opacity stays within 0.08–0.18 inclusive And stroke width auto-adjusts between 0.5–1.5 px (device-pixel aware) to maintain edge legibility And no token is rendered if the algorithm cannot meet the contrast threshold in its local patch (token is repositioned instead)
Face and Key Detail Avoidance
Given detected face bounding boxes and an optional caller-provided exclusion mask for key details When laying out the diagonal, repeated watermark tokens Then no glyph stroke intersects any exclusion area, maintaining a clearance of at least max(8 px, 1% of the shorter viewport side) And if avoidance would create a gap > 2× the baseline spacing, neighboring tokens are shifted (not removed) to preserve pattern continuity And avoidance logic preserves the minimum coverage rules defined for crop/screenshot resilience
Responsive Scaling Across Devices and Orientation
Given device viewports from 320×568 to 1440×1024 at DPR 1–3 When the viewer loads or the device orientation/size changes Then watermark text height scales to 2–3% of the shorter viewport side (clamped to 10–18 px at 1×), maintaining readability without obstruction And the diagonal angle is kept between 30°–45° relative to the horizontal And inter-line spacing is 0.8–1.2× the token height And the layout recalculates within 200 ms of a resize/orientation event
Video Overlay Performance and Sync
Given 1080p H.264 video at 30 fps on a low-end device profile common in care settings When the video plays with the watermark overlay enabled Then average dropped frames attributable to the overlay are < 2% over a 60 s playback window And median render time added by the overlay is ≤ 8 ms per frame (UI thread not blocked > 16 ms) And additional memory used by the overlay layer remains ≤ 20 MB And audio/video sync drift remains ≤ 20 ms compared to baseline playback without overlay
Non-Destructive Rendering of Originals
Given original image and video files stored by the system When they are displayed with the watermark overlay Then the underlying files are never modified on disk or in object storage And cryptographic checksums (e.g., SHA-256) of originals before and after display remain identical And any download/export workflow that delivers originals (where permitted) produces files byte-identical to the stored originals
Personalized Token Content per Viewer Session
Given an authenticated viewer session for a shared link When the watermark renders on media Then each token contains the viewer’s display name and the UTC timestamp of access in the format `YYYY-MM-DD HH:mm:ssZ` And the same personalized token is consistently shown across all frames in that session And a different viewer or a new session renders tokens with their respective identity and session timestamp
Crop and Screenshot Resilience Coverage
Given the watermark tiled diagonally across the viewport When any rectangular crop of ≥ 20% of the viewport area with aspect ratio between 0.5 and 2.0 is taken Then at least one full watermark token is visible and meets the legibility threshold (contrast ≥ 3:1) in ≥ 99% of 1000 random crop samples And the maximum gap between adjacent token baselines is ≤ 12% of the shorter viewport dimension And token repetition continues seamlessly beyond the viewport bounds to cover panning and OS-level screenshot UI overlays
Share and Download Friction Controls
"As an administrator, I want basic save/share deterrents enabled on secure links so that casual misuse is reduced even if determined screenshots remain possible."
Description

Add client-side deterrents alongside the watermark to reduce casual misuse: hide native download controls, disable right-click save, block drag-and-drop of media, prevent easy long-press saves where possible, set no-store cache headers for link views, and apply referrer and content security policies to minimize unintentional leakage. While acknowledging screenshots cannot be fully prevented, these measures increase friction and reinforce the Watermark Shield’s purpose without degrading legitimate viewing.

Acceptance Criteria
Hide Native Download Controls in Link Views
Given a KinLoop link view displaying images or videos in desktop and mobile browsers, When the user taps or clicks the media UI, Then no native Download control is visible on the media player. Given a video element in the link view, When the controls are opened, Then no menu item to download the video is present. Given media responses, When response headers are inspected, Then Content-Disposition is inline and no download filename is provided.
Disable Right-Click Save on Media
Given the link view is open on a desktop browser, When the user right-clicks directly on any image or video, Then the browser does not present Save image as or Save video as for that element. Given the user invokes the context menu via keyboard on focused media, When Shift+F10 or the Menu key is pressed, Then no direct save option for that media is available. Given the user presses Ctrl/Cmd+S on the page, When the save dialog appears, Then only a page snapshot is offered and not the original media asset.
Block Drag-and-Drop of Media
Given the link view is open, When the user attempts to drag an image or video to the desktop or another tab, Then the drop does not result in a saved media file or direct media navigation. Given a dragstart event on media, When dataTransfer is inspected, Then it contains no direct media URL or file payload. Given the user drags media into a new tab, When the drop occurs, Then the new tab does not navigate to a direct media URL of the asset.
Prevent Long-Press Save on Mobile
Given the link view is opened on iOS Safari or Android Chrome, When the user long-presses any image or video, Then no native Save Image, Save Video, or Download option is shown. Given touch-and-hold on media, When default behaviors would show a media action sheet, Then the default is suppressed without preventing play or pause actions. Given mobile assistive touch features are enabled, When the user interacts with media, Then playback and basic controls remain available without exposing a save option.
Enforce No-Store Cache on Link Views
Given the HTML for a link view is requested, When response headers are inspected, Then Cache-Control includes no-store and no-cache, Pragma is no-cache, and Expires is 0. Given JSON/API responses used by the link view are requested, When headers are inspected, Then they include Cache-Control: no-store. Given the user views the link, Then after closing the tab and enabling Airplane Mode, When the link is reloaded, Then the page does not render from cache and shows an offline state.
Apply Referrer and Content Security Policies
Given navigation from the link view to any external domain occurs, When request headers are inspected, Then the Referer header is absent per Referrer-Policy: no-referrer. Given the link view loads resources, When CSP is evaluated, Then only approved origins are allowed for script, image, media, and connect, and frame-ancestors denies embedding by other sites. Given the link view is embedded in an external iframe, When it loads, Then it is blocked from rendering due to CSP frame-ancestors (and/or X-Frame-Options) restrictions.
Admin Policy Controls and Presets
"As a compliance admin, I want to configure and lock watermark settings across my facilities so that our organization maintains a consistent, compliant deterrent policy."
Description

Provide tenant- and facility-level settings to configure Watermark Shield behavior, including on/off toggle, text components (contact name, facility name, timestamp format), pattern density, angle, and opacity presets. Include a real-time preview in the admin console and capture an audit trail of configuration changes. Default to a recommended compliant preset and allow policy locks to enforce settings across all communities within a group.

Acceptance Criteria
Tenant Toggle and Compliant Default Preset
Given a Tenant Admin opens Admin Console > Settings > Watermark Shield When the feature toggle is set to On and Save is clicked Then subsequent link views across the tenant display a watermark using the Compliant Default preset And the preview panel renders the same watermark prior to saving When the feature toggle is set to Off and Save is clicked Then subsequent link views across the tenant display no watermark
Facility Overrides Respect Tenant Policy Lock
Given the Tenant Admin has Watermark Shield set to On and Policy Lock set to Off When a Facility Admin changes text components, pattern density, angle, or opacity and clicks Save Then the facility preview updates immediately and subsequent link views in that facility reflect the changes within 60 seconds And reopening the settings page shows the saved values When the Tenant Admin sets Policy Lock to On and clicks Save Then all facility-level controls become read-only with a visible lock indicator And subsequent link views in all facilities reflect the tenant settings within 60 seconds When Policy Lock is switched Off and saved Then facility-level controls become editable again
Personalized Text Components and Timestamp Format
Given Watermark Shield is On and the admin enables contact name and facility name and selects timestamp format = YYYY-MM-DD HH:mm When the admin views the preview Then the preview watermark includes a sample viewer name, the facility name, and a timestamp formatted as YYYY-MM-DD HH:mm When a real viewer with display name Ava Chen opens a link in that facility Then the watermark contains the exact viewer display name Ava Chen, the facility name, and a timestamp in the selected format When the admin disables facility name and clicks Save Then subsequent link views do not include the facility name in the watermark
Pattern Controls and Presets with Validation
Given density, angle, and opacity controls display their allowed ranges When the admin attempts to enter values outside the allowed ranges Then the UI prevents saving and shows inline validation messages When the admin adjusts any control within the allowed range Then the preview updates within 300 milliseconds of input When the admin saves the current settings as a custom preset named Night Shift Then Night Shift appears in the preset list and selecting it reapplies the saved values And the system preset Compliant Default is always present and cannot be renamed or deleted
Audit Trail Captures Configuration Changes
Given an Admin changes any Watermark Shield setting and clicks Save Then an audit entry is recorded with timestamp (UTC), actor (user id and role), scope (tenant or facility), changed fields with before and after values, and the preset name if applied And the entry is immutable and visible in the audit log within 60 seconds of save When filtering the audit log by date range, actor, scope, and action type Then the results reflect the selected filters When exporting the audit log Then a CSV downloads containing only the filtered entries with all captured fields And only Admin roles can view or export the audit log
Group-Level Policy Lock Propagation
Given a Group Admin enables a group-level policy lock with a selected preset and saves Then all existing communities in the group inherit these settings and their local controls are read-only And changes propagate to all communities within 5 minutes When a new community is created under the group Then it inherits the group-locked settings by default When the Group Admin removes the policy lock and saves Then community-level controls become editable and retain the last enforced settings until changed locally
Real-Time Preview Fidelity
Given the admin changes any Watermark Shield setting in the configurator Then the preview updates within 300 milliseconds without affecting other console controls When the admin saves and opens a live link view Then the watermark on the live view matches the preview in text content, pattern density, angle, and opacity within a 1-pixel visual diff tolerance
Accessibility and Performance Guarantees
"As a caregiver sharing updates, I want the watermark to work smoothly on all families’ devices so that no one struggles to view important moments or information."
Description

Ensure the watermark does not impede accessibility or degrade performance. Meet WCAG 2.1 AA for contrast and readability of surrounding UI, preserve screen-reader semantics, and avoid obscuring critical UI controls. Maintain smooth playback at target frame rates for video overlays and keep image render times within acceptable thresholds on low-end devices. Provide graceful degradation paths (e.g., simplified overlay) when resources are constrained, and include monitoring hooks for overlay render time and errors.

Acceptance Criteria
Watermark respects WCAG 2.1 AA and control visibility
Given the personalized watermark is enabled on any screen with interactive controls When the screen is rendered on iOS and Android Then no tappable control is overlapped by any watermark glyph or tile And a minimum 8dp clearance exists between watermark elements and control hit areas And all tap targets remain ≥ 44x44 dp and fully hit-testable And all visible text and icons retain WCAG 2.1 AA contrast (normal text ≥ 4.5:1, large text/icons ≥ 3:1) with the watermark present And automated accessibility scan reports 0 critical or serious findings related to contrast or obscured controls
Screen reader semantics preserved with decorative watermark
Given VoiceOver (iOS) or TalkBack (Android) is enabled When viewing any screen or media with the watermark overlay Then the watermark is not focusable or announced (aria-hidden / not important for accessibility) And the swipe/focus order of interactive elements matches the same screen with the overlay disabled And control labels, roles, and hints are unchanged And heading/landmark navigation counts are unchanged And no additional accessibility nodes are introduced by the watermark
Image watermark render time on low-end devices
Given a low-end device (Android Go class ≥ 2GB RAM or iPhone 8 class) and watermarking enabled When opening or zooming a 12MP still image with the overlay applied Then p95 overlay compose time ≤ 120 ms and p99 ≤ 200 ms per frame And UI thread jank (missed frames) during image interactions ≤ 1% over a 10-second test window And peak additional memory usage attributable to the overlay ≤ 20 MB
Video watermark overlay frame rate and smoothness
Given 1080p30 video playback with the watermark overlay on a low-end device When playing any 60-second clip Then average FPS ≥ 28 and minimum sustained FPS ≥ 24 in any 10-second window And dropped frames ≤ 5% per minute And 95th percentile frame render time ≤ 42 ms And no ANR or media playback errors attributable to the overlay
Graceful degradation under resource constraints
Given watermark overlay is active and resource constraints occur (GPU > 85% for ≥ 1s, memory pressure warning, or FPS < 24 for ≥ 1s) When the condition is detected Then the system switches to a simplified watermark mode within 1 second (e.g., single-line corner mark) And performance returns to the target thresholds within 3 seconds And the watermark remains present (not removed), maintaining traceability (contact name and timestamp visible) And a mode-change event is recorded with reason=resource_constraint
Monitoring hooks for overlay performance and errors
Given analytics is enabled When the overlay renders on image or video Then a metric overlay_render_time_ms is recorded for ≥ 95% of render operations with tags: platform, device_tier, media_type(image|video), overlay_mode(standard|simplified) And during video playback, dropped_frame_count and avg_fps are emitted per session And on any overlay failure, an overlay_error event is logged with error_code and stack/context And metrics are available in the monitoring backend within 5 minutes at p95 ingestion latency
Audit and Forensics Reporting
"As a community director, I want reports that tie a leaked image back to a specific viewer and viewing time so that I can address issues quickly and maintain resident dignity and compliance."
Description

Store view events and watermark parameters for each link open to support traceability. Provide an internal report that shows which contacts viewed a specific update (with timestamps) and the exact watermark text shown, enabling administrators to match a leaked screenshot to a viewer without needing to alter media. Include exportable logs, filtering by resident, contact, and date range, and ensure data retention aligns with organizational policies.

Acceptance Criteria
Log View Event with Watermark Parameters
Given a valid share link to an update for an approved contact When the contact opens the link and the update renders Then the system persists a view event containing: event_id, update_id, resident_id, contact_id, contact_display_name_used_in_watermark, watermark_text, watermark_generated_at_utc, view_event_recorded_at_utc And the event is immutable and write-once And repeated opens create distinct events each with unique event_id and accurate timestamps And failed or expired link opens do not create a view event
Per-Update Internal Viewer Report
Given an administrator with report access selects a specific update When the Forensics Report is viewed Then the report lists each view event with columns: contact_display_name, contact_id (masked), viewed_at_utc, watermark_text And entries are sorted by viewed_at_utc descending by default And pagination reflects the correct total number of events and pages
Filter and Export Logs by Resident, Contact, Date Range
Given filters for resident, contact, and date range are available When any combination of filters is applied Then the results include only events satisfying all selected filters and whose viewed_at_utc falls within the inclusive date range And clearing filters resets the results to the full set for the tenant When export is requested Then a CSV file downloads containing only the filtered rows with a header row and RFC 4180-compliant escaping
Data Retention Policy Enforcement
Given an organization-wide retention period of N days is configured When a view event exceeds N days since view_event_recorded_at_utc Then the event is purged from storage and no longer appears in reports or exports within 24 hours And events newer than or equal to N days remain fully available And retention period changes apply to new purges going forward without restoring previously purged data
Traceback from Watermark Text
Given watermark text from a leaked screenshot is provided by an administrator When the admin searches the report by exact watermark_text Then matching view events are returned with the associated contact and timestamps And if no exact match exists, the system returns zero results without partial matches
Report Access Control and Audit
Given role-based permissions are configured for reporting When a non-authorized user requests the Forensics Report or export Then access is denied and no report data is returned When an authorized administrator accesses the Forensics Report or export Then the access is permitted and the access attempt is logged with admin_id, action, and timestamp

Consent Gate

Re-validates consent and Incident Freeze status at the moment of link open. If scopes have changed, the page auto-redacts or blocks access and logs the event, giving Privacy Stewards confidence that every share remains compliant in real time.

Requirements

Real-time Consent Revalidation on Link Open
"As a Privacy Steward, I want each opened link to revalidate consent and incident freeze status in real time so that access always reflects current policies and risk conditions."
Description

On every share link open, perform a server-side, real-time authorization check against the latest resident consent scopes and any active Incident Freeze flags before rendering content. The check must evaluate the requesting viewer’s identity, relationship, and permission scopes against all assets referenced by the link (photos, captions, voice-to-text notes, digests), including multi-resident content. The enforcement runs on the server (no client-side trust), supports short-lived tokens, and applies decisions atomically per asset. Target added latency is under 300ms p95, with clear fallback messaging. This ensures that access always reflects the most current policy state, eliminating stale permissions and ensuring compliance.

Acceptance Criteria
Server-side Revalidation Before Render
Given a share link is opened, When the server receives the initial HTTP request, Then it performs authorization against the latest consent scopes and Incident Freeze flags before sending any content bytes. Given server-side authorization fails for the viewer, When the request is processed, Then the response is 401 or 403 with zero bytes of asset content and Cache-Control: no-store. Given client-side scripts are disabled or tampered, When the link is opened, Then protected assets remain inaccessible because authorization is enforced exclusively server-side.
Short-lived Token Validation and Rotation
Given a share link contains a short-lived token with a configurable TTL (default ≤ 15 minutes), When the token is expired, revoked, or not yet valid (nbf), Then the server denies access with 401 and no asset bytes. Given a token is valid, When assets are authorized, Then the server issues per-asset ephemeral URLs (valid ≤ 60 seconds) or streams content directly, preventing reuse beyond their validity window. Given a token is replayed after first successful use and its validity window has elapsed, When the link is opened again, Then access is denied and the event is logged as a replay attempt.
Identity, Relationship, and Scope Enforcement
Given a viewer’s identity is resolved from the token to a specific relationship on record, When their current permission scopes are evaluated, Then only asset types allowed by scope (e.g., Photos but not Notes) are returned; disallowed types are withheld. Given a viewer’s relationship has been removed or set to View=Denied for any resident in the link, When the link is opened, Then access to assets involving that resident is blocked with a compliant message and logged. Given a viewer is approved for Resident A but not Resident B, When a link includes assets for both A and B, Then only Resident A assets are returned.
Per-Asset Atomic Decisions for Multi-Asset/Multi-Resident Links
Given a link references multiple assets across one or more residents, When authorization is evaluated, Then a decision is made independently per asset, and only assets with Allow are delivered in the same response. Given any asset fails authorization, When the response is constructed, Then that asset is excluded or redacted without affecting delivery of authorized assets, and no partial bytes of the denied asset are sent. Given streaming or pagination, When assets are fetched in batches, Then decisions remain atomic per asset across pages with consistent decision reasons.
Incident Freeze Overrides and Blocks
Given any resident associated with an asset has an active Incident Freeze, When the link is opened, Then that asset is fully blocked (not partially redacted), and the user sees a neutral message indicating content is unavailable due to updated privacy settings. Given an Incident Freeze is lifted, When the link is opened subsequently, Then previously blocked assets are re-evaluated and returned only if all other consent checks pass. Given an Incident Freeze causes a block, When the event is logged, Then the log includes resident IDs, asset IDs, freeze flag version/timestamp, viewer ID, decision=Blocked, and reason=IncidentFreeze.
Performance SLO: <300ms p95 Added Latency
Given typical production traffic and cold caches, When 10,000 link-open requests are executed, Then the added authorization and enforcement latency at the server is < 300 ms at p95 (measured excluding network RTT). Given degraded dependencies (e.g., consent store tail latency), When revalidation runs, Then the system either meets < 300 ms p95 via resilience mechanisms or fails closed with 503/403 within 500 ms. Given performance metrics are collected, When a release is deployed, Then dashboards display p50/p95/p99 added latency for link-open endpoints with weekly SLO compliance ≥ 99%.
Fallback Messaging and Comprehensive Audit Logging
Given any asset is denied, redacted, or blocked, When the response is sent, Then the viewer sees clear, non-sensitive messaging (e.g., “This content is unavailable due to updated privacy settings”) without revealing resident names or policy details. Given any authorization decision is made, When the request completes, Then an immutable audit log entry is written with timestamp, viewer ID, link ID, asset IDs, decision (Allow/Redact/Block/Deny), reason codes (ConsentRevoked/ScopeMismatch/IncidentFreeze/ExpiredToken), consent snapshot version/hash, and end-to-end latency. Given an audit is performed, When logs are queried for the last 30 days, Then entries are retrievable by time range, resident ID, link ID, viewer ID, and reason code within 2 seconds for 99% of queries.
Conditional Auto-Redaction & Access Blocking
"As a family member, I want the page to hide only what I’m not authorized to see—or clearly block when required—so that I still receive timely, compliant updates without confusion."
Description

Dynamically apply policy-driven redaction or full blocking when scope changes are detected at link open. For photos and videos, remove or blur non-consenting faces and identifiable elements using the existing auto-blur engine; for captions and voice-to-text, mask entities and names tied to non-consenting residents. If safe redaction cannot be guaranteed within latency thresholds, block the asset and present neutral, non-revealing messaging to viewers. Redaction must be applied on-the-fly without requiring re-upload, and decisions must be consistent across web and mobile views. Provide graceful UI placeholders to preserve context while ensuring privacy.

Acceptance Criteria
Real-Time Consent & Freeze Check on Link Open
Given a share link is opened by a viewer, When the request reaches the Consent Gate, Then the system re-validates current consent scopes and incident-freeze flags for all residents referenced by the asset within 300 ms using the latest policy version. Given re-validation completes, When a decision is produced, Then it must select redaction or blocking strictly according to policy with no cached policy older than 60 seconds influencing the outcome. Given a decision is made, When logging the event, Then an audit record is written including linkId, assetId, requesterAnonId, timestamp (ISO-8601), policyVersion, decision, and reasonCodes, with 99.9% write success over a rolling 24 hours.
Auto-Redaction for Photos/Videos (Faces and Identifiers)
Given a photo or video includes any non-consenting resident, When the asset is served, Then all non-consenting faces are blurred with Gaussian blur sigma ≥ 10 covering ≥ 98% of each detected face area, and consenting faces remain unblurred. Given visual identifiers tied to non-consenting residents (e.g., name badges, room numbers), When detected, Then they are obscured with a solid mask; precision ≥ 90% and false positives ≤ 5% on the acceptance test corpus. Given redaction is required, When processing, Then p95 latency ≤ 2.0 s for images and ≤ 4.0 s for 10 s videos; if thresholds would be exceeded, the request follows the blocking path.
Caption and Transcript Entity Masking
Given a caption or voice-to-text transcript contains entities tied to non-consenting residents, When rendering text to the viewer, Then all such entities (full names, first names with contextual link, room/unit identifiers) are replaced with "[redacted]" while preserving punctuation and sentence structure within ±10% length variance. Given entity detection runs, When evaluated on the acceptance test set, Then precision ≥ 95% and recall ≥ 90% for required entity classes. Given masking is applied, When the response is sent, Then only redacted text is delivered to the client; unredacted text is never exposed in payloads or client logs.
Latency- or Confidence-Based Safe Blocking with Neutral Messaging
Given required redaction cannot complete within defined latency thresholds or any mandatory detection confidence < 85%, When serving the request, Then the original media is not transmitted and the asset is blocked. Given the asset is blocked, When the page renders, Then the viewer sees the neutral, non-revealing message "This content is unavailable due to privacy settings." localized to the viewer locale, with no resident names, dates, units, or incident references included. Given the block is presented, When assistive tech is used, Then the message is announced with role=alert within 500 ms; an audit event is logged with decision=blocked and appropriate reasonCodes (e.g., latency_timeout, low_confidence).
Cross-Platform Decision Consistency (Web and Mobile)
Given the same share link is opened on web and on mobile within 5 minutes, When policy inputs (consent snapshot, incident freeze, policyVersion) are identical, Then the decision (redact vs block) and the applied mask set are identical; mask artifact hash matches across platforms. Given caching is employed, When consent/policy changes occur, Then cache invalidates within 2 seconds of the change webhook; cache TTL for prior decisions is ≤ 60 seconds to prevent divergence.
On-the-Fly Delivery Without Re-Upload
Given the source asset exists once in storage, When redaction is applied, Then the original binary remains unmodified; redactions are generated at serve-time or as short-lived derivatives linked to policyVersion. Given consent or policy changes after upload, When the link is opened subsequently, Then updated redaction/block rules are enforced within 60 seconds without requiring creator re-upload. Given derivatives are generated, When stored, Then retention is < 24 hours unless preserved for audit; originals are not overwritten or re-encoded.
Context-Preserving Placeholders and Accessibility
Given media or text content is redacted or blocked, When rendering the UI, Then placeholders preserve layout within ±5% of original dimensions and include neutral labels (e.g., "Redacted media") without revealing identities. Given a screen reader is used, When navigating placeholders, Then accessible names/roles convey "redacted media placeholder" and controls meet WCAG 2.1 AA contrast (≥ 4.5:1). Given captions contain masked spans, When displayed, Then masked tokens appear as "[redacted]" with no hover/preview revealing original content.
Incident Freeze Enforcement
"As an administrator, I want an incident freeze to instantly halt access to related content across all links so that we maintain safety and compliance during investigations."
Description

When an Incident Freeze is active for any resident represented in an asset, enforce immediate, facility-wide blocking of affected content at link open regardless of prior consent. Support partial blocking for group assets by removing or masking the frozen resident while preserving permissible portions if policy allows; otherwise, block the full asset. Provide neutral viewer messaging, staff-facing context in the admin console, and automatic unblocking on freeze release. Ensure propagation across all existing links and digests without re-publishing.

Acceptance Criteria
Block Single-Resident Asset on Active Incident Freeze
Given an asset representing only Resident A and an active Incident Freeze exists for Resident A; When any user opens any existing or newly created share/link to the asset; Then access is denied before any media bytes are served, regardless of prior consent or token validity, and the response returns HTTP 403 with error code INCIDENT_FREEZE_ACTIVE; And the UI renders a neutral placeholder instead of the asset; And an access-denied event is appended to the audit log with timestamp, asset_id, resident_ids, freeze_id, link_id (if any), viewer_context, and outcome=blocked; And the denial is consistently enforced across web, mobile, and API endpoints on first request.
Partial vs Full Blocking for Group Assets per Policy
Given a group asset containing Residents A (frozen) and B (not frozen); When policy facility.allowPartialFreezeRedaction=true and a viewer opens the asset; Then the asset renders with Resident A visually masked/removed (face/body occlusion ≥95% of pixels across all frames for images/videos) and any resident-specific caption or tag for Resident A is omitted; And a neutral "Content redacted to protect privacy" badge is shown; And an audit event outcome=partial_redact is logged. Given the same asset and policy facility.allowPartialFreezeRedaction=false; When a viewer opens the asset; Then the entire asset is blocked with HTTP 403 INCIDENT_FREEZE_ACTIVE and neutral placeholder; And an audit event outcome=fully_blocked is logged.
Enforce Freeze on Existing Digest and Shared Links
Given a previously sent email/SMS digest and previously shared links that reference an asset containing Resident A; And an Incident Freeze is activated for Resident A after the digest/links were sent; When a recipient clicks any digest item or opens any existing link; Then the Consent Gate re-validates at open and enforces block or partial-redaction per policy without requiring re-publish; And any server-rendered thumbnail/preview requested after activation reflects the freeze (placeholder or redacted) within 60 seconds globally; And CDN caches do not serve unfrozen media after 60 seconds from activation; And an audit event is recorded for each access attempt.
Neutral Viewer Messaging and Placeholder Behavior
Given any access that is blocked or partially redacted due to an Incident Freeze; When the viewer interface renders the outcome; Then the message copy is neutral (does not mention incident, resident name, or PHI) and reads "This content is temporarily unavailable" for full blocks or "Portions of this content are redacted to protect privacy" for partial; And no resident-identifying data appears in alt text, filenames, URLs, or metadata; And the placeholder/badge meets WCAG 2.1 AA contrast and is localized to the viewer’s language when available with English fallback; And refresh/retry controls do not bypass enforcement.
Admin Console Context and Audit Logging
Given staff with Privacy Steward or Admin role views an affected asset in the admin console; When an Incident Freeze is active or has recently enforced; Then the console displays the frozen resident(s), freeze_id, freeze start time, policy applied (partial/full), count of impacted links/digests, and last 10 enforcement events; And every enforcement writes an immutable audit log entry with fields: timestamp (UTC), asset_id, affected_resident_ids, freeze_id, request_source (web/mobile/API), viewer_type (family/staff/anonymous), link_or_digest_id, outcome (blocked/partial_redact/allowed), http_status, and request_id; And audit entries are queryable within 5 seconds of the event and exportable (CSV) with exact field fidelity.
Automatic Unblocking After Freeze Release
Given an Incident Freeze for Resident A is lifted at time T; When a viewer opens a previously blocked/redacted asset at time T+Δ; Then enforcement re-validates and unblocks or removes redaction according to current consent scopes without requiring re-publish; And the change propagates to all endpoints and thumbnail/preview requests within 60 seconds; And an audit event outcome=unblocked is logged; And the admin console reflects resolved state with freeze end time.
Propagation, Revalidation, and Safe-Default on Failure
Given an Incident Freeze is activated; When any endpoint (web, mobile, public link, API) receives an open/view request; Then it must call the Consent Gate to re-validate at the moment of open and apply enforcement before streaming media; And system-wide propagation of enforcement occurs within 60 seconds; And if the Consent Gate is unreachable or times out, the client shows the neutral placeholder and no media bytes are served (safe default) within 2 seconds; And once connectivity restores, subsequent opens reflect the current freeze state.
Access Decision Audit Logging
"As a Privacy Steward, I want a searchable audit trail of every access decision so that I can prove compliance and investigate anomalies quickly."
Description

Record a tamper-evident audit event for every link open and per-asset decision including timestamp, viewer ID, content IDs, resident IDs, evaluated consent version IDs, policy rule path, action (allow/redact/block), and latency metrics. Provide a steward console to search, filter, and export logs (CSV) with retention aligned to compliance policy. Correlate related events via request IDs and support drill-down into the exact redaction rationale without exposing protected content. This enables provable compliance and rapid incident investigation.

Acceptance Criteria
Audit Event on Link Open — Allow
Given a valid share link and active consents for all assets When the viewer opens the link Then an "access_decision" audit event is written with fields: timestamp_utc, request_id, viewer_id, resident_ids, content_ids, consent_version_ids_evaluated, policy_rule_path, action, incident_freeze, latency_decision_ms, latency_log_write_ms, record_hash, chain_prev_hash And action equals "allow" And incident_freeze equals false And timestamp_utc is in ISO 8601 UTC (Z) format And the event is persisted before the response body is returned And the event is retrievable by request_id within 5 seconds And record_hash verification succeeds and chain_prev_hash matches the immediately prior event in the log stream
Per-Asset Decisions and Correlation — Redaction in Mixed Asset Set
Given a post containing N assets where some assets require redaction per current consent scopes When the viewer opens the link Then exactly N "asset_decision" audit events are written, one per asset, each with fields: timestamp_utc, request_id, viewer_id, resident_id(s), content_id, consent_version_ids_evaluated, policy_rule_path, action, latency_decision_ms, latency_log_write_ms, record_hash, chain_prev_hash, rationale_ref (for action in {"redact","block"}) And all "asset_decision" events share the same request_id as the parent "access_decision" And the parent "access_decision" event exists and is retrievable by the same request_id And actions reflect the per-asset evaluation with at least one action = "redact" And the count of "asset_decision" events equals N And each rationale_ref resolves in the steward console to a rationale view without exposing protected content
Dynamic Consent/Incident Freeze — Block on Change
Given a valid share link where consent has been revoked for at least one resident or an Incident Freeze is active at the moment of open When the viewer opens the link Then no protected content is returned and the HTTP status is 403 And an "access_decision" audit event is written with fields: timestamp_utc, request_id, viewer_id, resident_ids, content_ids, consent_version_ids_evaluated, policy_rule_path, action, incident_freeze, latency_decision_ms, latency_log_write_ms, record_hash, chain_prev_hash And action equals "block" And incident_freeze reflects the active freeze state (true if active, false otherwise) And policy_rule_path identifies the exact rule that triggered the block And the event is searchable by viewer_id and resident_ids within the steward console within 1 minute
Steward Console — Search and Filter Logs
Given a steward with "View Audit Logs" permission When the steward applies filters for any combination of date_range (UTC), resident_id, viewer_id, action, request_id, policy_rule_path, content_id, consent_version_id Then the results include only records matching all active filters And results are sortable by timestamp_utc ascending or descending And the first page of up to 100 records returns within 2 seconds for result sets up to 50,000 records And pagination supports page_size 25, 50, or 100 and next/previous navigation And removing all filters returns results for the default last 7 days And users without the required permission receive HTTP 403 and cannot access the console
Export Logs to CSV — Fields, Filtering, and Privacy
Given any current filter set in the steward console When the user clicks "Export CSV" Then the system generates a CSV (RFC 4180) containing only records matching the filters, with header columns in this exact order: timestamp_utc, request_id, log_type, viewer_id, resident_ids, content_ids, consent_version_ids_evaluated, policy_rule_path, action, incident_freeze, latency_decision_ms, latency_log_write_ms, record_hash, chain_prev_hash, rationale_ref And all timestamps are UTC (Z) and values are properly quoted and comma-separated And no protected content or thumbnails are included in the CSV And exports up to 100,000 rows stream without timeouts; larger requests prompt the user to narrow filters And a corresponding "export" audit event is logged with steward user_id, timestamp_utc, and filter summary
Drill-Down Rationale — No Content Exposure
Given a log entry with action in {"redact","block"} When a steward clicks "View rationale" Then the UI displays the evaluated policy_rule_path, consent scopes and versions, matched resident_ids, and content_id, plus a human-readable rationale text, but does not render or link to the protected content And network requests for content bytes are not made and any attempted asset fetch is blocked by the API And the rationale view reveals no PHI/PII beyond IDs and policy metadata And a "rationale_view" audit event is recorded with steward user_id, timestamp_utc, and request_id
Retention, Immutability, and Tamper Verification
Given a retention policy of R days configured by Privacy Stewards When the system stores audit events Then events are written to an immutable, append-only store; update or delete operations on non-expired events are rejected And each event includes record_hash and chain_prev_hash and the verification API returns status "OK" for the retained range And when events exceed R days, they are purged automatically and a retention_tombstone record is created summarizing the purged range without including protected content And after purge, chain verification still returns "OK" for the retained range And any detected tamper causes verification status "FAIL" and triggers an alert to Privacy Stewards within 5 minutes
Consent Scope Versioning & Secure Tokenization
"As a security engineer, I want links to use short-lived tokens and consent versioning so that outdated permissions cannot be reused or exploited."
Description

Maintain versioned consent records per resident and map viewer authorization scopes to those versions. Issue short-lived, signed link tokens that reference resource IDs and viewer identity but never embed permissions directly. On open, resolve the latest consent versions and enforce them; when consent changes, previously issued links automatically reflect the new policy without cache inconsistencies. Support token revocation lists, clock skew tolerance, and replay protections.

Acceptance Criteria
Enforce Latest Consent on Link Open
Given a link token issued at T0 and consent changes at T1 > T0, When the viewer opens the link at T2 ≥ T1 + 5s, Then the system resolves and enforces the latest consent version for the resident and viewer. Given the latest consent removes access to photos, When the link is opened, Then no photo bytes are delivered and thumbnails are replaced with redacted placeholders. Given the latest consent allows notes-only, When the link is opened, Then only text note content is delivered. Given consent is fully revoked, When the link is opened, Then a 403 Forbidden is returned and the event is logged with reason "consent_revoked".
Signed Short-Lived Token Without Embedded Permissions
Given a link is generated, Then the token payload contains jti, residentId, resourceId(s), viewerId, iat, exp, nonce, and contains no consent scope or permission claims. Rule: exp - iat ≤ 900 seconds; tokens with exp > iat + 900 are rejected at creation. Given a token is presented, When the signature validates with the current active key and exp/iat are within allowed window including skew tolerance, Then proceed to consent resolution; otherwise return 401 Unauthorized. Given an expired token, When presented, Then return 401 and log reason "token_expired".
Token Revocation and Replay Protection
Given jti is on the revocation list, When token is presented, Then return 401 and log "token_revoked". Given a token with unseen jti is accepted, Then record jti as seen until exp + 300 seconds. Given the same jti is presented again, When seen status is true, Then return 401 and log "replay_detected" with no content delivered.
Viewer Scope Mapping to Consent Version
Given viewerId belongs to an organization and role, When evaluating access, Then the system derives authorization scope server-side and compares to the resident's latest consent version without relying on token claims. Given a viewer's role changes between issuance and open, When opening a previously issued link, Then the new role-derived scope is used in evaluation. Given no consent exists for the resident, When the link is opened, Then return 403 with reason "no_consent" and log the decision.
Automatic Redaction on Scope Downgrade
Given latest consent requires face blurring for non-consenting individuals, When rendering a photo, Then blurred images are generated server-side and only blurred bytes are delivered. Given consent allows transcript-only access, When accessing an update with audio, Then the transcript is returned and the audio URL is omitted. Given field-level restrictions prohibit location metadata, When delivering JSON, Then location fields are omitted entirely.
Clock Skew Tolerance
Rule: Accept tokens if server_now ≤ exp + 120s and iat ≥ server_now - 120s; otherwise reject with 401 "time_skew". Given client time differs by ≤ 120 seconds, When presenting a valid token, Then validation succeeds.
Audit Logging of Access Decisions
Given any link open attempt, When a decision is made, Then an immutable audit entry is written with tokenId (jti), viewerId, residentId, resourceId(s), resolvedConsentVersionId, viewerScopeId, decision (allow/redact/block), reason codes, redactions applied, timestamp (UTC), and request IP. Given validation fails at any step, Then an audit entry is written with failure reason and no resource payload is persisted in logs. Given a privacy steward queries logs by tokenId or viewerId over a time range, Then matching entries are retrievable.
Fail-Safe Degradation & Timeouts
"As an operations lead, I want the system to fail safely during outages so that we never expose content beyond current consent."
Description

Implement resilient, privacy-first behavior when dependencies degrade. If the consent service or face-redaction engine is unavailable or exceeds timeouts, default to the safest permissible action (block or redact-all) and present neutral messaging. Add exponential backoff, circuit breakers, idempotent retries, and structured error telemetry. Provide service-level objectives (e.g., 99.9% decision availability, 300ms p95 added latency) with dashboards and alerts for breach detection.

Acceptance Criteria
Admin Policy Configuration & Alerts
"As an administrator, I want to configure enforcement rules and receive alerts on blocked access so that our policies match the facility’s risk posture and compliance needs."
Description

Provide an administrative UI to configure consent enforcement policies, including default action on uncertainty (redact vs. block), latency thresholds, redaction strictness, and viewer messaging templates. Enable role-based access for Privacy Stewards to subscribe to real-time alerts and daily summaries of blocked/redacted access attempts via email/SMS/in-app notifications. Allow facility-level overrides and per-resident exceptions with audit trails for all policy changes.

Acceptance Criteria

Link Ack

Let recipients acknowledge or send a quick ‘Thanks’ right on the link—no app required. Acks post back to the resident timeline and feed Delta Highlights, signaling to staff that the update was received and reducing follow-up calls.

Requirements

Secure Magic Link Tokens
"As an approved family member, I want to acknowledge an update from a secure link without logging in so that I can quickly confirm receipt while keeping the resident’s information private."
Description

Generate unique, expiring, recipient-scoped tokens appended to outbound update links (email/SMS) that enable one-tap acknowledgment without login. Tokens are HMAC-signed, time-bound, and tied to a specific update and recipient to prevent replay and spoofing. Backend validates token scope, enforces rate limits, and guarantees idempotent processing of acks. Includes endpoints to issue, validate, and consume tokens; supports revocation, configurable expiry windows, and channel attribution for analytics. Ensures minimal PII in links and server-side mapping to approved contacts.

Acceptance Criteria
One-tap Web Acknowledgment UI
"As a family contact, I want a simple one-tap “Thanks” on the shared update so that I can respond without installing an app or creating an account."
Description

Deliver a lightweight, mobile-first web page that loads from the shared link and presents large, accessible buttons for “Ack” and “Thanks,” with an optional short note (up to 120 characters). No account or app install required; auto-associates identity from the token and pre-fills known display name when available. Handles expired/invalid link states with clear guidance, prevents duplicate submissions, and shows a confirmation receipt. Meets accessibility (WCAG 2.1 AA), supports localization, and targets sub-1s first contentful paint on 4G. Captures device/channel metadata and consent to display name where policy allows.

Acceptance Criteria
Timeline and Delta Highlights Integration
"As a staff member, I want acknowledgments to appear on the resident’s timeline and Highlights so that I know families saw the update and can avoid follow-up calls."
Description

On successful acknowledgment, create a structured event on the resident’s timeline with reaction type, timestamp, optional short note, and the actor’s masked identity per policy. Update Delta Highlights with acknowledgment metrics (count per update, time-to-first-ack) and surface an ack badge on the originating update. Ensure deduplication via idempotency keys, correct chronological ordering, and near-real-time propagation to staff views. Respect data retention settings and avoid exposing other recipients’ identities in family-facing contexts.

Acceptance Criteria
Staff Visibility and Notifications
"As a caregiver, I want to see which updates have been acknowledged and by whom so that I can gauge whether follow-up is needed."
Description

Provide clear indicators in staff dashboards showing per-update acknowledgment status, counts, and first-ack time. Offer configurable alerts when no acknowledgment is received within a set window or when the first acknowledgment arrives, delivered via in-app badge and optional push/email. Add filters and sorting for unacknowledged updates to prioritize follow-up. Display who acknowledged (name/relationship) to staff according to permissions, while keeping family recipients anonymous to one another.

Acceptance Criteria
Admin Controls and Policy Settings
"As an administrator, I want to configure how acknowledgments work for our facility so that the feature aligns with our policies and reduces calls without adding risk."
Description

Enable organization- and resident-level settings to turn Link Ack on/off, select allowed reactions (“Ack,” “Thanks”), toggle optional notes, configure token expiry and resend behavior, and define notification thresholds. Provide default copy and branding for the web ack page, plus customization for language and accessibility. Enforce consent and privacy rules (e.g., whether to display recipient names to staff) and support audit-ready exports of configuration changes.

Acceptance Criteria
Analytics and Reporting
"As a community director, I want reports on acknowledgment rates and response times so that I can quantify impact and optimize communication."
Description

Track and report acknowledgment KPIs, including ack rate per update, time-to-first-ack, channel performance (email vs SMS), and engagement by unit/facility. Provide trend charts and CSV export, and attribute impact to operational outcomes such as reduced inbound calls and faster handoffs. Integrate metrics into Delta Highlights summaries and allow drill-down from facility level to resident and update. Ensure aggregation and anonymization where required by policy.

Acceptance Criteria
Security, Privacy, and Audit Logging
"As a compliance officer, I want acknowledgments to be secure and fully auditable so that we maintain privacy and regulatory compliance."
Description

Enforce end-to-end HTTPS, strict CSP, and no third-party trackers on the ack page. Store minimal PHI in transit and at rest; keep tokens opaque and short-lived. Log token issuance, validation, and acknowledgment events with timestamps, actor mapping, and hashed IP/device fingerprints for fraud detection. Provide auditable trails and retention controls aligned with regulatory requirements. Prevent enumeration of recipients or updates, and ensure CSRF protection and bot mitigation on ack endpoints.

Acceptance Criteria

Panic Revoke

Instantly invalidate any active SafeShare links for a resident or specific update with a single action (optional DuoTap for sensitive items). The change takes effect immediately and is fully logged, offering a fast, safe response if circumstances change.

Requirements

Instant SafeShare Link Invalidation
"As a caregiver or admin, I want revoked SafeShare links to stop working immediately so that I can protect resident privacy when circumstances change."
Description

Provides a server-side revocation mechanism that immediately invalidates active SafeShare tokens and pre-signed URLs within seconds of activation. Ensures denial of access at API, CDN, and media layers using token versioning and blacklist checks to prevent race conditions and replays. Integrates with KinLoop’s SafeShare service to dispatch revocation events to clients and edge caches, guaranteeing no residual access after the action completes. Surfaces success and failure states in the UI, with clear counts of links affected and robust error handling.

Acceptance Criteria
Scoped Revocation (Resident or Update-Level)
"As a caregiver, I want to revoke links for an entire resident or a specific update so that I can respond precisely without disrupting unrelated access."
Description

Enables precise selection of revocation scope from Panic Revoke, supporting resident-level (all active links for a resident) or update-level (one or more specific updates). Previews the number of links to be invalidated before confirmation, supports bulk operations with progress feedback, and guarantees idempotency. Honors assignment boundaries so users can only revoke within residents they are permitted to manage. Provides API parity for programmatic use cases.

Acceptance Criteria
DuoTap Sensitive-Action Confirmation
"As a caregiver, I want a quick two-step confirmation for sensitive revokes so that I don’t accidentally invalidate access during a busy shift."
Description

Introduces an accessible two-tap confirmation pattern to reduce accidental activation for sensitive scopes (resident-level revokes and updates tagged as sensitive). The second tap reiterates scope, impact, and link count, with large touch targets, haptic/audio feedback, and keyboard alternatives. Admin policy controls when DuoTap is required (always, sensitive only, or off). Records confirmation intent in the audit trail.

Acceptance Criteria
Real-Time Propagation & Link Expired Handling
"As a caregiver, I want confirmation that revocation has propagated and recipients see an expired message so that I know the action took effect everywhere."
Description

Propagates revocation instantly across delivery paths, including CDN edges, push deep links, and email links. Purges caches, revokes pre-signed media URLs, and closes active sessions or streams where applicable. Displays a neutral, branded link-expired page to recipients that reveals no PHI, while staff see clear confirmation that propagation completed. Provides a progress indicator until end-to-end confirmation and actionable errors with retry when propagation cannot be verified.

Acceptance Criteria
Immutable Audit Logging & Reason Capture
"As an administrator, I want a complete audit trail of revocations with reason codes so that we meet compliance and can review incidents."
Description

Creates a tamper-evident audit record for every revoke, including actor identity, role, scope and target details, timestamp, reason code and notes, affected link IDs, originating IP/device, and result. Stores entries in an append-only ledger with retention aligned to compliance policies. Provides searchable views, exports, and SIEM-friendly event streams for compliance and incident review.

Acceptance Criteria
Role-Based Access, Re-Auth & Rate Limiting
"As an administrator, I want revocation limited to authorized users with re-auth and safeguards so that misuse and mistakes are prevented."
Description

Restricts Panic Revoke to authorized roles and assigned residents, with optional step-up re-authentication for high-risk actions and recent session inactivity. Applies configurable rate limits and cooldowns to prevent misuse or mass errors, returning clear, localized messages when blocked. Integrates with existing RBAC, SSO, and session management, and logs all policy denials for oversight.

Acceptance Criteria

Guided Rounds

A step‑by‑step, first‑week simulation that walks new Snapshot Aides through mock resident rounds on real devices. Trainees practice one‑tap photos, voice‑to‑text notes, CareTag Shortcuts, and auto‑blur decisions with instant, plain‑language feedback. Scenarios mirror Memory Care, Assisted Living, and Rehab units so staff build confidence where they actually work—no trainer shadowing required.

Requirements

Unit-Specific Scenario Library
"As a new Snapshot Aide, I want realistic practice scenarios that match my unit so that I can build confidence with the exact workflows I’ll use on shift."
Description

Provide a curated library of training scenarios tailored to Memory Care, Assisted Living, and Rehab units. Each scenario mirrors real shift workflows (e.g., morning hygiene snapshot, mealtime check-in, PT session handoff) with clear success criteria for photo capture, voice-to-text notes, CareTag Shortcut selection, and blur decisions. Scenarios can be sequenced into a “first week” plan, randomized to prevent rote memorization, and parameterized for difficulty (time limits, noise levels, lighting). The library reuses KinLoop’s production UI components in a read-only training mode to build muscle memory without risking production data. Content is versioned, allowing administrators to publish updates and unit-specific variations while maintaining an audit trail.

Acceptance Criteria
Step-by-Step On-Device Walkthrough
"As a trainee, I want a step-by-step guide on the actual device so that I can learn exactly where to tap and what to do without a trainer shadowing me."
Description

Deliver an interactive, on-device guide that overlays coach marks and checklists on the live app, leading trainees through each step: open Snapshot, take a one-tap photo, dictate a note, choose CareTag Shortcuts, and make blur decisions. The walkthrough gates progress until required actions are completed, supports back/skip with confirmations, provides haptic and visual confirmations, and gracefully handles interruptions (lock screen, calls). It operates offline-first and detects device capabilities to adapt prompts. The guide uses plain language with large tap targets and accessibility support to ensure adoption for tech-light staff.

Acceptance Criteria
Safe Capture Sandbox (Photo + Voice)
"As a trainee, I want to practice taking photos and dictating notes safely so that I don’t risk sharing real resident data during training."
Description

Implement a sandbox mode for camera and voice-to-text that mimics production behavior while ensuring no protected or training data leaves the device. All captured media is stored in encrypted, ephemeral storage and auto-deleted at session end. A built-in gallery of test images/videos and synthetic faces allows practice when live capture is impractical. Voice-to-text uses the same pipeline and UI as production but flags sessions as training to isolate telemetry. The sandbox enforces clear watermarks and headers to avoid confusion with live updates and never posts to family feeds or care timelines.

Acceptance Criteria
Auto-Blur Decision Trainer
"As a caregiver in training, I want to learn when and how to blur faces based on consent so that I protect resident dignity and stay compliant."
Description

Provide an interactive module that teaches proper blurring decisions using consent-aware scenarios. The system highlights detected faces and objects, prompts the trainee to choose blur levels, and cross-references a mock consent roster to simulate real compliance decisions. It offers side-by-side previews (blurred vs. original), explains the rationale for correct choices in plain language, and scores accuracy and speed. Edge cases include partial profiles, background bystanders, and low-light images. Guidance aligns with facility policy configurations so that feedback is consistent with actual compliance standards.

Acceptance Criteria
CareTag Shortcuts Drills
"As a Snapshot Aide, I want to practice choosing the right CareTag Shortcuts so that my updates are fast, consistent, and useful to families and staff."
Description

Create targeted drills for selecting CareTag Shortcuts quickly and correctly based on scenario cues (e.g., hydration, mobility assist, mood). Drills present timed prompts, suggest best-practice tag combinations, and validate against unit-configured rules. The system surfaces tips when incorrect tags are chosen and tracks improvement over repeated attempts. Results feed into overall training scores and help standardize documentation language across teams.

Acceptance Criteria
Instant Feedback & Scoring Engine
"As a trainee, I want immediate, easy-to-understand feedback so that I can correct mistakes and improve quickly without waiting for a trainer."
Description

Integrate a rules-driven engine that validates actions in real time and returns plain-language feedback (e.g., “Great lighting—faces clear,” “Try adding a CareTag for mobility assist”). The engine aggregates per-step and per-session scores, supports streaks and retries, and provides tailored remediation suggestions with links to micro-tips. Rubrics are configurable by administrators to reflect policy and unit norms. Session summaries include strengths, gaps, and suggested next scenarios, and scores are securely logged for analytics.

Acceptance Criteria
Training Analytics & Certification
"As an administrator, I want visibility into trainee progress and a clear certification signal so that I can schedule staff confidently and ensure compliance."
Description

Track trainee progress across scenarios, attempts, scores, and completion times; surface cohort and unit-level insights to administrators. Provide dashboards, CSV export, and alerts for overdue first-week milestones. When trainees meet configurable thresholds (e.g., minimum scores across required scenarios), automatically issue a “Guided Rounds Ready” badge on their KinLoop staff profile. Maintain an audit log of completions and refresh intervals to support re-certification and policy changes. Access is role-based to protect trainee privacy and compliance data.

Acceptance Criteria

Sandbox SafePost

A training‑only environment that mirrors live capture and sharing but never publishes to families. Staff can see a ShareSafe preview, trigger Consent Gate checks, and test Incident Freeze without risk. Missteps are highlighted with what to fix and why, so learners practice freely and retain compliant habits faster.

Requirements

Sandbox Mode Isolation & Non-Publish Guarantee
"As a caregiver in training, I want assurance that anything I capture won’t reach families so that I can practice without risking privacy or compliance violations."
Description

Provide a dedicated training-only mode that mirrors all capture and compose flows while guaranteeing no content is ever published to families. Implement an end-to-end “sandbox” flag propagated from client to backend services, storing training artifacts in segregated data stores/queues and disabling all outbound delivery channels (push, email, digest generation). Display persistent, high-contrast “Training—Not Sent to Families” indicators and watermark previews. Enforce identical encryption, access controls, and audit logging as production while preventing cross-environment data mixing. Support offline use with sandbox-scoped caches. Apply automatic retention (e.g., 30 days) and secure purge for all sandbox data. Provide admin controls to enable/disable Sandbox SafePost per site and role, and expose environment state via telemetry for compliance verification.

Acceptance Criteria
ShareSafe Family Preview Mirror
"As a caregiver, I want to see exactly what a family would see so that I can validate tone, clarity, and compliance before going live."
Description

Render a pixel-accurate preview of what a family would see for posts created in Sandbox SafePost, using the same templating, formatting, captions, timestamps, auto-blur indicators, and digest batching logic as production but with delivery disabled. Include device-specific previews (mobile push, email digest excerpt, portal view) and accessibility elements (alt text, screen reader order). Surface the “would-be recipients” list using simulated or empty recipients and clearly label as training. Implement automated parity checks against production renderers to detect drift when new styles or components ship.

Acceptance Criteria
Consent Gate Simulator
"As a new hire, I want to practice handling consent flags so that I learn how to avoid sharing non‑consenting residents."
Description

Simulate the Consent Gate checks using synthetic rosters and configurable consent states (photo allowed/denied, group visibility, HIPAA-sensitive flags) to reproduce real error and warning conditions. Allow trainers to toggle resident consent scenarios and attach them to practice sessions. When a violation is detected, present the exact policy rule, the impacted element (e.g., resident face, name in caption), and actionable steps to resolve (retag, crop, remove PII, adjust audience). Mirror production API response structures and edge cases (mixed consents in group photos, revocations mid-session) without exposing real PHI.

Acceptance Criteria
Incident Freeze Drill
"As a caregiver, I want to rehearse the incident freeze flow so that I respond correctly under pressure and avoid accidental sharing."
Description

Enable learners to trigger a simulated incident event that immediately freezes related media and notes in the sandbox, disables sharing, and guides them through the incident workflow steps. Include timers, escalation prompts, and supervisor notification simulations. Lock editing per policy while allowing required incident metadata entry. Provide clear visual states for “Frozen” items and a rehearsal of unfreeze/closure when supervisor approval is simulated. Ensure no data exits the sandbox, and log user actions for review.

Acceptance Criteria
Real-time Misstep Coaching
"As a learner, I want immediate feedback on mistakes so that I build compliant habits quickly and confidently."
Description

Detect training missteps in real time—such as missing resident tags, unclear or PII-containing captions, non-consenting faces, or inappropriate audience selection—and surface inline coaching cards that explain what to fix and why, with one-tap fixes where possible. Classify feedback by severity (blocker, warning, tip), localize messages, and link to policy micro-lessons. Capture telemetry on missteps and resolutions for trainer analytics. Run checks on-device when feasible to preserve responsiveness, falling back to sandbox services as needed.

Acceptance Criteria
Auto-Blur & Redaction Practice
"As a caregiver, I want to practice blurring and redacting faces and sensitive details so that I can share compliant images confidently in production."
Description

Provide a practice workflow for auto-blur and manual redaction using test media. Run the same face/person detection models as production, display confidence levels, and allow users to accept/reject auto-blur, brush to redact sensitive areas (names on badges, screens), and compare before/after. Persist practice outcomes for trainer review while ensuring all derivatives remain in sandbox storage. Support low-end device performance with progressive rendering and allow retry with different lighting/background examples.

Acceptance Criteria
Trainer Analytics & Progress Tracking
"As a training administrator, I want visibility into practice activity and trouble areas so that I can target coaching and verify readiness before enabling live posting."
Description

Deliver a trainer dashboard that aggregates sandbox session metrics per learner and cohort: sessions completed, scenario coverage, misstep types/frequency, time-to-fix, pass/fail on required drills (Consent Gate, Incident Freeze, Auto-Blur). Provide export (CSV), filters by site/role/date, and automated completion badges that sync to Admin. Exclude PHI and use pseudonymous identifiers. Respect role-based access and SSO. Offer alerts for learners who stall or repeatedly fail specific checks to target coaching.

Acceptance Criteria

Consent Drills

Interactive micro‑scenarios that build muscle memory for Scope Templates, Renewal Radar, DuoTap approvals, and FaceLink matches. Examples like “non‑consenting face detected” or “consent expiring today” teach the right next tap and policy rationale. Reduces audit findings by making compliance second nature before going live.

Requirements

Drill Scenario Engine
"As a caregiver, I want to practice resolving realistic consent situations in under a minute so that I can respond correctly without hesitation during my shift."
Description

Core engine to render interactive, sub‑60‑second micro‑scenarios that mirror KinLoop workflows (Scope Templates, Renewal Radar notices, DuoTap approvals, FaceLink matches). Simulates system states such as “non‑consenting face detected,” “consent expiring today,” or “missing scope,” with one‑tap choices that match production UI. Provides instant, actionable feedback and the correct next tap, including micro‑explanations and links to the relevant policy. Runs on-device, supports offline mode with pre‑cached scenarios, and uses synthetic resident profiles and media to avoid PHI. Tracks step accuracy, time to resolution, and hesitation points for analytics. Integrates with existing navigation and component libraries to ensure consistency and low maintenance.

Acceptance Criteria
Policy Logic Emulator & Rationale Coach
"As a compliance admin, I want drills to follow our current consent rules and explain the why so that training aligns with audits and improves policy adherence."
Description

Embeds facility‑specific consent rules and Scope Templates into the drills, emulating production decision logic (e.g., allowed media types, approver roles, consent expirations, DuoTap thresholds). When a learner selects an incorrect action, provides the policy rationale, a brief plain‑language explanation, and links to the relevant clause or renewal process. Supports versioned policy bundles per facility and per state, with effective dates and rollback. Syncs with Renewal Radar to reflect real expiration logic and warning windows. Ensures drills stay aligned with compliance changes without app updates via remote configuration.

Acceptance Criteria
Contextual Launchers & Just‑in‑Time Drills
"As a caregiver, I want practice prompts to appear when I face a consent decision so that I can learn the correct action in the moment without leaving my workflow."
Description

Surfaces “Practice this” entry points exactly where users encounter consent tasks in KinLoop (e.g., after a FaceLink non‑consent alert, within a DuoTap approval screen, or when Renewal Radar flags an expiring consent). Deep links open a matching drill with the same UI controls and decisions, then return the user to their original task. Includes scheduled nudges for upcoming expirations and first‑day onboarding flows. Respects shift mode and quiet hours, and degrades gracefully on low bandwidth. Admins can target launchers by role, unit, or competency gaps.

Acceptance Criteria
Adaptive Spaced Practice & Mastery Tracking
"As a training lead, I want drills to focus on each caregiver’s weak spots and recur at the right cadence so that we build lasting, audit‑ready competence with minimal time away from care."
Description

Adapts drill frequency and difficulty per user based on accuracy, response time, and error types. Implements spaced repetition to resurface weak concepts (e.g., scope exclusions, renewal timing) until mastery. Provides short mastery streaks, gentle reminders, and optional weekly micro‑reviews. Stores per‑skill competency scores and decays them over time to re‑prompt. Timeboxes sessions to stay under 60 seconds, supporting tech‑light environments and minimizing workflow disruption.

Acceptance Criteria
Admin Analytics & Compliance Evidence
"As an administrator, I want clear visibility into training completion and error trends so that I can target coaching and produce evidence for regulators and families."
Description

Delivers dashboards and exports covering drill participation, completion rates, accuracy by rule type, time‑to‑correct, and repeat errors. Provides filterable views by facility, unit, role, and date range, with cohort comparisons pre‑ and post‑policy changes. Generates audit‑ready evidence packs (CSV/PDF) mapping competencies to policy clauses and renewal outcomes. Sends proactive alerts when teams fall below mastery thresholds for high‑risk scenarios. Supports de‑identified rollups by default, with RBAC‑gated access to named user views.

Acceptance Criteria
No‑Code Scenario Authoring Studio
"As a policy owner, I want to create and update drills myself so that training stays current with changing regulations and facility practices."
Description

Provides a browser‑based and in‑app editor for ops/compliance to create, localize, and version micro‑scenarios without engineering. Authors can select templates (FaceLink, Renewal Radar, DuoTap), define correct/incorrect paths, attach rationale text, and upload or choose synthetic media. Supports preview in production UI skin, review/approve workflow, and rollout scheduling with targeted audiences. Maintains version history with audit logs and quick rollback. Validates scenarios against current policy bundles to prevent contradictions.

Acceptance Criteria
Synthetic Media & Privacy Safeguards
"As a privacy officer, I want drills to use synthetic data and strict controls so that we protect resident dignity and remain compliant while training staff effectively."
Description

Ensures drills never expose PHI by using synthetic resident identities, AI‑generated or stock faces, and placeholder names. Enforces automatic face blurring in all training images/videos by default, with FaceLink‑like detection to simulate non‑consenting faces. Segregates training telemetry from production records, applies data minimization and 30/90‑day retention policies, and encrypts at rest/in transit. Provides clear consent notices for staff training analytics and RBAC to restrict access. Aligns with HIPAA, state privacy rules, and facility policies.

Acceptance Criteria

TapCoach Tips

Bite‑size, on‑screen nudges that appear at the moment of need—suggesting tags, reminding about ShareSafe Mode, or prompting clearer voice‑to‑text. Tips adapt as skill grows and can be played as quick audio for tech‑light staff. Learners get just‑in‑time guidance without leaving their flow, shortening the path to proficiency.

Requirements

Contextual Tip Trigger Engine
"As a tech-light caregiver, I want tips to appear exactly when they’re helpful in my workflow so that I get guidance without stopping what I’m doing."
Description

A low-latency decision layer that listens to KinLoop app events (e.g., photo capture start, mic activate, tag field focus, ShareSafe state changes, error patterns), user attributes (role, tenure), and environment signals (connectivity, time of day) to determine when and where to surface TapCoach nudges. Must inject tips as non-blocking overlays within 150 ms, respect critical workflows (e.g., emergencies) by suppressing tips, and degrade gracefully offline. Implements configurable rule-based triggers with a pluggable strategy interface for future ML. Persists per-user tip impressions, dismissals, and outcomes for analytics while keeping all decisions on-device to protect PHI. Serves as the foundation enabling moment-of-need guidance without disrupting caregiver flow.

Acceptance Criteria
Skill‑Adaptive Personalization
"As a new staff member, I want the app to tailor tips to my skill level so that I learn faster without being overwhelmed or annoyed."
Description

A personalization layer that models per-user proficiency for key skills (tagging, ShareSafe usage, dictation) and adapts tip content, sequence, and frequency accordingly. Hides mastered tips, introduces advanced hints as competency grows, and re-surfaces basics after inactivity. Uses lightweight, privacy-preserving telemetry (impressions, actions, completion times) stored locally with periodic aggregated sync. Supports facility-level policies and role-based presets (caregiver vs. admin). Ensures transparent behavior with a simple "Why this tip?" explainer on each nudge.

Acceptance Criteria
One‑Tap Audio Tips
"As a caregiver who prefers listening over reading, I want to hear quick tip audio so that I can follow guidance without stopping my task."
Description

Audio-rendered versions of each TapCoach tip optimized for tech-light users: a prominent play button, 3–5 second voice guidance, and offline caching for reliability in low-connectivity facilities. Uses on-device TTS where available; falls back to pre-generated audio packs. Respects device volume, Do Not Disturb, and accessibility settings. Allows replay and slower playback. Localized content and simple language ensure quick comprehension without leaving the task flow.

Acceptance Criteria
ShareSafe Mode Nudges
"As a caregiver capturing a photo, I want a timely reminder to enable ShareSafe when needed so that I protect residents’ dignity and stay compliant."
Description

Real-time prompts that encourage enabling ShareSafe (auto-blur for non-consenting faces) during photo/video capture and attachment. On-device face detection warns when ShareSafe is off and likely non-consenting faces are present, offering a one-tap toggle and brief compliance rationale. Applies cooldowns to avoid repeated prompts, confirms when ShareSafe is enabled, and never uploads media for detection. Integrates with existing auto-blur pipeline and resident consent records to reduce risk and speed compliant handoffs.

Acceptance Criteria
Smart Tag Suggestions
"As a caregiver creating an update, I want helpful tag suggestions so that I can file updates quickly and consistently."
Description

Contextual hints that suggest 1–3 relevant tags while composing updates, based on detected keywords from voice-to-text, recent resident context, and media type. Provides one-tap apply with clear rationale (e.g., "heard ‘med pass’"). Runs on-device using lightweight rules and phrase lists initially, with a pluggable interface for future ML models. Optimized for low-end devices and offline operation. Logs acceptance and dismissal to improve precision and measure time saved, without auto-applying to preserve user control.

Acceptance Criteria
Voice‑to‑Text Clarity Coaching
"As a caregiver dictating notes, I want small prompts that help me speak clearly so that the transcription is accurate and I spend less time editing."
Description

Subtle, real-time nudges that improve dictation quality: prompts about mic distance, background noise, speaking resident names, and using clear sentence starters. Detects low input volume, prolonged silence, or repeated corrections and surfaces unobtrusive tips with quick actions like "Retry last sentence". Provides example phrasing and optional short audio guidance. All analysis remains on-device; respects privacy and accessibility settings to avoid recording beyond dictation intent.

Acceptance Criteria
Nudge Frequency & Dismissal Controls
"As a caregiver under time pressure, I want to snooze or dismiss tips and see them less often so that I’m not interrupted during critical tasks."
Description

Global controls that prevent over-notifying and build trust: per-tip cooldown windows, session caps, shift-long snooze, and honoring Do Not Disturb. Suppresses tips during sensitive workflows (e.g., medication pass, active call). Remembers dismissals for a configurable period and optionally captures a quick reason to improve future relevance. Exposes facility-level defaults for administrators while keeping user-level preferences simple and discoverable.

Acceptance Criteria

Checklist Tracks

Role‑aware checklists auto‑generated from schedule and unit via RoleSmart Mapping, e.g., “3 Guided Rounds in Memory Care,” “1 ShareSafe post,” “Run an Incident Freeze drill.” Progress, due dates, and blockers are visible to the Onboarding Guide, keeping everyone aligned and reducing trainer follow‑ups.

Requirements

RoleSmart Checklist Generation
"As a community admin, I want checklists to auto-generate from role, schedule, and unit so that staff see the right tasks without manual setup."
Description

Build a rule-based mapping engine that auto-generates role-aware checklists from schedule, unit assignment, and care program metadata. Inputs include staff role, shift schedule, unit (e.g., Memory Care), resident roster flags, and compliance requirements. Outputs a per-user daily checklist composed of items like “3 Guided Rounds in Memory Care,” “1 ShareSafe post,” or “Run an Incident Freeze drill.” Supports rule conditions, frequencies, per-shift quotas, dependencies, and effective dates. Integrates with KinLoop’s posting and Incident Freeze modules to create linked tasks and keeps lists in sync when schedules or assignments change. Reduces manual setup, improves consistency, and ensures the right work is surfaced automatically.

Acceptance Criteria
Shift-Aware Assignment & Due Windows
"As a caregiver, I want my tasks to have clear due windows tied to my shift so that I know what to do and when."
Description

Automatically assign checklist items to individuals based on active shift and unit location, with configurable start times, due windows, and recurrence (per shift, daily, weekly). Enforce timeboxing (e.g., 3 rounds distributed across the shift) and unit-specific caps. Handle reassignment for call-offs or schedule changes via API/CSV imports or native scheduler integration. Surface due/overdue states in app and API. Ensures the right task is due at the right time without manual chasing.

Acceptance Criteria
Progress Tracking & Blocker Reporting
"As an onboarding guide, I want to see progress and blockers in real time so that I can intervene early and reduce follow-up."
Description

Provide real-time tracking of completed, in-progress, and blocked items at the item, checklist, and user levels. Each item supports quick-complete, notes, photo/voice-to-text evidence, and blocker reasons with required fields (e.g., resident asleep, supply unavailable). Allow tagging blockers to residents or locations and attach media. Maintain immutable timestamps, actor, and location metadata for auditability. Expose progress and blockers to Onboarding Guides and admins to reduce trainer follow-ups and enable timely support.

Acceptance Criteria
Onboarding Guide Oversight Dashboard
"As an onboarding guide, I want a dashboard of trainees’ checklist status so that I can coach efficiently and keep onboarding on track."
Description

Deliver a role-specific dashboard for Onboarding Guides showing trainee progress, due items, blockers, and SLA breaches across units. Provide drill-down to individual checklists and evidence, quick nudge actions, and assignment adjustments. Include filters by role, shift, unit, and date, plus exportable progress summaries for supervisor reviews. Integrates with notifications and RoleSmart mapping to reflect changes immediately and streamline onboarding oversight.

Acceptance Criteria
Smart Reminders & Escalation Notifications
"As a caregiver, I want smart reminders and gentle escalations so that I stay on pace and don’t miss required rounds or posts."
Description

Send context-aware reminders to assignees based on due windows and completion pace (e.g., prompt when only 1 of 3 rounds is logged mid-shift). Provide overdue alerts and escalation to Onboarding Guides or charge nurses for persistent blockers. Respect quiet hours and notification preferences. Support in-app and push notifications, with optional SMS based on org settings. Record reminder delivery and user responses for accountability.

Acceptance Criteria
Privacy-Safe Attachments & Auto-Blur Enforcement
"As a caregiver, I want to attach photos and notes that are automatically privacy-safe so that I can document care without risking compliance issues."
Description

Enable attaching photos and voice-to-text notes to checklist items with automatic enforcement of KinLoop’s auto-blur for non-consenting faces and PHI minimization. Prevent publishing to family feeds unless required compliance checks pass and faces are cleared. Store media with secure access controls tied to checklist permissions. Ensures dignity, compliance, and safe handoffs when tasks involve resident content.

Acceptance Criteria
Offline Capture & Reliable Sync
"As a caregiver in low-connectivity areas, I want to complete checklists offline so that my shift isn’t blocked by poor Wi‑Fi."
Description

Support full checklist interaction offline, including viewing assigned items, logging rounds, capturing notes and media, and marking blockers. Implement conflict-aware sync that merges updates, preserves sequence and timestamps, and surfaces conflicts for resolution. Use lightweight, encrypted local storage with per-facility data retention controls. Guarantees continuity in low-connectivity environments common in assisted living.

Acceptance Criteria

Readiness Radar

A visual dashboard scoring each learner on time‑to‑capture, tag coverage, consent accuracy, and error resolution in the sandbox. It recommends the next best drill, flags who’s live‑ready, and produces exportable proof for HR orientation completion. Supervisors focus coaching where it matters and cut ramp time.

Requirements

Learner Performance Scoring Engine
"As a training supervisor, I want an objective readiness score for each learner so that I can consistently compare progress and decide who is live‑ready."
Description

Implements a configurable scoring model that calculates an objective readiness score per learner using four core metrics sourced from the KinLoop training sandbox: time‑to‑capture latency, tag coverage completeness, consent accuracy rate, and error resolution efficiency. Supports per-session, 7/14/30‑day rolling windows, and cohort benchmarks. Weightings, thresholds, and pass/fail rules are admin-configurable at org and site levels. Persists score histories for trends, exposes read APIs for the dashboard, and emits events for certification and recommendations. Ensures metric normalization, fairness checks, and localization of labels. Integrates with the auto‑blur service and consent ground truth to validate accuracy and with KinLoop identity services for learner mapping.

Acceptance Criteria
Real‑time Sandbox Telemetry Ingestion
"As a platform administrator, I want reliable live telemetry from the training sandbox so that the Readiness Radar reflects current practice without delays."
Description

Builds a resilient, near‑real‑time pipeline that ingests sandbox events (capture start/submit timestamps, tags applied, consent labels, blur outcomes, error events and their resolution) into Readiness Radar. Guarantees idempotent processing, schema versioning, and at‑least‑once delivery with de‑duplication. Targets end‑to‑end latency under 5 seconds and provides backfill for historical sessions. Applies PII minimization, encryption in transit/at rest, and site scoping. Exposes a monitoring panel with alerts and retry tooling to keep the dashboard data fresh and trustworthy.

Acceptance Criteria
Next‑Best‑Drill Recommendation Service
"As a learner, I want clear next‑best drills tailored to my weaknesses so that I can improve efficiently and get live‑ready faster."
Description

Delivers targeted drill recommendations per learner by identifying metric deficits (e.g., slow time‑to‑capture, low tag coverage, consent errors) and mapping them to drills with step‑by‑step guidance. Combines rules with optional ML ranking, ensures explainability (‘recommended due to repeated consent misses’), and respects supervisor overrides, site policies, and device availability. Tracks acceptance and completion, prevents repetition fatigue, and supports A/B tests to measure ramp‑time impact. Integrates with notifications to nudge learners and with the scoring engine to update readiness post‑drill.

Acceptance Criteria
Live‑Readiness Certification & HR Export
"As an HR coordinator, I want verifiable orientation completion documentation so that I can record compliance without manual reconciliation."
Description

Evaluates learners against configurable readiness thresholds and required drills, then issues a certification status with audit evidence. Generates exportable proof for HR orientation completion in PDF/CSV and via a secure API, including learner identifiers, scores, drill history, dates, supervisor sign‑off, and a tamper‑evident watermark. Supports e‑signature capture, revocation/recertification, renewal reminders, and multi‑site reporting. Aligns with HRIS integrations and maintains an immutable audit trail for compliance.

Acceptance Criteria
Supervisor Coaching Dashboard & Filters
"As a supervisor, I want an at‑a‑glance dashboard with drill‑downs so that I can focus coaching time where it will most improve readiness."
Description

Provides a responsive dashboard with cohort overviews, color‑coded readiness bands, trend sparklines, and sortable leaderboards. Offers advanced filters (site, shift, role, trainer, date range) and quick views for metric deficits (e.g., consent accuracy < 95%). Enables drill‑down to session details with annotated errors and before/after blur examples. Supports CSV/PDF export of filtered views, saved filter presets, and shareable supervisor links with access controls. Optimized for tablet use on the floor and meets accessibility standards.

Acceptance Criteria
Consent Accuracy Verification & Auto‑Blur QA
"As a compliance officer, I want detailed consent accuracy results with remediation evidence so that resident privacy and regulations are consistently upheld."
Description

Adds a validation module that compares learner consent tagging against ground truth and checks auto‑blur outcomes for false positives/negatives. Surfaces misclassifications with visual exemplars, explains the correct action, and assigns remediation drills. Flags severe privacy misses for supervisor review and tracks remediation completion. Aggregates consent accuracy into the readiness score and enforces minimum standards before certifying live‑ready. Integrates with the vision service, sandbox labeling tools, and compliance reporting.

Acceptance Criteria
Role‑Based Access & Audit Logging
"As a security administrator, I want role‑based access and comprehensive audit trails so that sensitive training data is protected and reviewable."
Description

Implements fine‑grained RBAC for learners, supervisors, admins, and HR roles with site‑level scoping. Restricts access to PII and consent exemplars to authorized users, supports SSO, and logs all sensitive actions (score changes, certification issuance, exports, overrides) with timestamp, actor, and reason codes. Provides exportable audit logs, retention policies, and data subject access tooling. Ensures the Readiness Radar aligns with KinLoop’s privacy model and regulatory obligations.

Acceptance Criteria

Handoff Rehearsal

A shift‑change simulator for Shift Relay Leads that practices approvals, Delta Highlights scanning, Priority Queue ordering, and Audio Brief creation. Trainees learn to standardize handoffs and spot misses in minutes. Families get clearer digests from day one while after‑hours callbacks drop sooner.

Requirements

Privacy-Safe Scenario Sandbox
"As a Shift Relay Lead trainee, I want a realistic sandbox that mirrors live handoffs using privacy-safe data so that I can practice without risking resident privacy or production disruptions."
Description

Provide a rehearsal environment that mirrors the live Shift Relay experience using synthetic or fully de-identified resident data, sample photos with auto-blur, and mock activity feeds. The sandbox supports full practice of approvals, Delta Highlights scanning, Priority Queue ordering, and Audio Brief creation without writing to production timelines or exposing PHI. Role-based access limits usage to Shift Relay Leads and trainers. Scenarios are prebuilt and configurable to reflect facility policies, acuity mixes, and common edge cases (e.g., missing consent, conflicting priorities). Session data is ephemeral, instrumented for training analytics, and isolated from family-facing digests, ensuring compliance while accelerating onboarding.

Acceptance Criteria
Real-time Coaching & Scoring
"As a trainee, I want real-time coaching and a clear score with specific feedback so that I know exactly what to improve to meet facility standards."
Description

Embed an in-session guidance layer that provides step-by-step prompts, checklists, and automated checks as trainees conduct simulated handoffs. The system detects misses (e.g., unapproved updates, overlooked Delta Highlights, incorrect queue order, incomplete Audio Brief structure), surfaces corrective tips, and calculates a standardized score with category breakdowns and rationales. Post-run summaries include time-to-complete, error heatmaps, and suggested micro-lessons. Coaching rules are driven by facility-configured rubrics and integrate with the sandbox telemetry to personalize feedback and accelerate skill standardization.

Acceptance Criteria
Configurable Handoff Policies & Rubrics
"As an administrator, I want to configure handoff rules and scoring rubrics so that training reflects our facility’s standards and remains consistent as policies change."
Description

Deliver an admin configuration module where facility leaders define handoff standards that power the simulator and evaluation engine. Inputs include approval checklists, Delta Highlight criteria and thresholds, priority queue weightings and tie-break rules, and the required Audio Brief template (e.g., SBAR). Policies are versioned, scoped to units or shifts, and previewable in the sandbox. The simulator consumes these configurations at runtime to evaluate trainee actions consistently, enabling multi-facility rollouts with local variations and ensuring training remains aligned with evolving compliance and operational expectations.

Acceptance Criteria
Priority Queue Ordering Drill
"As a Shift Relay Lead trainee, I want to practice ordering the Priority Queue under realistic pressures so that I can internalize our tie-break rules and make faster, safer decisions during handoff."
Description

Offer an interactive exercise where trainees order a dynamic list of resident updates into a Priority Queue under time constraints. The drill presents realistic signals such as fall risk flags, med windows, family SLA commitments, and overnight deltas. Trainees arrange items via drag-and-drop, apply facility-specific tie-break rules, and submit for instant evaluation against the configured rubric. The system explains discrepancies, highlights conflicting cues the trainee missed, and tracks improvement over repeated attempts.

Acceptance Criteria
Delta Highlights Scanner Trainer
"As a trainee, I want to practice identifying Delta Highlights with clear explanations so that I consistently surface the right changes in handoffs and family digests."
Description

Create a focused module that presents shift notes, observations, and media for a resident set and asks the trainee to select the correct Delta Highlights. The trainer provides optional ML-suggested candidates with reasoning, requires confirmation or rejection, and measures precision, recall, and critical-miss rates against a gold standard derived from policies. Immediate feedback explains why each highlight mattered, with links to policy references and similar past scenarios to reinforce pattern recognition.

Acceptance Criteria
Audio Brief Composer (Voice-to-Text)
"As a Shift Relay Lead trainee, I want guided practice creating concise, structured audio briefs so that I can deliver clear, complete handoffs that reduce after-hours callbacks."
Description

Enable trainees to record a structured Audio Brief within the simulator using a facility-defined template (e.g., SBAR), with live transcription, length targets, and quality hints (pace, filler words, missing sections). The tool supports re-recording, quick edits to the transcript, and playback for self-review or mentor feedback. All audio and text remain in the sandbox, with privacy safeguards and no downstream distribution to families. Guidance ties back to the rubric, ensuring trainees practice the exact briefing style required in production.

Acceptance Criteria
Progress Tracking & Certification
"As an administrator, I want to track progress and certify readiness so that I know who can run handoffs independently and where to focus coaching."
Description

Provide dashboards for trainees and administrators showing attempt counts, scores by competency (approvals, deltas, priority, audio), time trends, and readiness indicators. Define pass thresholds and auto-issue completion certificates when criteria are met, with exports to staff records. Notify admins of trainees who are stalled or excelling, and suggest targeted drills. All training events are audit-logged for compliance, enabling evidence of standardization and tying improvements to reduced family callbacks and faster shift transitions.

Acceptance Criteria

SmartSuggest

Surfaces the three most likely CareTags at capture based on time of day, location (e.g., dining room vs. therapy room), recent notes, and each resident’s care plan. Snapshot Aides tap once instead of scrolling, boosting speed and consistency. Fewer missed tags mean cleaner analytics and clearer family digests without extra effort.

Requirements

Context Signal Aggregation
"As a Snapshot Aide, I want the app to consider time, location, and recent notes when suggesting tags so that I get relevant options without searching."
Description

Aggregate and normalize contextual signals required for SmartSuggest, including time of day, facility/room location, resident identity, recent notes and CareTags, shift information, and structured care-plan data. Provide a lightweight, low-latency context service accessible from the capture screen that delivers a feature vector within strict SLAs to support real-time inference. Implement data adapters to existing KinLoop services and device sensors, with schema versioning, caching, and graceful degradation when certain signals are unavailable. Ensure event logging and traceability for debugging, with minimal battery and bandwidth impact. Expected outcome is a reliable, consistent context layer that materially improves suggestion relevance and enables downstream prediction and analytics.

Acceptance Criteria
Consent-Aware Tagging Guardrails
"As a compliance-focused administrator, I want SmartSuggest to honor consent and care-plan restrictions so that prohibited tags never appear to staff."
Description

Enforce privacy and care-plan constraints in SmartSuggest by filtering out any CareTags that conflict with resident consent settings, privacy flags, or plan-of-care restrictions before suggestions are rendered. Integrate with KinLoop’s consent registry and care-plan store to reflect updates in near real time, and maintain an auditable decision trail indicating which rules affected each suggestion. Include configurable facility-level policies and default safe fallbacks. Expected outcome is consistently compliant suggestions that reduce staff error risk and support regulatory audits without adding friction for Snapshot Aides.

Acceptance Criteria
Top-3 CareTag Prediction
"As a Snapshot Aide, I want the top three most likely CareTags to surface instantly so that I can tag updates with a single tap and keep moving."
Description

Produce the three most likely CareTags for a resident at capture time using a ranking model that consumes contextual signals from the aggregation layer. Meet sub-150ms p95 latency for on-device or edge inference with deterministic ordering and confidence scores. Provide thresholding and fallback logic to default tag sets when confidence is low, plus feature flags for safe rollout and A/B testing. Support multilingual tag labels and taxonomy versioning so predictions remain stable across updates. Expected outcome is highly relevant, instantly available suggestions that reduce scrolling, increase tagging consistency, and improve downstream analytics and family digests.

Acceptance Criteria
One-Tap Suggestion Chips
"As a Snapshot Aide, I want clearly labeled, tappable suggestion chips in the capture screen so that I can apply tags quickly without breaking my flow."
Description

Deliver an accessible, unobtrusive UI component in the capture screen that presents the predicted CareTags as tappable chips with clear labels and optional icons. Ensure single-tap application with immediate visual confirmation, haptic feedback, and undo. Position and size chips to avoid interfering with the camera shutter and note entry, honoring WCAG contrast and touch target guidelines. Include a lightweight “why suggested” hint for transparency without slowing the flow. Instrument interactions for analytics while preserving performance. Expected outcome is faster, more satisfying tagging with minimal cognitive load for aides.

Acceptance Criteria
Personalized Learning Loop
"As a Snapshot Aide, I want SmartSuggest to learn from what I select or ignore so that suggestions become more accurate for each resident over time."
Description

Continuously improve suggestion relevance by learning from user interactions, including which suggestions are tapped, ignored, or replaced with manual tags. Maintain per-resident, per-facility, and global preference signals with privacy-aware aggregation. Implement a lightweight bandit or re-ranking layer that boosts likely tags based on recent outcomes, with safeguards against bias and drift. Support cold-start heuristics using care plans and location defaults, and allow opt-out at facility level. Expected outcome is steadily increasing precision and user trust as SmartSuggest adapts to local workflows and resident patterns.

Acceptance Criteria
Offline & Low-Connectivity Support
"As a Snapshot Aide, I want tag suggestions to work offline or on weak Wi‑Fi so that my workflow is uninterrupted during rounds."
Description

Ensure SmartSuggest functions reliably without stable internet by packaging a compact on-device model, caching recent context features, and precomputing fallback suggestion sets per resident. Detect connectivity state and degrade gracefully while maintaining sub-150ms local inference and queuing telemetry for later sync. Manage cache staleness with time-to-live rules and secure storage. Expected outcome is uninterrupted one-tap tagging during rounds, even in dead zones, preserving speed and data completeness.

Acceptance Criteria
Admin Controls & Accuracy Telemetry
"As an administrator, I want controls and reports on SmartSuggest accuracy and behavior so that I can tune it and demonstrate value to stakeholders."
Description

Provide administrator tools to tune SmartSuggest and monitor performance. Include settings for location-to-tag mappings, confidence thresholds, and eligible tag pools by unit. Expose dashboards for accuracy, coverage, time-to-tag, and top missed or overridden suggestions, with drill-down by resident and shift while respecting privacy. Offer export and alerting when accuracy drops or taxonomy changes impact suggestions. Role-based access ensures only authorized users can modify behavior. Expected outcome is controllable, transparent operation that aligns with facility goals and demonstrates measurable value.

Acceptance Criteria

Tag Packs

Role- and unit‑aware bundles of curated CareTags (e.g., Memory Care AM, Rehab PM) that auto-load for the right staff via RoleSmart Mapping. Onboarding Guides create and publish packs in minutes; Snapshot Aides see only what’s relevant, cutting hunt time and standardizing language across shifts.

Requirements

Pack Builder & Publishing Workflow
"As an Onboarding Guide, I want to quickly assemble and publish standardized Tag Packs so that staff see the right tags in the right order without hunting."
Description

A guided admin experience for Onboarding Guides to create, curate, and publish bundles of CareTags as named Tag Packs scoped by facility, unit, shift, and role. Provides drag-and-drop ordering, category grouping, metadata (e.g., AM/PM/NOC), duplication detection, and validation against retired or restricted CareTags. Includes draft, review, schedule, and publish states with template starters and preview-as-user to see exactly how packs render in the Snapshot Aide mobile view. Published packs propagate to devices via KinLoop’s sync service and integrate with RoleSmart Mapping to determine eligibility, triggering notifications to affected staff upon changes.

Acceptance Criteria
RoleSmart Mapping & Eligibility Rules
"As an administrator, I want to map Tag Packs to roles, units, and shifts so that the correct packs auto-load for each staff member’s context."
Description

A rules engine that assigns Tag Packs to staff based on role (e.g., Snapshot Aide, Nurse), unit (e.g., Memory Care, Rehab), shift window, and optional attributes (e.g., float status, language). Supports rule precedence, conflict detection with resolution suggestions, and a default fallback pack when no rules match. Provides a test/simulation mode to input a user and context and preview the resulting pack set. Fully audited edits and seamless integration with the Pack Builder to reference eligible roles/units and validate mappings before publishing.

Acceptance Criteria
Auto-Load & Context Switching
"As a Snapshot Aide, I want the right Tag Pack to appear automatically when I start or move units so that I can capture updates without switching or searching."
Description

Mobile client behavior that auto-loads the correct Tag Pack upon login and whenever the user’s role, unit assignment, or shift changes, showing only relevant CareTags in capture screens. Includes a quick-switch control for multi-role or float staff, a temporary override with auto-expiry, and visual confirmation of active pack. Provides offline resilience by caching last-known eligible packs and deferring updates until connectivity returns. Integrates with RoleSmart Mapping for eligibility and with local device storage for instant performance.

Acceptance Criteria
Pack Versioning & Rollback
"As an Onboarding Guide, I want version history and one-click rollback so that I can safely correct mistakes or revert changes without disrupting care."
Description

End-to-end version control for Tag Packs with immutable history, semantic versioning, change summaries, and the ability to roll back to a prior version instantly. Supports scheduled effective dates/times, canary rollouts to selected units, and deprecation flags for phased transitions. Ensures version compatibility with RoleSmart Mapping rules and propagates lightweight deltas to clients to minimize bandwidth. Surfaces version badges in the mobile UI so staff can confirm they’re on the latest standard.

Acceptance Criteria
Distribution & Caching for Low-Connectivity
"As an IT coordinator, I want Tag Packs to be reliably available offline so that staff in low-connectivity areas still see the correct tags."
Description

A synchronization layer that prefetches and caches Tag Packs on devices based on upcoming shifts and assignments, with bandwidth-aware downloads, content hashing for integrity, and incremental updates. Supports graceful degradation when networks are slow or offline, local encryption at rest, and cache invalidation upon publish or mapping changes. Provides telemetry on sync success and stale cache detection to alert admins of distribution issues across facilities.

Acceptance Criteria
Access Control & Audit Trail
"As a compliance officer, I want controlled access and full audit logs for Tag Pack changes so that we meet regulatory and policy requirements."
Description

Granular permissions that restrict who can create, edit, approve, and publish Tag Packs, aligned to KinLoop’s RBAC model. Requires approval workflows for high-impact changes, captures an immutable audit trail (who, what, when, why) for both pack edits and mapping changes, and exports reports for regulatory reviews. Avoids PHI by logging tag IDs and metadata only, enforces retention policies, and integrates with Single Sign-On and multi-site administration.

Acceptance Criteria
Usage Analytics & Optimization Insights
"As a product owner, I want visibility into how Tag Packs are used so that we can refine content and ordering to speed capture and standardize language."
Description

Privacy-safe analytics that measure Tag Pack effectiveness, including tag usage frequency, time-to-first-tag, search/no-hit rates, and cross-shift consistency. Provides dashboards and CSV export, highlights stale or unused tags, recommends merges or reordering to reduce hunt time, and tracks impact after changes. Aggregates by facility, unit, role, and shift without exposing resident data, and allows admins to opt-in/opt-out per site.

Acceptance Criteria

QuickBundle

One tap applies a configurable set of commonly paired tags (e.g., Morning ADL: Hydrated, Groomed, Meds Given). Each tag still logs individually for analytics and digests. Speeds routine documentation while preserving granular reporting and compliance clarity.

Requirements

Bundle Library Management & Versioning
"As an administrator, I want to create and version common tag bundles so that caregivers can document routines quickly while we retain audit clarity over what was applied."
Description

Provide a facility-level library of QuickBundles that can be created, edited, cloned, and versioned by authorized staff. Bundles consist of a named set of existing tags with optional default notes and ordering. Versioning maintains historical records of bundle composition for auditability; applying a bundle references the version used. Support facility-wide bundles and unit-specific bundles; caregivers can favorite bundles for faster access. Validation ensures only active tags are included and prevents deletion of tags in active bundles. Changes propagate without altering past logs. Import/export capability allows seeding from templates across facilities.

Acceptance Criteria
One-Tap Apply with Quick Deselect and Undo
"As a caregiver, I want to apply a routine’s tags with one tap and quickly tweak them so that I can document accurately without slowing care."
Description

Single tap applies a selected QuickBundle to the current resident and shift context, logging each contained tag individually. A lightweight preview sheet shows included tags with the ability to deselect items and add notes in-line; default notes from the bundle are pre-filled. Provide a one-tap Undo within a configurable window and an edit window based on role permissions; undo reverses all associated tag entries atomically. Include haptic feedback, clear confirmations, and a progress indicator; maintain sub-200 ms tap-to-preview responsiveness on supported devices. Support keyboardless operation and large-touch targets for speed and accessibility.

Acceptance Criteria
Per-Tag Logging, De-duplication, and Audit Trail
"As a compliance officer, I want each bundled tag logged individually with traceability so that reports and audits remain accurate and defensible."
Description

Applying a QuickBundle creates discrete log entries for each tag with timestamps, author, resident, location, and a bundle_id and bundle_version reference for traceability. If a tag in the bundle has already been logged for the resident within a configurable time window, de-duplication prompts the user or auto-skips per facility policy while recording a skip_reason. All entries are immutable after the edit window and visible in audit reports, preserving compliance clarity that each tag was individually recorded even when applied via QuickBundle.

Acceptance Criteria
Role-Based Access and Visibility Controls
"As an administrator, I want to control who manages and sees bundles so that documentation stays accurate and aligned with our care protocols."
Description

Enforce permissions so that only designated roles can create, edit, or delete QuickBundles, while caregivers can apply approved bundles. Bundle visibility can be scoped by facility, unit, role, and resident attributes to prevent misuse. Application and management actions are logged with user identity for accountability. Feature flags enable gradual rollout per site without impacting existing workflows.

Acceptance Criteria
Offline Apply and Idempotent Sync
"As a caregiver, I want QuickBundle to work when Wi‑Fi drops so that my documentation remains fast and reliable."
Description

QuickBundle application works without network connectivity by queuing per-tag log entries locally under a single bundle transaction envelope. On reconnection, a sync process posts entries with idempotent keys to prevent duplicates from replays, resolves conflicts with server-side validation and de-duplication rules, and maintains original timestamps. The UI clearly shows offline state and pending sync, with automatic retries and user notification on errors requiring attention.

Acceptance Criteria
Digest and Analytics Integration
"As an administrator, I want digests and analytics to reflect bundled entries transparently so that families stay informed and we can measure efficiency gains."
Description

Per-tag entries generated via QuickBundle are included in daily/weekly family digests and internal dashboards exactly like manually-added tags, while preserving a reference to the originating bundle for internal analytics. Digest rendering groups related events for readability without obscuring individual tags. Analytics report bundle adoption, time saved, tag frequency, and de-dup rates by unit and shift, enabling continuous optimization of bundle composition.

Acceptance Criteria
Performance, Accessibility, and UX Standards
"As a caregiver, I want a fast and accessible QuickBundle experience so that I can document efficiently regardless of device or conditions."
Description

Ensure the QuickBundle flow meets defined non-functional standards: sub-200 ms tap-to-preview, sub-500 ms apply under normal network conditions; fully operable with one hand and large touch targets; WCAG AA contrast and screen reader labels for all controls; localized strings; and clear error states. Telemetry captures latency and error rates to monitor real-world performance and guide optimization.

Acceptance Criteria

Tag Nudge

Gentle, on-card prompts when expected tags are missing within a time window (e.g., Hydration by 10am). Integrates with Priority Queue to lift residents with gaps, helping Shift Relay Leads prevent misses before handoff. Nudges never block posting and adapt as completion improves.

Requirements

Configurable Tag Schedules & Rules
"As a community admin, I want to set tag expectations by care plan and shift so that caregivers get timely prompts aligned to each resident’s needs."
Description

Provide an admin-managed rule engine to define expected care tags per resident, group, or care plan with time windows and frequencies (e.g., Hydration by 10am, Range of Motion twice per shift). Rules support templates, per-resident overrides, shift calendars, and timezone-aware scheduling. The engine evaluates real-time activity to detect missing tags, emits nudge-ready signals, and respects consent/privacy settings. Implement lightweight evaluation to run offline with deferred sync; resolve conflicts on re-connect. Expose APIs/events for UI nudges and Priority Queue score updates.

Acceptance Criteria
On-card Non-Blocking Nudge UX
"As a caregiver, I want clear, quick prompts to add missing tags without slowing me down so that I can stay compliant while keeping my focus on residents."
Description

Surface gentle, contextual prompts on the resident update card when expected tags are missing within their time window. Prompts allow one-tap tag add, quick voice-to-text note, or dismiss/snooze without blocking posting. Copy is plain-language, large-tap targets, low-contrast badge when early, elevated banner as due time nears, and calm tone. Respect do-not-disturb mode, offline mode, and accessibility settings. Log interactions for audit and feed completion metrics back to adaptive tuning.

Acceptance Criteria
Priority Queue Lift for Gaps
"As a Shift Relay Lead, I want residents with care gaps to rise in my queue so that I can direct attention before handoff."
Description

Integrate nudge signals with the existing Priority Queue so residents with unmet tag expectations are elevated based on urgency, care plan weight, and time overdue. Provide a transparent score and reason code for each lift, update in real time, and avoid thrashing via hysteresis and debounce rules. Ensure role-based visibility for Shift Relay Leads and floor staff, and maintain non-blocking behavior.

Acceptance Criteria
Adaptive Nudge Tuning
"As an operations manager, I want nudges to adapt as teams improve so that reminders stay helpful and not annoying."
Description

Adjust nudge frequency, timing, and copy per unit, shift, caregiver, and tag type based on historical completion and interaction patterns to reduce alert fatigue and encourage habit formation. Use deterministic heuristics first (e.g., space nudges after dismissal, suppress after completion, quiet hours) with guardrails and override controls. Store models client-side where possible for responsiveness and privacy; fall back to server recommendations.

Acceptance Criteria
Audit Trail & Compliance Reporting
"As an administrator, I want an auditable record of nudges and follow-through so that I can demonstrate compliance and improve workflows."
Description

Record when nudges are issued, viewed, dismissed, snoozed, and fulfilled, including timestamps, actor, resident, tag, and time-to-completion. Provide filterable reports and export capabilities for compliance reviews and family inquiries, without exposing PHI beyond roles. Support retention policies and data minimization in line with privacy standards.

Acceptance Criteria
Handoff Gap Summary
"As an outgoing Shift Relay Lead, I want a quick view of unresolved care tags so that I can hand off confidently and prevent misses."
Description

At shift handoff, present a concise summary of remaining tag gaps by resident and tag, with one-tap bulk nudges or reassignment to the incoming team. Show what was completed post-nudge and what remains, and capture optional notes for context. The summary is advisory and never blocks handoff.

Acceptance Criteria
Admin Exceptions & Snooze Controls
"As a nurse supervisor, I want to set temporary exceptions for certain tags so that staff are not prompted inappropriately and the queue stays accurate."
Description

Allow admins and leads to set temporary exceptions to tag expectations for specific residents (e.g., off-site appointment, NPO before procedure, hospice changes) with start/end times and reasons. Provide caregiver-level snooze for a resident/tag within policy limits, with automatic reactivation and audit logging. Exceptions propagate to rule engine, nudges, and Priority Queue.

Acceptance Criteria

Digest Mapper

Automatically routes CareTags into clean, family‑friendly sections in daily/weekly digests and Voice Digest (e.g., Meals, Therapy, Spiritual Life). Shift Relay Leads can reorder or spotlight sections per family preference. Families get faster, clearer updates; staff field fewer clarifying calls.

Requirements

CareTag-to-Section Mapping Engine
"As an administrator, I want CareTags to automatically map to clear digest sections so that families receive organized updates without staff editing."
Description

Implements a canonical digest section schema (e.g., Meals, Therapy, Activities, Spiritual Life, Health & Vitals, Meds, Hygiene, Mobility, Social, Notes) and deterministic rules that map CareTags on updates to one or more digest sections. Supports default and facility-specific taxonomies, one-to-many mappings with priority order, conflict resolution, and a fallback to a General Updates section. Persists normalized section assignments at ingestion time and de-duplicates repeated items within a shift window. Provides versioning, environment configuration, and auditability to ensure consistent routing across facilities.

Acceptance Criteria
NLP Augmentation & Confidence Thresholds
"As a caregiver, I want the system to auto-classify untagged notes so that I spend less time tagging and families still get complete digests."
Description

Enhances routing by analyzing voice-to-text captions and notes when tags are missing or ambiguous. Uses lightweight NLP to infer likely sections and applies confidence thresholds to auto-assign, suggest for review, or leave unassigned. Flags low-confidence items for Shift Relay Lead review, supports language variants, and detects sensitive phrases requiring redaction or exclusion. Operates server-side with graceful offline handling and logs rationale for each automated decision for audit.

Acceptance Criteria
Family Preference Profiles & Section Ordering
"As a family member, I want my digest to highlight the areas I care about and hide the rest so that I can skim quickly."
Description

Stores per-family digest preferences, including custom section order, visibility toggles, spotlight priorities, and preferred digest cadence (daily/weekly/voice). Defaults inherit from facility standards but allow resident-family overrides. Exposes an API to retrieve effective preferences at render time, with validation, versioning, and audit logs. Ensures changes are immediately reflected in subsequent digests without affecting other families or residents.

Acceptance Criteria
Shift Relay Lead Spotlight & Reorder UI
"As a Shift Relay Lead, I want to reorder and spotlight sections per family so that digests match each family’s priorities."
Description

Provides a simple, role-gated interface for Shift Relay Leads to drag-and-drop reorder sections, toggle visibility, and mark spotlight sections per family before digest generation. Surfaces low-confidence classification items for quick approval or reassignment, supports undo/redo, and distinguishes temporary per-shift overrides from persistent profile updates. Ensures all actions are tracked with user, timestamp, and reason codes.

Acceptance Criteria
Digest Assembly & Delivery (Daily/Weekly + Voice Digest)
"As a family member, I want a clear daily or weekly digest and a playable voice version so that I can keep up even when I’m busy."
Description

Builds scheduled digests per resident-family by applying mappings, family preferences, and spotlights to assemble clean sections with titles, thumbnails, captions, timestamps, and staff attribution. Generates in-app views, accessible HTML/email, and a Voice Digest script that converts to TTS audio with clear section cues. Is timezone-aware, retries on failure, and respects recipient permissions and consent lists. Tracks delivery status, opens, and playback for analytics.

Acceptance Criteria
Privacy & Compliance Filters in Digests
"As a compliance officer, I want digests to automatically respect consent and PHI rules so that we protect resident dignity and stay compliant."
Description

Applies consent-aware media filtering and auto-blur to all digest assets, suppressing content with non-consenting faces or names and redacting PHI per policy. Enforces least-necessary data inclusion, strips sensitive metadata (e.g., precise location), and blocks sections that would expose restricted information. Maintains an audit trail of filtered items with reasons and provides an admin review workflow with justifications for any overrides.

Acceptance Criteria

Tag Pulse

Live coverage and trend insights for CareTags by resident, unit, and shift—completion rates, most/least used tags, and gaps that drive callbacks. Exportable views help supervisors coach teams and tune Tag Packs. Better coverage translates into more confident families and fewer inbound calls.

Requirements

Live Coverage Dashboard
"As a unit supervisor, I want a live dashboard of CareTag completion by resident, unit, and shift so that I can spot coverage gaps early and coach staff before families notice."
Description

Provide a real-time dashboard showing CareTag coverage and completion rates by resident, unit, and shift with color-coded status, trend sparklines, and drill-downs. Include filters for time window, staff, and location, and display clear denominators (completed vs. expected) based on care plans and shift definitions. Ensure sub‑minute data freshness with resilient event aggregation, correct late-entry attribution, and timezone-aware shift boundaries. Support annotations for coaching, accessible visuals, and consistent metric definitions, while minimizing PHI exposure and honoring resident consent.

Acceptance Criteria
Trend Insights & Tag Usage Analytics
"As an administrator, I want to see trends for most and least used CareTags over time so that I can identify training needs and standardize best practices."
Description

Deliver interactive analytics that highlight most and least used CareTags over selectable ranges (1/7/30/90 days), segmented by resident, unit, shift, and caregiver. Provide baseline comparisons, moving averages, and seasonality cues to reveal behavior changes. Handle tag renames via lineage mapping, maintain a clear definition of "use," and backfill historical data. Offer interactive charts with tooltips, filters, and comparisons, while enforcing role-based visibility and de-identification in aggregated views.

Acceptance Criteria
Gap Detection & Callback Driver Analysis
"As a community director, I want automatic detection of missing care updates that trigger family callbacks so that I can reduce avoidable calls and improve trust."
Description

Implement a rules engine that detects missing required tags per resident care plan and quantifies coverage gaps by unit and shift. Correlate gap patterns with inbound family call topics to surface top callback drivers. Provide in-app alerts and daily digests with severity thresholds, quiet hours, and snooze controls. Offer an explainability view that shows which expectations were missed and recommended next actions. Log all alerts for auditability and ensure privacy by suppressing low-count cells.

Acceptance Criteria
Export & Scheduled Reports
"As a regional manager, I want to export and schedule Tag Pulse reports so that I can share performance summaries with leadership and regulators without granting app access."
Description

Enable one-click export of dashboard and analytics views to CSV and PDF with configurable columns, filters, and date ranges. Support scheduled deliveries (daily/weekly/monthly) to authorized recipients via secure, expiring links, with watermarks, audit logging, and timezone-stamped headers. Preserve metric definitions in report metadata, enforce row-level access rules, and apply rate limits and retention policies for generated files.

Acceptance Criteria
Tag Pack Coaching Recommendations
"As a care coach, I want recommendations for tuning Tag Packs so that teams capture the most meaningful updates with less effort and higher consistency."
Description

Generate data-driven recommendations to add, remove, or reorder CareTags within Tag Packs based on usage frequency, gap incidence, and caregiver friction signals. Provide impact projections (e.g., expected coverage lift), a preview of changes, and safe rollout options (A/B by unit or shift) with versioning and rollback. Track post-change outcomes to validate effectiveness and feed future recommendations. Integrate with existing Tag Pack management flows and resident consent constraints.

Acceptance Criteria
Access Control & Privacy Safeguards
"As a compliance officer, I want strict access controls and privacy safeguards around analytics so that insights never expose resident PHI or non-consenting data."
Description

Enforce role-based access with least-privilege permissions for Tag Pulse, ensuring resident-level drill-downs are restricted to assigned supervisors while aggregated views use de-identification and minimum cell thresholds. Apply consent-aware filtering, encrypt data in transit and at rest, and redact PHI from exports. Maintain HIPAA-aligned audit logs of access, exports, and configuration changes, with session controls and device safeguards suitable for shared workstation environments.

Acceptance Criteria

Product Ideas

Innovative concepts that could enhance this product's value proposition.

TapBadge Login

Staff tap an NFC ID badge to instantly sign in on shared devices, auto-assigning role and unit. Cuts password friction and prevents stray logins during shift swaps.

Idea

Consent Pocket Vault

Mobile consent manager stores signed photo/audio permissions with expiry and resident scope. Snapshots auto-check consent at capture, reducing audits and blocking non-compliant posts.

Idea

Shift Snapshot Cards

Auto-generate per-resident cards summarizing last 12 hours with key photo, vitals tags, and family acknowledgments. One-tap print or share trims handoff briefings by minutes per resident.

Idea

Call Deflect Line

A dedicated phone line reads the latest approved updates via PIN and text-to-speech. Families get answers without staff pickup, deflecting routine calls after hours.

Idea

PIN SafeShare

Create time-limited, PIN-protected web links to a single update for relatives without the app. Audit every view and auto-expire to maintain privacy.

Idea

CoachMode Onboarding

Interactive checklists and bite-size prompts guide first-week posts, with simulated residents for practice. Reduces trainer time and builds confident, compliant habits fast.

Idea

CareTag Shortcuts

One-tap tags like Hydrated, PT Done, or Visited Chapel attach to photos and drive digest sections and analytics. Speeds capture while structuring data for reports.

Idea

Press Coverage

Imagined press coverage for this groundbreaking product concept.

Want More Amazing Product Ideas?

Subscribe to receive a fresh, AI-generated product idea in your inbox every day. It's completely free, and you might just discover your next big thing!

Product team collaborating

Transform ideas into products

Full.CX effortlessly brings product visions to life.

This product was entirely generated using our AI and advanced algorithms. When you upgrade, you'll gain access to detailed product requirements, user personas, and feature specifications just like what you see below.